Logo Search packages:      
Sourcecode: kdeutils-kde4 version File versions  Download package

kvaio.cpp

/* -*- 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: kvaio.cpp 721930 2007-10-06 09:41:04Z apaku $

   * 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 <fixx11h.h>

#include <QLabel>
#include <qevent.h>
#include <QDataStream>
#include <QTextStream>
#include <QDBusReply>
#include <QDBusInterface>
#include <kxmlguiwindow.h>
#include <kconfiggroup.h>
#include <klocale.h>
#include <kdebug.h>
#include <kapplication.h>
#include <ktoolinvocation.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),
      mDisp(0),
      mTimer (new QTimer (this) )
{
    setObjectName(name);
    myparent = parent;
    
    mDriver = new KVaioDriverInterface(this);

    if(!mDriver->connectToDriver())
    {
        delete mDriver; mDriver = 0L;
        kDebug() << "KVaio: Cannot connect to driver." ;
    } else {
        kDebug() << "KVaio: Connected to SonyPI driver." ;
        connect(mDriver, SIGNAL(vaioEvent(int)), SLOT(slotVaioEvent(int)));
      connect (mTimer, SIGNAL (timeout ()), SLOT (slotTimeout() ) );
      mTimer->setSingleShot (true);
      mTimer->setInterval (10000);
      mTimer->start ();
    }

    mDisp = XOpenDisplay(NULL);
    if(!mDisp)
    {
        kDebug() << "KVaio ctor: Failed to open display. Very strange."
              << 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;    
    kmixAdaptor = new QDBusInterface("org.kde.kmix", "/Mixer0", "org.kde.KMix");
    kmixWindowAdaptor = new QDBusInterface("org.kde.kmix","/kmix/KMixWindow", "org.kde.kmix.KMixWindow");

//    retrieveVolume();
//    retrieveMute();

}

KVaio::~KVaio()
{
    kDebug() << "KVaio dtor: shutting down." ;
    if(mDriver!=0)
    {
        mDriver->disconnectFromDriver();
    }
}

void KVaio::slotVaioEvent(int event)
{
    QString text;
    QTextStream stream(&text, QIODevice::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);
          kDebug() << "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()
{
#ifdef __GNUC__
#warning port to DBUS
#endif

#if 0
    bool blankonly;

    if (isKScreensaverAvailable()) {
    
        QByteArray data, replyData;
        QDataStream arg( &data,IO_WriteOnly);

        arg.setVersion(QDataStream::Qt_3_1);
        DCOPCString 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) )
        {
            kDebug() << "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) ;

    }
#endif
}

void KVaio::suspendToDisk()
{
#ifdef __GNUC__
#warning port to DBUS
#endif

#if 0
 
        QByteArray data, replyData;
        QDataStream arg( &data,IO_WriteOnly);

        arg.setVersion(QDataStream::Qt_3_1);
        DCOPCString replyType;

      mClient.call("kpowersave","KPowersaveIface","do_suspendToDisk()",
                  data, replyType, replyData) ;
#endif
}


bool KVaio::isKScreensaverAvailable()
{
#ifdef __GNUC__
#warning port to DBUS
#endif

#if 0
    if(mClient.isAttached())
        {
        // kDebug() << "KVaio::showTextMsg: attached to DCOP server." ;
        if(mClient.isApplicationRegistered("kdesktop"))
        {
            DCOPCStringList objects;

            // kDebug() << "KVaio::showTextMsg: kded is registered at dcop server."
            //           << endl;
            objects = mClient.remoteObjects("kdesktop");
            if(objects.contains("KScreensaverIface"))
            {
                // kDebug() << "KVaio::showTextMsg: kmilod is available at kded."
                //           << endl;
                return true;
            } else {
                kDebug() << "KVaio::isKScreensaverAvailable: "
                          << "KScreensaverIface is NOT available at kdesktop." << endl;
            return false;
            }
        } else {
            kDebug() << "KVaio::isKScreensaverAvailable: "
                      << "kdesktop is NOT registered at dcop server." << endl;
            return false;
        }
    } else {
        kDebug() << "KVaio::isKScreensaverAvailable: "
                  << "kdesktop is NOT registered at dcop server." << endl;
        return false;
    }
#endif
    return false;
}

bool KVaio::isKMiloDAvailable()
{
#ifdef __GNUC__
#warning port to DBUS
#endif

#if 0
    if(mClient.isAttached())
    {
        // kDebug() << "KVaio::showTextMsg: attached to DCOP server." ;
        if(mClient.isApplicationRegistered("kded"))
        {
            DCOPCStringList objects;

            // kDebug() << "KVaio::showTextMsg: kded is registered at dcop server."
            //           << endl;
            objects = mClient.remoteObjects("kded");
            if(objects.contains("kmilod"))
            {
                // kDebug() << "KVaio::showTextMsg: kmilod is available at kded."
                //           << endl;
                return true;
            } else {
                kDebug() << "KVaio::isKMiloDAvailable: "
                          << "kmilod is NOT available at kded." << endl;
                return false;
            }
        } else {
            kDebug() << "KVaio::isKMiloDAvailable: "
                      << "kded is NOT registered at dcop server." << endl;
            return false;
        }
    } else {
        kDebug() << "KVaio::isKMiloDAvailable: "
                  << "kded is NOT registered at dcop server." << endl;
        return false;
    }
#endif
    return false;
}

void KVaio::loadConfiguration(KConfig *k)
{
    KConfigGroup gr = k->group("KVaio");

    mReportUnknownEvents =
      gr.readEntry("Report_Unknown_Events", false);
    mReportPowerStatus =
      gr.readEntry("PeriodicallyReportPowerStatus", false);
    mShowPowerStatusOnBackButton =
      gr.readEntry("PowerStatusOnBackButton", true);

    kDebug() << "KVaio::loadConfiguration: " 
              << "       mReportUnknownEvents:      "
            << mReportUnknownEvents << endl
            << "       mReportPowerStatus:        "
            << mReportPowerStatus << endl
            << "mShowPowerStatusOnBackButton:     "
            << mShowPowerStatusOnBackButton << endl;
}

const KVaioDriverInterface* KVaio::driver()
{
    return mDriver;
}

void KVaio::slotTimeout ()
{
    showBatteryStatus ();

    mTimer->setInterval (4000);
    mTimer->start ();
}

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, QIODevice::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).", 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%", 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.
        kmixAdaptor->call("setMasterVolume", m_volume);
        if (m_mute)
        {
                m_mute = false;
                kmixAdaptor->call("setMute",  QString(), m_mute);
        }
}


bool KVaio::retrieveVolume() {
       bool kmix_error = false;

        QDBusReply<int> reply = kmixAdaptor->call("masterVolume");
        if( reply.isValid())
             m_volume = reply;
        else
            kmix_error = true;
        if (kmix_error) { // maybe the error occurred because kmix wasn't running
           if (KToolInvocation::startServiceByDesktopName("kmix")==0) { // trying to start kmix
              // trying again
              reply = kmixAdaptor->call("masterVolume");
              if (reply.isValid())  {
                 m_volume = reply;
                 kmix_error = false;
                 kmixWindowAdaptor->call("minimize");
              }
           }
        }
       
        if (kmix_error)
        {
                kDebug() << "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;
        QDBusReply<bool> reply = kmixAdaptor->call("mute");
        if( reply.isValid())
             m_volume = reply;
        else
            kmix_error = true;
        if (kmix_error) { // maybe the error occurred because kmix wasn't running
           showTextMsg(i18n("Starting KMix..."));
           if (KToolInvocation::startServiceByDesktopName("kmix")==0) { // trying to start kmix
              // trying again
              reply = kmixAdaptor->call("mute",0);
              if (reply.isValid())  {
                 m_mute = reply;
                 kmix_error = false;
                 kmixWindowAdaptor->call("minimize");
              }
           }
           else
           {
                  kmixWindowAdaptor->call("minimize");
                  kmix_error = true;
           }
        }

        if (kmix_error)
        {
                kDebug() << "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");
    }
    
    kmixAdaptor->call("setMute", QString(),m_mute);

    //_interface->displayText(muteText);
    showTextMsg(muteText);

}


#include "kvaio.moc"

Generated by  Doxygen 1.6.0   Back to index