diff options
Diffstat (limited to 'kmilo/kmilo_kvaio/kvaio.cpp')
-rw-r--r-- | kmilo/kmilo_kvaio/kvaio.cpp | 606 |
1 files changed, 606 insertions, 0 deletions
diff --git a/kmilo/kmilo_kvaio/kvaio.cpp b/kmilo/kmilo_kvaio/kvaio.cpp new file mode 100644 index 0000000..8a02098 --- /dev/null +++ b/kmilo/kmilo_kvaio/kvaio.cpp @@ -0,0 +1,606 @@ +/* -*- C++ -*- + + This file implements the KVaio class. + + $ Author: Mirko Boehm $ + $ Copyright: (C) 1996-2003, Mirko Boehm $ + $ Contact: mirko@kde.org + http://www.kde.org + http://www.hackerbuero.org $ + $ License: LGPL with the following explicit clarification: + This code may be linked against any version of the Qt toolkit + from Troll Tech, Norway. $ + + $Id$ + + * Portions of this code are + * (C) 2001-2002 Stelian Pop <stelian@popies.net> and + * (C) 2001-2002 Alcove <www.alcove.com>. + * Thanks to Stelian for the implementation of the sonypi driver. + + * Modified by Toan Nguyen <nguyenthetoan@gmail.com> + * to include support for + * Fn+F2,F3,F4 (Volume) + * Fn+F5,F6 (Brightness) + * Fn+F1 (blankscreen) + * Fn+F12 (suspend to disk) +*/ + +#include <kconfig.h> + +#include "kvaio.h" +#include "kmilointerface.h" + +#include <qlabel.h> +#include <qcstring.h> +#include <qevent.h> +#include <qdatastream.h> +#include <kmainwindow.h> +#include <klocale.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <dcopclient.h> +#include <kapplication.h> + +extern "C" { +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <getopt.h> +#include <errno.h> + +#include "./sonypi.h" +} + + +KVaio::KVaio(KMiloKVaio *parent, const char* name) + : QObject(parent, name), + mDisp(0), + mTimer (new QTimer (this) ) +{ + myparent = parent; + + mDriver = new KVaioDriverInterface(this); + + if(!mDriver->connectToDriver()) + { + delete mDriver; mDriver = 0L; + kdDebug() << "KVaio: Cannot connect to driver." << endl; + } else { + kdDebug() << "KVaio: Connected to SonyPI driver." << endl; + connect(mDriver, SIGNAL(vaioEvent(int)), SLOT(slotVaioEvent(int))); + connect (mTimer, SIGNAL (timeout ()), SLOT (slotTimeout() ) ); + mTimer->start (10000, true); + } + + mDisp = XOpenDisplay(NULL); + if(!mDisp) + { + kdDebug() << "KVaio ctor: Failed to open display. Very strange." + << endl; + } + + if(!mClient.attach()) + { + kdDebug() << "KVaio ctor: cannot attach to DCOP server." << endl; + } + + KConfig config("kmilodrc"); + + loadConfiguration(&config); + + m_mute = false; + m_progress = 0; + m_minVolume = 0; + m_maxVolume = 100; + m_volume = 50; + + m_VolumeStep = 10; + + m_brightness = 128; + m_minBright = 0; + m_maxBright = 255; + m_BrightnessStep = 16; + + kmixClient = new DCOPRef("kmix", "Mixer0"); + kmixWindow = new DCOPRef("kmix", "kmix-mainwindow#1"); +// retrieveVolume(); +// retrieveMute(); + +} + +KVaio::~KVaio() +{ + kdDebug() << "KVaio dtor: shutting down." << endl; + if(mDriver!=0) + { + mDriver->disconnectFromDriver(); + } + if(mClient.isAttached()) + { + mClient.detach(); + } +} + +void KVaio::slotVaioEvent(int event) +{ + QString text; + QTextStream stream(text, IO_WriteOnly); + + switch(event) + { + case SONYPI_EVENT_FNKEY_RELEASED: + break; + case SONYPI_EVENT_FNKEY_F1: + blankScreen(); + break; + case SONYPI_EVENT_FNKEY_F2: + mute(); + break; + case SONYPI_EVENT_FNKEY_F3: + VolumeDown(m_VolumeStep); + break; + case SONYPI_EVENT_FNKEY_F4: + VolumeUp(m_VolumeStep); + break; + case SONYPI_EVENT_FNKEY_F5: + BrightnessDown(m_BrightnessStep); + break; + case SONYPI_EVENT_FNKEY_F6: + BrightnessUp(m_BrightnessStep); + break; + case SONYPI_EVENT_FNKEY_F12: + suspendToDisk(); + break; + case SONYPI_EVENT_MEMORYSTICK_INSERT: + showTextMsg( i18n ("Memory Stick inserted") ); + break; + case SONYPI_EVENT_MEMORYSTICK_EJECT: + showTextMsg( i18n ("Memory Stick ejected") ); + break; + case SONYPI_EVENT_BACK_PRESSED: + if (mShowPowerStatusOnBackButton) + { + showBatteryStatus (true); + } + break; + default: + stream << i18n("Unhandled event: ") << event; + if(mReportUnknownEvents) showTextMsg(text); + kdDebug() << "KVaio::slotVaioEvent: event not handled." + << endl; + } +} + +bool KVaio::showTextMsg(const QString& msg) +{ + return myparent->showTextMsg(msg); +} + + + +bool KVaio::showProgressMsg(const QString& msg, int value) +{ + m_progress = value; + return myparent->showProgressMsg(msg,value); +} + +void KVaio::blankScreen() +{ + bool blankonly; + + if (isKScreensaverAvailable()) { + + QByteArray data, replyData; + QDataStream arg(data, IO_WriteOnly); + QCString replyType; + + /* Set the screensave to BlankOnly mode */ + blankonly = true; + arg << blankonly; + mClient.call("kdesktop","KScreensaverIface","setBlankOnly(bool)", + data, replyType, replyData) ; + + /* Save the screen */ + if ( !mClient.call("kdesktop", "KScreensaverIface", "save()", + data, replyType, replyData) ) + { + kdDebug() << "KVaio::blankScreen: there was some error " + << "using DCOP." << endl; + } + + /* Set the screensave to its original mode */ + blankonly = false; + arg << blankonly; + mClient.call("kdesktop","KScreensaverIface","setBlankOnly(bool)", + data, replyType, replyData) ; + + } + +} + +void KVaio::suspendToDisk() +{ + QByteArray data, replyData; + QDataStream arg(data, IO_WriteOnly); + QCString replyType; + + mClient.call("kpowersave","KPowersaveIface","do_suspendToDisk()", + data, replyType, replyData) ; +} + + +bool KVaio::isKScreensaverAvailable() +{ + if(mClient.isAttached()) + { + // kdDebug() << "KVaio::showTextMsg: attached to DCOP server." << endl; + if(mClient.isApplicationRegistered("kdesktop")) + { + QCStringList objects; + + // kdDebug() << "KVaio::showTextMsg: kded is registered at dcop server." + // << endl; + objects = mClient.remoteObjects("kdesktop"); + if(objects.contains("KScreensaverIface")) + { + // kdDebug() << "KVaio::showTextMsg: kmilod is available at kded." + // << endl; + return true; + } else { + kdDebug() << "KVaio::isKScreensaverAvailable: " + << "KScreensaverIface is NOT available at kdesktop." << endl; + return false; + } + } else { + kdDebug() << "KVaio::isKScreensaverAvailable: " + << "kdesktop is NOT registered at dcop server." << endl; + return false; + } + } else { + kdDebug() << "KVaio::isKScreensaverAvailable: " + << "kdesktop is NOT registered at dcop server." << endl; + return false; + } +} + +bool KVaio::isKMiloDAvailable() +{ + if(mClient.isAttached()) + { + // kdDebug() << "KVaio::showTextMsg: attached to DCOP server." << endl; + if(mClient.isApplicationRegistered("kded")) + { + QCStringList objects; + + // kdDebug() << "KVaio::showTextMsg: kded is registered at dcop server." + // << endl; + objects = mClient.remoteObjects("kded"); + if(objects.contains("kmilod")) + { + // kdDebug() << "KVaio::showTextMsg: kmilod is available at kded." + // << endl; + return true; + } else { + kdDebug() << "KVaio::isKMiloDAvailable: " + << "kmilod is NOT available at kded." << endl; + return false; + } + } else { + kdDebug() << "KVaio::isKMiloDAvailable: " + << "kded is NOT registered at dcop server." << endl; + return false; + } + } else { + kdDebug() << "KVaio::isKMiloDAvailable: " + << "kded is NOT registered at dcop server." << endl; + return false; + } +} + +void KVaio::loadConfiguration(KConfig *k) +{ + k->setGroup("KVaio"); + + mReportUnknownEvents = + k->readBoolEntry("Report_Unknown_Events", false); + mReportPowerStatus = + k->readBoolEntry("PeriodicallyReportPowerStatus", false); + mShowPowerStatusOnBackButton = + k->readBoolEntry("PowerStatusOnBackButton", true); + + kdDebug() << "KVaio::loadConfiguration: " << endl + << " mReportUnknownEvents: " + << mReportUnknownEvents << endl + << " mReportPowerStatus: " + << mReportPowerStatus << endl + << "mShowPowerStatusOnBackButton: " + << mShowPowerStatusOnBackButton << endl; +} + +const KVaioDriverInterface* KVaio::driver() +{ + return mDriver; +} + +void KVaio::slotTimeout () +{ + showBatteryStatus (); + mTimer->start (4000, true); +} + +bool KVaio::showBatteryStatus ( bool force ) +{ + static bool acConnectedCache = false; + static int previousChargeCache = -1; + bool bat1Avail = false, bat2Avail = false, acConnected = false; + int bat1Remaining = 0, bat1Max = 0, bat2Remaining = 0, bat2Max = 0; + bool displayBatteryMsg = false; + bool displayACStatus = false; + + QString text, acMsg; + QTextStream stream(text, IO_WriteOnly); + + // ----- + // only display on startup if mReportPowerStatus is true: + if (mReportPowerStatus==false || !force) + { + return true; + } + + // query all necessary information: + (void) mDriver->getBatteryStatus(bat1Avail, bat1Remaining, bat1Max, + bat2Avail, bat2Remaining, bat2Max, + acConnected); + + int remaining; + if ( bat1Avail || bat2Avail ) + remaining = (int)(100.0*(bat1Remaining+bat2Remaining) + / (bat1Max+bat2Max)); + else + remaining = -1; // no battery available + + if (acConnectedCache != acConnected || force) + { + displayACStatus = true; + acConnectedCache = acConnected; + } + + displayBatteryMsg = ( previousChargeCache * 100 / remaining > 1000 ) + || ( previousChargeCache * 100 / remaining > 200 && remaining < 10 ) + || force; + + + if (displayBatteryMsg) + { + previousChargeCache = remaining; + } + + // ----- prepare text messages + if (displayACStatus || displayBatteryMsg) + { + + if (displayACStatus) + { + acMsg = acConnected ? i18n ("AC Connected") : i18n ("AC Disconnected"); + } + + switch (remaining) + { + case 100: + stream << i18n("Battery is Fully Charged. "); + break; + case 5: + case 4: + case 3: + case 2: + case 1: + stream << i18n("Caution: Battery is Almost Empty (%1% remaining).").arg(remaining); + break; + case 0: + stream << i18n("Alert: Battery is Empty!"); + break; + case -1: + stream << i18n("No Battery Inserted."); + break; + default: + stream << i18n("Remaining Battery Capacity: %1%").arg( remaining ); + }; + + // show a message if the battery status changed by more then 10% or on startup + if (displayACStatus) + { + stream << endl << acMsg; + } + + return showTextMsg (text); + } else { + return true; + } +} + +void KVaio::BrightnessUp(int step) +{ + m_brightness = mDriver->brightness(); + + m_brightness += step; + if(m_brightness > m_maxBright) { + m_brightness = m_maxBright; + } + + mDriver->setBrightness(m_brightness); + showProgressMsg( i18n("Brightness"), m_brightness*100/255); +} + +void KVaio::BrightnessDown(int step) +{ + m_brightness = mDriver->brightness(); + + m_brightness -= step; + if(m_brightness < m_minBright) { + m_brightness = m_minBright; + } + + mDriver->setBrightness(m_brightness); + showProgressMsg( i18n("Brightness"), m_brightness*100/255); +} + + +void KVaio::displayVolume() +{ +// _interface->displayProgress(i18n("Volume"), m_volume); + + showProgressMsg(i18n("Volume"), m_volume); + // If we got this far, the DCOP communication with kmix works, + // so we don't have to test the result. + kmixClient->send("setMasterVolume", m_volume); + + // if mute then unmute + if (m_mute) + { + m_mute = false; + kmixClient->send("setMasterMute", m_mute); + } +} + + +bool KVaio::retrieveVolume() { + bool kmix_error = false; + + DCOPReply reply = kmixClient->call("masterVolume"); + if (reply.isValid()) + m_volume = reply; + else + kmix_error = true; + + if (kmix_error) // maybe the error occurred because kmix wasn't running + { +// _interface->displayText + showTextMsg(i18n("Starting KMix...")); + if (kapp->startServiceByDesktopName("kmix")==0) // trying to start kmix + { + // trying again + reply = kmixClient->call("masterVolume"); + if (reply.isValid()) + { + m_volume = reply; + kmix_error = false; + kmixWindow->send("hide"); + } + } + } + + if (kmix_error) + { + kdDebug() << "KMilo: GenericMonitor could not access kmix/Mixer0 via dcop" + << endl; + //_interface->displayText + showTextMsg(i18n("It seems that KMix is not running.")); + + return false; + } else { + return true; + } +} + +void KVaio::VolumeUp(int step) +{ + if (!retrieveVolume()) + return; + + // FIXME if the mixer doesn't support steps of the specified size it + // could get stuck at one position + m_volume += step; + if (m_volume > m_maxVolume) + m_volume = m_maxVolume; + + displayVolume(); +} + +void KVaio::VolumeDown(int step) +{ + if (!retrieveVolume()) + return; + + m_volume -= step; + if (m_volume < m_minVolume) + m_volume = m_minVolume; + + displayVolume(); +} + +bool KVaio::retrieveMute() +{ + bool kmix_error = false; + + DCOPReply reply = kmixClient->call("masterMute"); + if (reply.isValid()) + m_volume = reply; + else + kmix_error = true; + + if (kmix_error) + { + // maybe the error occurred because kmix wasn't running + //_interface->displayText + showTextMsg(i18n("Starting KMix...")); + if (kapp->startServiceByDesktopName("kmix")==0) // trying to start kmix + { + // trying again + reply = kmixClient->call("masterMute"); + if (reply.isValid()) + { + m_mute = reply; + kmix_error = false; + kmixWindow->send("hide"); + } + } else + { + kmixWindow->send("hide"); + kmix_error = true; + } + } + + if (kmix_error) + { + kdDebug() << "KMilo: GenericMonitor could not access kmix/Mixer0 via dcop" + << endl; + //_interface->displayText + showTextMsg(i18n("It seems that KMix is not running.")); + + return false; + } else { + return true; + } +} + +void KVaio::mute() +{ + if (!retrieveMute()) + return; + + m_mute = !m_mute; + + int newVolume; + QString muteText; + if (m_mute) + { + m_oldVolume = m_volume; + newVolume = 0; + muteText = i18n("Mute on"); + } else { + newVolume = m_oldVolume; + muteText = i18n("Mute off"); + } + + kmixClient->send("setMasterMute", m_mute); + + //_interface->displayText(muteText); + showTextMsg(muteText); + +} + + +#include "kvaio.moc" |