You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
607 lines
15 KiB
607 lines
15 KiB
/* -*- 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 TQt 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 <tqlabel.h>
|
|
#include <tqcstring.h>
|
|
#include <tqevent.h>
|
|
#include <tqdatastream.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)
|
|
: TQObject(parent, name),
|
|
mDisp(0),
|
|
mTimer (new TQTimer (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, TQT_SIGNAL(vaioEvent(int)), TQT_SLOT(slotVaioEvent(int)));
|
|
connect (mTimer, TQT_SIGNAL (timeout ()), TQT_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)
|
|
{
|
|
TQString text;
|
|
TQTextStream 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 TQString& msg)
|
|
{
|
|
return myparent->showTextMsg(msg);
|
|
}
|
|
|
|
|
|
|
|
bool KVaio::showProgressMsg(const TQString& msg, int value)
|
|
{
|
|
m_progress = value;
|
|
return myparent->showProgressMsg(msg,value);
|
|
}
|
|
|
|
void KVaio::blankScreen()
|
|
{
|
|
bool blankonly;
|
|
|
|
if (isKScreensaverAvailable()) {
|
|
|
|
TQByteArray data, replyData;
|
|
TQDataStream arg(data, IO_WriteOnly);
|
|
TQCString 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()
|
|
{
|
|
TQByteArray data, replyData;
|
|
TQDataStream arg(data, IO_WriteOnly);
|
|
TQCString 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;
|
|
|
|
TQString text, acMsg;
|
|
TQTextStream 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;
|
|
TQString 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"
|