summaryrefslogtreecommitdiffstats
path: root/kmilo/delli8k/delli8k.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmilo/delli8k/delli8k.cpp')
-rw-r--r--kmilo/delli8k/delli8k.cpp256
1 files changed, 256 insertions, 0 deletions
diff --git a/kmilo/delli8k/delli8k.cpp b/kmilo/delli8k/delli8k.cpp
new file mode 100644
index 0000000..74c0d60
--- /dev/null
+++ b/kmilo/delli8k/delli8k.cpp
@@ -0,0 +1,256 @@
+/*
+ This file is part of the KDE project
+
+ Copyright (c) 2004 Barry O'Donovan (barry.odonovan@kdemail.net)
+
+ The code in this module is heavily based on:
+ - the Asus Laptop plug-in for KMilo
+ Copyright (c) 2004 Chris Howells (howells@kde.org)
+ - the Thinkpad plug-in
+ Copyright (c) 2004 Jonathan Riddell (jr@jriddell.org)
+ - the i8k kernel module and utilities (http://www.debian.org/~dz/i8k/)
+ Copyright (c) 2001-2003 Massimo Dal Zotto <dz@debian.org>
+
+ 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 <kgenericfactory.h>
+
+#include "kmilointerface.h"
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "i8k.h"
+
+/* For compatibilty with i8k kernel driver 1.1 */
+#define I8K_VOL_MUTE_1_1 3
+
+#include "delli8k.h"
+
+namespace KMilo
+{
+
+DellI8kMonitor::DellI8kMonitor( QObject* parent, const char* name, const QStringList& args )
+ : Monitor( parent, name, args )
+{
+}
+
+DellI8kMonitor::~DellI8kMonitor()
+{
+}
+
+bool DellI8kMonitor::init()
+{
+ kdDebug() << "KMilo: loading Dell I8k KMilo plugin" << endl;
+
+ // Ensure the Dell I8k kernel module is installed/loaded
+ if( ( m_fd = open( I8K_PROC, O_RDONLY ) ) < 0 )
+ {
+ kdDebug() << "KMilo: DellI8kMonitor: unable to open i8k proc file: " << I8K_PROC
+ << " in init()" << endl;
+ return false;
+ }
+ else
+ {
+ kmixClient = new DCOPRef( "kmix", "Mixer0" );
+ kmixWindow = new DCOPRef( "kmix", "kmix-mainwindow#1" );
+ retrieveVolume();
+ retrieveMute();
+ }
+
+ return true;
+}
+
+Monitor::DisplayType DellI8kMonitor::poll()
+{
+ Monitor::DisplayType pollResult = None;
+
+ if( ( m_status = fn_status( m_fd ) ) < 0 )
+ {
+ kdDebug() << "KMilo: DellI8kMonitor: unable to read fn status in poll()" << endl;
+ return pollResult;
+ }
+ else
+ {
+ switch( m_status )
+ {
+ case I8K_VOL_UP:
+ pollResult = Volume;
+ retrieveVolume();
+ setVolume( m_volume + DELLI8K_VOLUME_STEPSIZE );
+ m_progress = m_volume;
+ break;
+ case I8K_VOL_DOWN:
+ pollResult = Volume;
+ retrieveVolume();
+ setVolume( m_volume - DELLI8K_VOLUME_STEPSIZE );
+ m_progress = m_volume;
+ break;
+ case I8K_VOL_MUTE:
+ case I8K_VOL_MUTE_1_1:
+ pollResult = None;
+ retrieveMute();
+ setMute( !m_mute );
+ if( m_mute )
+ _interface->displayText( i18n( "Mute On" ) );
+ else
+ _interface->displayText( i18n( "Mute Off" ) );
+ break;
+ case 0:
+ break;
+ default:
+ kdDebug() << "KMile: DellI8kMonitor: invalid button status: " << m_status
+ << " in poll()" << endl;
+ break;
+ }
+ }
+
+ return pollResult;
+}
+
+int DellI8kMonitor::progress() const
+{
+ return m_progress;
+}
+
+bool DellI8kMonitor::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
+ 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)
+ {
+ kdError() << "KMilo: DellI8kMonitor could not access kmix/Mixer0 via dcop" << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void DellI8kMonitor::setVolume(int volume)
+{
+ if( !retrieveVolume() )
+ {
+ return;
+ }
+
+ if( volume > 100 )
+ {
+ m_volume = 100;
+ }
+ else if( volume < 0 )
+ {
+ m_volume = 0;
+ }
+ else
+ {
+ m_volume = volume;
+ }
+
+ kmixClient->send("setMasterVolume", m_volume);
+
+ m_progress = m_volume;
+}
+
+bool DellI8kMonitor::retrieveMute()
+{
+ bool kmix_error = false;
+
+ DCOPReply reply = kmixClient->call( "masterMute" );
+
+ if( reply.isValid() )
+ {
+ m_mute = reply;
+ }
+ else
+ {
+ kmix_error = true;
+ }
+
+ if (kmix_error)
+ {
+ // maybe the error occurred because kmix wasn't running
+ 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)
+ {
+ kdError() << "KMilo: DellI8kMonitor could not access kmix/Mixer0 via dcop in isMute()" << endl;
+ return false;
+ }
+
+ return true;
+}
+
+void DellI8kMonitor::setMute( bool b )
+{
+ m_mute = b;
+ kmixClient->send( "setMasterMute", m_mute );
+}
+
+int DellI8kMonitor::fn_status( int fd )
+{
+ int args[1];
+ int rc;
+
+ if( ( rc = ioctl( fd, I8K_FN_STATUS, &args ) ) < 0 )
+ {
+ kdError() << "KMilo: DellI8kMonitor: ioctl failed in fn_status()" << endl;
+ return rc;
+ }
+
+ return args[0];
+}
+
+} //close namespace
+
+K_EXPORT_COMPONENT_FACTORY( kmilo_delli8k, KGenericFactory<KMilo::DellI8kMonitor>( "kmilo_delli8k" ) )