• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdeutils
  • Sitemap
  • Contact Us
 

kmilo

thinkpad.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the KDE project
00003 
00004    Copyright (c) 2004 Jonathan Riddell <jr@jriddell.org>
00005 
00006    Based on Demo kmilo service by George Staikos
00007    Copyright (c) 2003 George Staikos <staikos@kde.org>
00008 
00009    And tpb by Markus Braun
00010    Copyright (C) 2002,2003 Markus Braun <markus.braun@krawel.de>
00011 
00012    FreeBSD support by Markus Brueffer
00013    Copyright (C) 2005 Markus Brueffer <markus@FreeBSD.org>
00014 
00015    This library is free software; you can redistribute it and/or
00016    modify it under the terms of the GNU Library General Public
00017    License as published by the Free Software Foundation; either
00018    version 2 of the License, or (at your option) any later version.
00019 
00020    This library is distributed in the hope that it will be useful,
00021    but WITHOUT ANY WARRANTY; without even the implied warranty of
00022    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00023    Library General Public License for more details.
00024 
00025    You should have received a copy of the GNU Library General Public License
00026    along with this library; see the file COPYING.LIB.  If not, write to
00027    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00028    Boston, MA 02110-1301, USA.
00029 
00030 */
00031 
00032 #include <QDBusReply>
00033 #include <kpluginfactory.h>
00034 #include <kpluginloader.h>
00035 #include <kconfig.h>
00036 #include <kconfiggroup.h>
00037 #include <krun.h>
00038 #include <kdebug.h>
00039 #include <kurl.h>
00040 #include <klocale.h>
00041 #include "kmilointerface.h"
00042 #include <QDBusInterface>
00043 #ifdef Q_OS_FREEBSD
00044 #include <sys/sysctl.h>
00045 #endif
00046 #include <ktoolinvocation.h>
00047 
00048 #include "thinkpad.h"
00049 
00050 namespace KMilo {
00051 
00052 ThinkPadMonitor::ThinkPadMonitor(QObject* parent, const QVariantList& args): Monitor(parent, args) {
00053     m_progress = 0;
00054     m_volume = 50;  //set in retrieveVolume()
00055 }
00056 
00057 ThinkPadMonitor::~ThinkPadMonitor() {
00058 }
00059 
00060 bool ThinkPadMonitor::init() {
00061 
00062     KConfig config("kmilodrc");
00063     reconfigure(&config);
00064 
00065     if (m_run) {
00066         clearStruct(thinkpad_state);
00067         clearStruct(last_thinkpad_state);
00068         if ( getNvramState(&thinkpad_state) == false )  {
00069             return false;
00070         }
00071 
00072         if (m_softwareVolume || m_volumeStep != defaultVolumeStep) {
00073             kmixAdaptor = new QDBusInterface("org.kde.kmix", "/Mixer0", "org.kde.KMix");
00074             kmixWindowAdaptor = new QDBusInterface("org.kde.kmix","/kmix/KMixWindow", "org.kde.kmix.KMixWindow");
00075             retrieveVolume();
00076             setNvramVolume();
00077         }
00078     }
00079 
00080     return m_run;
00081 }
00082 
00083 Monitor::DisplayType ThinkPadMonitor::poll() {
00084 
00085     // save last state and get new one
00086     memcpy(&last_thinkpad_state, &thinkpad_state, sizeof(thinkpad_state_struct));
00087     getNvramState(&thinkpad_state);
00088 
00089     Monitor::DisplayType pollResult = None;
00090 
00091     // determine the state of the mute button
00092     if (thinkpad_state.mute_toggle != last_thinkpad_state.mute_toggle ||
00093         (thinkpad_state.volume_toggle != last_thinkpad_state.volume_toggle
00094          && last_thinkpad_state.mute_toggle == 1)) {
00095 
00096         showToggleMessage(i18n("Mute on"), i18n("Mute off"), thinkpad_state.mute_toggle == 1);
00097         if (m_softwareVolume || m_volumeStep != defaultVolumeStep) {
00098                         kmixAdaptor->call("setMute",QString(),(thinkpad_state.mute_toggle == 1));
00099         }
00100     }
00101 
00102     // determine the state of the Thinkpad button
00103     if (thinkpad_state.thinkpad_toggle != last_thinkpad_state.thinkpad_toggle &&
00104         thinkpad_state.hibernate_toggle == last_thinkpad_state.hibernate_toggle) {
00105         _interface->displayText(i18n("Thinkpad Button Pressed"));
00106 
00107         KUrl url(m_buttonThinkpad);
00108         (void) new KRun(url, 0, true, true);
00109     }
00110 
00111     // determine the state of ThinkLight
00112     if (thinkpad_state.thinklight_toggle != last_thinkpad_state.thinklight_toggle) {
00113         showToggleMessage(i18n("ThinkLight is on"), i18n("ThinkLight is off"), thinkpad_state.thinklight_toggle == 1);
00114     }
00115 
00116     // determine the state of the volume buttons
00117     if (thinkpad_state.volume_level != last_thinkpad_state.volume_level) {
00118 
00119         pollResult = Volume;
00120 
00121         if (m_volumeStep == defaultVolumeStep && m_softwareVolume == false) {
00122             //no need to write to nvram or set volume in software
00123             m_progress = thinkpad_state.volume_level * 100 / defaultVolumeStep;
00124         } else {
00125             if (thinkpad_state.volume_level > last_thinkpad_state.volume_level)  {
00126                 m_progress = m_volume + m_volumeStep;
00127             } else {
00128                 m_progress = m_volume - m_volumeStep;
00129             }
00130             setVolume(m_progress);
00131         }
00132 
00133     }
00134 
00135     // determine the state of the brightness buttons
00136     if (thinkpad_state.brightness_level != last_thinkpad_state.brightness_level) {
00137         pollResult = Brightness;
00138         m_progress = thinkpad_state.brightness_level * 100 / 7;
00139     }
00140 
00141     // Buttons below here are untested because they do not exist on my R31
00142 
00143     // determine the state of zoom
00144     if (thinkpad_state.zoom_toggle != last_thinkpad_state.zoom_toggle) {
00145         // showToggleMessage(i18n("Zoom is on"), i18n("Zoom is off"), thinkpad_state.zoom_toggle == 1);
00146 
00147         // Use as button since an Zooming is implemented
00148         _interface->displayText(i18n("Zoom button pressed"));
00149 
00150         KUrl url(m_buttonZoom);
00151         (void) new KRun(url, 0, true, true);
00152     }
00153 
00154     // determine the state of the home button
00155     if (thinkpad_state.home_toggle != last_thinkpad_state.home_toggle &&
00156         thinkpad_state.hibernate_toggle == last_thinkpad_state.hibernate_toggle) {
00157         _interface->displayText(i18n("Home button pressed"));
00158         KUrl url(m_buttonHome);
00159         (void) new KRun(url, 0, true, true);
00160     }
00161 
00162     // determine the state of the search button
00163     if (thinkpad_state.search_toggle != last_thinkpad_state.search_toggle &&
00164         thinkpad_state.hibernate_toggle == last_thinkpad_state.hibernate_toggle) {
00165         _interface->displayText(i18n("Search button pressed"));
00166         KUrl url(m_buttonSearch);
00167         (void) new KRun(url, 0, true, true);
00168     }
00169 
00170     // determine the state of the mail button
00171     if (thinkpad_state.mail_toggle != last_thinkpad_state.mail_toggle &&
00172         thinkpad_state.hibernate_toggle == last_thinkpad_state.hibernate_toggle) {
00173         _interface->displayText(i18n("Mail button pressed"));
00174         KUrl url(m_buttonMail);
00175         (void) new KRun(url, 0, true, true);
00176     }
00177 
00178     // determine the state of display
00179     if (thinkpad_state.display_toggle != last_thinkpad_state.display_toggle &&
00180        thinkpad_state.hibernate_toggle == last_thinkpad_state.hibernate_toggle) {
00181 
00182         // Some thinkpads have no hardware support to switch lcd/crt. They also
00183         // don't reflect the current state in thinkpad_state.display_state. So, if
00184         // thinkpad_state.display_toggle changes, but thinkpad_state.display_state does
00185         // not change, simulate the display state.
00186 
00187         unsigned int display_state = 1;
00188         if (thinkpad_state.display_state == last_thinkpad_state.display_state) {
00189             display_state = display_state % 3 + 1;
00190         } else {
00191             display_state = thinkpad_state.display_state;
00192         }
00193 
00194         switch (display_state & 0x03) {
00195         case 0x1:
00196             _interface->displayText(i18n("Display changed: LCD on, CRT off"));
00197             break;
00198 
00199         case 0x2:
00200             _interface->displayText(i18n("Display changed: LCD off, CRT on"));
00201             break;
00202 
00203         case 0x3:
00204             _interface->displayText(i18n("Display changed: LCD on, CRT on"));
00205             break;
00206         }
00207     }
00208 
00209     // determine the state of hv expansion
00210     if (thinkpad_state.expand_toggle != last_thinkpad_state.expand_toggle) {
00211         showToggleMessage(i18n("HV Expansion is on"), i18n("HV Expansion is off"), (thinkpad_state.expand_toggle & 0x01) == 1);
00212     }
00213 
00214     // determine power management mode AC
00215     if (thinkpad_state.powermgt_ac != last_thinkpad_state.powermgt_ac) {
00216         switch(thinkpad_state.powermgt_ac) {
00217         case 0x4:
00218             _interface->displayText(i18n("Power management mode AC changed: PM AC high"));
00219             break;
00220 
00221         case 0x2:
00222             _interface->displayText(i18n("Power management mode AC changed: PM AC auto"));
00223             break;
00224 
00225         case 0x1:
00226             _interface->displayText(i18n("Power management mode AC changed: PM AC manual"));
00227             break;
00228 
00229         default:
00230             _interface->displayText(i18n("Power management mode AC changed: PM AC unknown"));
00231             break;
00232         }
00233     }
00234 
00235     // determine power management mode battery
00236     if (thinkpad_state.powermgt_battery != last_thinkpad_state.powermgt_battery) {
00237         switch(thinkpad_state.powermgt_battery) {
00238         case 0x4:
00239             _interface->displayText(i18n("Power management mode battery changed: PM battery high"));
00240             break;
00241 
00242         case 0x2:
00243             _interface->displayText(i18n("Power management mode battery changed: PM battery auto"));
00244             break;
00245 
00246         case 0x1:
00247             _interface->displayText(i18n("Power management mode battery changed: PM battery manual"));
00248             break;
00249 
00250         default:
00251             _interface->displayText(i18n("Power management mode battery changed: PM battery unknown"));
00252             break;
00253         }
00254     }
00255 
00256     // determine the state of wireless lan
00257     if (thinkpad_state.wireless_toggle != last_thinkpad_state.wireless_toggle) {
00258         showToggleMessage(i18n("Wireless LAN is enabled"), i18n("Wireless LAN is disabled"), thinkpad_state.wireless_toggle == 1);
00259     }
00260 
00261     // determine the state of bluetooth
00262     if (thinkpad_state.bluetooth_toggle != last_thinkpad_state.bluetooth_toggle) {
00263         showToggleMessage(i18n("Bluetooth is enabled"), i18n("Bluetooth is disabled"), thinkpad_state.bluetooth_toggle == 1);
00264     }
00265 
00266     return pollResult;
00267 }
00268 
00269 
00270 int ThinkPadMonitor::progress() const {
00271     return m_progress;
00272 }
00273 
00274 QString ThinkPadMonitor::message() const {
00275     //unused
00276     //return i18n("yer maw!");
00277     return "";
00278 }
00279 
00280 bool ThinkPadMonitor::getNvramState(thinkpad_state_struct* thinkpad_state) {
00281 #ifndef Q_OS_FREEBSD
00282     int file;
00283     unsigned char buffer[114];
00284 
00285     // open nvram for reading
00286     // must use open/close because seek is not supported by nvram
00287     if ((file=open(m_nvramFile.toLatin1(), O_RDONLY|O_NONBLOCK)) == -1) {
00288         kError() << "Unable to open device: " << m_nvramFile << endl;
00289         return false;
00290     }
00291 
00292     // read nvram
00293     if (read(file, buffer, sizeof(buffer)) != sizeof(buffer)) {
00294         kError() << "Unable to read from device: " << m_nvramFile << endl;
00295         return false;
00296     }
00297 
00298     // close nvram device
00299     if (close(file) == -1) {
00300         kError() << "Unable to close device %s: " << m_nvramFile << endl;
00301         return false;
00302     }
00303 
00304     thinkpad_state->thinkpad_toggle
00305         = (thinkpad_state->thinkpad_toggle   & ~0x01) | (( buffer[0x57] & 0x08) >> 3);
00306     thinkpad_state->zoom_toggle
00307         = (thinkpad_state->zoom_toggle       & ~0x01) | ((~buffer[0x57] & 0x20) >> 5);
00308     thinkpad_state->display_toggle
00309         = (thinkpad_state->display_toggle    & ~0x01) | (( buffer[0x57] & 0x40) >> 6);
00310     thinkpad_state->home_toggle
00311         = (thinkpad_state->home_toggle       & ~0x01) | (( buffer[0x56] & 0x01)     );
00312     thinkpad_state->search_toggle
00313         = (thinkpad_state->search_toggle     & ~0x01) | (( buffer[0x56] & 0x02) >> 1);
00314     thinkpad_state->mail_toggle
00315         = (thinkpad_state->mail_toggle       & ~0x01) | (( buffer[0x56] & 0x04) >> 2);
00316     thinkpad_state->thinklight_toggle
00317         = (thinkpad_state->thinklight_toggle & ~0x01) | (( buffer[0x58] & 0x10) >> 4);
00318     thinkpad_state->hibernate_toggle
00319         = (thinkpad_state->hibernate_toggle  & ~0x01) | (( buffer[0x58] & 0x01)     );
00320     thinkpad_state->display_state
00321         =                                               (( buffer[0x59] & 0x03)     );
00322     thinkpad_state->expand_toggle
00323         = (thinkpad_state->expand_toggle     & ~0x01) | (( buffer[0x59] & 0x10) >> 4);
00324     thinkpad_state->brightness_level
00325         =                                               (( buffer[0x5E] & 0x07)     );
00326     thinkpad_state->brightness_toggle
00327         = (thinkpad_state->brightness_toggle & ~0x01) | (( buffer[0x5E] & 0x20) >> 5);
00328     thinkpad_state->volume_level
00329         =                                               (( buffer[0x60] & 0x0f)     );
00330     thinkpad_state->volume_toggle
00331         = (thinkpad_state->volume_toggle     & ~0x01) | (( buffer[0x60] & 0x80) >> 7);
00332     thinkpad_state->mute_toggle
00333         = (thinkpad_state->mute_toggle       & ~0x01) | (( buffer[0x60] & 0x40) >> 6);
00334     thinkpad_state->powermgt_ac
00335         =                                               (( buffer[0x39] & 0x07)     );
00336     thinkpad_state->powermgt_battery
00337         =                                               (( buffer[0x39] & 0x38) >> 3);
00338 #else
00339     u_int n = 0;
00340     size_t len = sizeof(n);
00341 
00342     if ( sysctlbyname("dev.acpi_ibm.0.hotkey", &n, &len, NULL, 0) == -1 ) {
00343         kError() << "Unable to read sysctl: dev.acpi_ibm.0.hotkey" << endl;
00344         return false;
00345     }
00346 
00347     thinkpad_state->thinkpad_toggle
00348         = (thinkpad_state->thinkpad_toggle   & ~0x01) | (( n & (1<<3)) >> 3);
00349     thinkpad_state->zoom_toggle
00350         = (thinkpad_state->zoom_toggle       & ~0x01) | (( n & (1<<4)) >> 4);
00351     thinkpad_state->display_toggle
00352         = (thinkpad_state->display_toggle    & ~0x01) | (( n & (1<<6)) >> 6);
00353     thinkpad_state->home_toggle
00354         = (thinkpad_state->home_toggle       & ~0x01) | (( n & (1<<0))     );
00355     thinkpad_state->search_toggle
00356         = (thinkpad_state->search_toggle     & ~0x01) | (( n & (1<<1)) >> 1);
00357     thinkpad_state->mail_toggle
00358         = (thinkpad_state->mail_toggle       & ~0x01) | (( n & (1<<2)) >> 2);
00359     thinkpad_state->hibernate_toggle
00360         = (thinkpad_state->hibernate_toggle  & ~0x01) | (( n & (1<<7)) >> 7);
00361     thinkpad_state->expand_toggle
00362         = (thinkpad_state->expand_toggle     & ~0x01) | (( n & (1<<9)) >> 9);
00363     thinkpad_state->brightness_toggle
00364         = (thinkpad_state->brightness_toggle & ~0x01) | (( n & (1<<10)) >> 10);
00365     thinkpad_state->volume_toggle
00366         = (thinkpad_state->volume_toggle     & ~0x01) | (( n & (1<<11)) >> 11);
00367 
00368     // Don't fail if the thinklight sysctl is not present. It is generated dynamically
00369     if ( sysctlbyname("dev.acpi_ibm.0.thinklight", &n, &len, NULL, 0) != -1 )
00370         thinkpad_state->thinklight_toggle = n;
00371     else
00372         kWarning() << "Unable to read sysctl: dev.acpi_ibm.0.thinklight" ;
00373 
00374     if ( sysctlbyname("dev.acpi_ibm.0.lcd_brightness", &n, &len, NULL, 0) == -1 ) {
00375         kError() << "Unable to read sysctl: dev.acpi_ibm.0.lcd_brightness" << endl;
00376         return false;
00377     }
00378     thinkpad_state->brightness_level = n;
00379 
00380     if ( sysctlbyname("dev.acpi_ibm.0.volume", &n, &len, NULL, 0) == -1 ) {
00381         kError() << "Unable to read sysctl: dev.acpi_ibm.0.volume" << endl;
00382         return false;
00383     }
00384     thinkpad_state->volume_level = n;
00385 
00386     if ( sysctlbyname("dev.acpi_ibm.0.mute", &n, &len, NULL, 0) == -1 ) {
00387         kError() << "Unable to read sysctl: dev.acpi_ibm.0.mute" << endl;
00388         return false;
00389     }
00390     thinkpad_state->mute_toggle = n;
00391 
00392     // Don't fail if wlan or bluetooth sysctls are not present. They are generated dynamically
00393     if ( sysctlbyname("dev.acpi_ibm.0.wlan", &n, &len, NULL, 0) != -1 )
00394         thinkpad_state->wireless_toggle = n;
00395     else
00396         kWarning() << "Unable to read sysctl: dev.acpi_ibm.0.wlan" ;
00397 
00398     if ( sysctlbyname("dev.acpi_ibm.0.bluetooth", &n, &len, NULL, 0) != -1 )
00399         thinkpad_state->bluetooth_toggle = n;
00400     else
00401         kWarning() << "Unable to read sysctl: dev.acpi_ibm.0.bluetooth" ;
00402 #endif
00403     return true;
00404 }
00405 
00406 void ThinkPadMonitor::clearStruct(thinkpad_state_struct& thinkpad_state)  {
00407     thinkpad_state.thinkpad_toggle = 0;
00408     thinkpad_state.zoom_toggle = 0;
00409     thinkpad_state.display_toggle = 0;
00410     thinkpad_state.home_toggle = 0;
00411     thinkpad_state.search_toggle = 0;
00412     thinkpad_state.mail_toggle = 0;
00413     thinkpad_state.favorites_toggle = 0;
00414     thinkpad_state.reload_toggle = 0;
00415     thinkpad_state.abort_toggle = 0;
00416     thinkpad_state.backward_toggle = 0;
00417     thinkpad_state.forward_toggle = 0;
00418     thinkpad_state.fn_toggle = 0;
00419     thinkpad_state.thinklight_toggle = 0;
00420     thinkpad_state.hibernate_toggle = 0;
00421     thinkpad_state.display_state = 0;
00422     thinkpad_state.expand_toggle = 0;
00423     thinkpad_state.brightness_level = 0;
00424     thinkpad_state.brightness_toggle = 0;
00425     thinkpad_state.volume_level = 0;
00426     thinkpad_state.volume_toggle = 0;
00427     thinkpad_state.mute_toggle = 0;
00428     thinkpad_state.ac_state = 0;
00429     thinkpad_state.powermgt_ac = 0;
00430     thinkpad_state.powermgt_battery = 0;
00431     thinkpad_state.wireless_toggle = 0;
00432     thinkpad_state.bluetooth_toggle = 0;
00433 }
00434 
00435 void ThinkPadMonitor::showToggleMessage(QString onMessage, QString offMessage, bool state) 
00436 {
00437         QString message;
00438         if (state)  {
00439             message = onMessage;
00440         } else {
00441             message = offMessage;
00442         }
00443         _interface->displayText(message);
00444 }
00445 
00446 void ThinkPadMonitor::reconfigure(KConfig* config) {
00447     KConfigGroup group = config->group("thinkpad");
00448 
00449     m_nvramFile = group.readEntry("nvram", "/dev/nvram");
00450     m_softwareVolume = group.readEntry("softwareVolume", true);
00451     m_run = group.readEntry("run", false);
00452     m_volumeStep = group.readEntry("volumeStep", defaultVolumeStep);
00453     m_buttonThinkpad = group.readEntry("buttonThinkpad", "/usr/bin/konsole");
00454     m_buttonHome = group.readEntry("buttonHome", "/usr/bin/konqueror");
00455     m_buttonSearch = group.readEntry("buttonSearch", "/usr/bin/kfind");
00456     m_buttonMail = group.readEntry("buttonMail", "/usr/bin/kmail");
00457     m_buttonZoom = group.readEntry("buttonZoom", "/usr/bin/ksnapshot");
00458 }
00459 
00460 bool ThinkPadMonitor::retrieveVolume() {
00461     bool kmix_error = false;
00462         QDBusReply<int> reply = kmixAdaptor->call("masterVolume");
00463         if( reply.isValid())
00464              m_volume = reply;
00465         else
00466             kmix_error = true;
00467         if (kmix_error) { // maybe the error occurred because kmix wasn't running
00468            if (KToolInvocation::startServiceByDesktopName("kmix")==0) { // trying to start kmix
00469               // trying again
00470               reply = kmixAdaptor->call("masterVolume");
00471               if (reply.isValid())  {
00472                  m_volume = reply;
00473                  kmix_error = false;
00474                  kmixWindowAdaptor->call("minimize");
00475               }
00476            }
00477         }
00478 #if 0
00479     DCOPReply reply = kmixClient->call("masterVolume");
00480     if (reply.isValid())  {
00481         m_volume = reply;
00482     } else {
00483         kmix_error = true;
00484     }
00485 
00486     if (kmix_error) { // maybe the error occurred because kmix wasn't running
00487         if (KToolInvocation::startServiceByDesktopName("kmix")==0) { // trying to start kmix
00488             // trying again
00489             reply = kmixClient->call("masterVolume");
00490             if (reply.isValid())  {
00491                 m_volume = reply;
00492                 kmix_error = false;
00493                 kmixWindow->send("minimize");
00494             }
00495         }
00496     }
00497 #endif
00498 
00499     if (kmix_error) {
00500         kError() << "KMilo: ThinkPadMonitor could not access kmix/Mixer0 via dcop" << endl;
00501         return false;
00502     } else {
00503         return true;
00504     }
00505 }
00506 
00507 void ThinkPadMonitor::setVolume(int volume) {
00508     if (!retrieveVolume())  {
00509         return;
00510     }
00511 
00512     if (volume > 100)  {
00513         m_volume = 100;
00514     } else if (volume < 0)  {
00515         m_volume = 0;
00516     } else {
00517         m_volume = volume;
00518     }
00519         kmixAdaptor->call("setMasterVolume",m_volume);
00520 
00521     //write back to nvram but only if volume steps is not default
00522     if (m_volumeStep != defaultVolumeStep) {
00523         setNvramVolume();
00524     }
00525     m_progress = m_volume;
00526 }
00527 
00528 void ThinkPadMonitor::setNvramVolume() {
00529 #ifndef Q_OS_FREEBSD
00530     int file;
00531     char buffer;
00532 
00533     //open nvram
00534     if ((file = open(m_nvramFile.toLatin1(), O_RDWR|O_NONBLOCK)) == -1) {
00535         kError() << "Unable to open device " << m_nvramFile << endl;
00536         return;
00537     }
00538 
00539     // jump to volume section
00540     if (lseek(file, 0x60, SEEK_SET) == -1 ) {
00541         kError() << "Unable to seek device " << m_nvramFile << endl;
00542         return;
00543     }
00544 
00545     // read nvram
00546     if (read(file, &buffer, sizeof(buffer)) != sizeof(buffer)) {
00547         kError() << "Unable to read from device " << m_nvramFile << endl;
00548         return;
00549     }
00550 
00551     // set volume_level to the value we write back to nvram
00552     // taken from tpb, unfortunately I'm not sure why it works
00553     thinkpad_state.volume_level = 0x07;
00554     buffer &= 0xf0;
00555     buffer |= thinkpad_state.volume_level;
00556 
00557     // jump to volume section
00558     if (lseek(file, 0x60, SEEK_SET) == -1 ) {
00559         kError() << "Unable to seek device " << m_nvramFile << endl;
00560         return;
00561     }
00562 
00563     // write std value for volume
00564     if (write(file, &buffer, sizeof(buffer)) != sizeof(buffer)) {
00565         kError() << "Unable to write to device " << m_nvramFile << endl;
00566         return;
00567     }
00568 
00569     close(file);
00570 #else
00571     u_int n = thinkpad_state.volume_level;
00572 
00573     if (sysctlbyname("dev.acpi_ibm.0.volume", NULL, NULL, &n, sizeof(n)))
00574         kError() << "Unable to write sysctl: dev.acpi_ibm.0.volume" << endl;
00575 #endif
00576 }
00577 
00578 } //close namespace
00579 
00580 K_PLUGIN_FACTORY(KMiloFactory, registerPlugin<KMilo::ThinkPadMonitor>();)
00581 K_EXPORT_PLUGIN(KMiloFactory("kmilo_thinkpad"))
00582 

kmilo

Skip menu "kmilo"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

kdeutils

Skip menu "kdeutils"
  • ark
  • kcalc
  • kcharselect
  • kdelirc
  • kdessh
  • kdf
  • kfloppy
  • kgpg
  • kjots
  • klaptopdaemon
  • kmilo
  • ksim
  • ktimer
  • kwallet
  • superkaramba
Generated for kdeutils by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal