/* 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 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 #include "kmilointerface.h" #include #include #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( TQObject* parent, const char* name, const TQStringList& 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_delli8k" ) )