diff options
author | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-05-21 23:15:24 +0900 |
---|---|---|
committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2020-05-25 13:28:20 +0900 |
commit | c20f6cb658e757b8174be8fb537036bfc3c7c7a8 (patch) | |
tree | 4adf532de83136359d859202b0be0d22836dab76 | |
parent | 9fdd3356a8135aae08cb2f329af053056c3d1bb8 (diff) | |
download | tdeutils-c20f6cb658e757b8174be8fb537036bfc3c7c7a8.tar.gz tdeutils-c20f6cb658e757b8174be8fb537036bfc3c7c7a8.zip |
KMilo: added support for PulseAudio volume control.
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
-rw-r--r-- | kmilo/generic/generic_monitor.cpp | 309 | ||||
-rw-r--r-- | kmilo/generic/generic_monitor.h | 24 |
2 files changed, 122 insertions, 211 deletions
diff --git a/kmilo/generic/generic_monitor.cpp b/kmilo/generic/generic_monitor.cpp index 9017f70..44d540c 100644 --- a/kmilo/generic/generic_monitor.cpp +++ b/kmilo/generic/generic_monitor.cpp @@ -42,27 +42,54 @@ using namespace KMilo; +// now the key data (from kkeyserver_x11.h and $TQTDIR/include/tqnamespace.h) +struct ShortcutInfo +{ + const char* name; + int symbol; + const char *slot; +}; + +static const ShortcutInfo shortcuts[] = +{ + { "Search", TDEShortcut("XF86Search"), TQT_SLOT(launchSearch()) }, + { "Home Folder", TDEShortcut("XF86MyComputer"), TQT_SLOT(launchHomeFolder()) }, + { "Mail", TDEShortcut("XF86Mail"), TQT_SLOT(launchMail()) }, + { "Audio Media", TDEShortcut("XF86AudioMedia"), TQT_SLOT(launchMusic()) }, + { "Music", TDEShortcut("XF86Music"), TQT_SLOT(launchMusic()) }, + { "Browser", TDEShortcut("XF86WWW"), TQT_SLOT(launchBrowser()) }, + { "Calculator", TDEShortcut("XF86Calculator"), TQT_SLOT(launchCalculator()) }, + { "Terminal", TDEShortcut("XF86Terminal"), TQT_SLOT(launchTerminal()) }, + { "Eject", TDEShortcut("XF86Eject"), TQT_SLOT(eject()) }, + { "Help", TDEShortcut("XF86Launch0"), TQT_SLOT(launchHelp()) }, + { "Light Bulb", TDEShortcut("XF86LightBulb"), TQT_SLOT(lightBulb()) }, + { "Battery", TDEShortcut("XF86LaunchB"), TQT_SLOT(pmBattery()) }, + { "FastVolumeUp", TQt::Key_VolumeUp, TQT_SLOT(fastVolumeUp()) }, + { "FastVolumeDown", TQt::Key_VolumeDown, TQT_SLOT(fastVolumeDown()) }, + { "SlowVolumeUp", TQt::CTRL+TQt::Key_VolumeUp, TQT_SLOT(slowVolumeUp()) }, + { "SlowVolumeDown", TQt::CTRL+TQt::Key_VolumeDown, TQT_SLOT(slowVolumeDown()) }, + { "Mute", TDEShortcut("XF86AudioMute"), TQT_SLOT(toggleMute()) }, + { "BrightnessUp", TDEShortcut("XF86MonBrightnessUp"), TQT_SLOT(brightnessUp()) }, + { "BrightnessDown", TDEShortcut("XF86MonBrightnessDown"), TQT_SLOT(brightnessDown()) } +}; + GenericMonitor::GenericMonitor(TQObject *parent, const char *name, const TQStringList& args) -: Monitor(parent, name, args), kmixClient(NULL), kmixWindow(NULL), tdepowersave(NULL) +: Monitor(parent, name, args), kmixClient(NULL), kmixWindow(NULL), tdepowersave(NULL), + m_progress(0), m_displayType(Monitor::None) { _poll = false; - m_displayType = Monitor::None; - - m_mute = false; - m_progress = 0; - m_minVolume = 0; - m_maxVolume = 100; - m_volume = 50; } GenericMonitor::~GenericMonitor() { - if(ga) { - ga->remove("FastVolumeUp"); - ga->remove("FastVolumeDown"); - ga->remove("SlowVolumeUp"); - ga->remove("SlowVolumeDown"); - ga->remove("Mute"); + if (ga) + { + int len = (int)sizeof(shortcuts)/sizeof(ShortcutInfo); + for (int i = 0; i < len; i++) + { + ga->remove(shortcuts[i].name); + } + ga->updateConnections(); delete ga; } } @@ -75,27 +102,6 @@ bool GenericMonitor::init() if(!m_enabled) return false; // exit early if we are not supposed to run - static const ShortcutInfo shortcuts[] = { - { "Search", TDEShortcut("XF86Search"), TQT_SLOT(launchSearch()) }, - { "Home Folder", TDEShortcut("XF86MyComputer"), TQT_SLOT(launchHomeFolder()) }, - { "Mail", TDEShortcut("XF86Mail"), TQT_SLOT(launchMail()) }, - { "Audio Media", TDEShortcut("XF86AudioMedia"), TQT_SLOT(launchMusic()) }, - { "Music", TDEShortcut("XF86Music"), TQT_SLOT(launchMusic()) }, - { "Browser", TDEShortcut("XF86WWW"), TQT_SLOT(launchBrowser()) }, - { "Calculator", TDEShortcut("XF86Calculator"), TQT_SLOT(launchCalculator()) }, - { "Terminal", TDEShortcut("XF86Terminal"), TQT_SLOT(launchTerminal()) }, - { "Eject", TDEShortcut("XF86Eject"), TQT_SLOT(eject()) }, - { "Help", TDEShortcut("XF86Launch0"), TQT_SLOT(launchHelp()) }, - { "Light Bulb", TDEShortcut("XF86LightBulb"), TQT_SLOT(lightBulb()) }, - { "Battery", TDEShortcut("XF86LaunchB"), TQT_SLOT(pmBattery()) }, - { "FastVolumeUp", TQt::Key_VolumeUp, TQT_SLOT(fastVolumeUp()) }, - { "FastVolumeDown", TQt::Key_VolumeDown, TQT_SLOT(fastVolumeDown()) }, - { "SlowVolumeUp", TQt::CTRL+TQt::Key_VolumeUp, TQT_SLOT(slowVolumeUp()) }, - { "SlowVolumeDown", TQt::CTRL+TQt::Key_VolumeDown, TQT_SLOT(slowVolumeDown()) }, - { "Mute", TDEShortcut("XF86AudioMute"), TQT_SLOT(mute()) }, - { "BrightnessUp", TDEShortcut("XF86MonBrightnessUp"), TQT_SLOT(brightnessUp()) }, - { "BrightnessDown", TDEShortcut("XF86MonBrightnessDown"), TQT_SLOT(brightnessDown()) } - }; ga = new TDEGlobalAccel(this, "miloGenericAccel"); @@ -113,7 +119,7 @@ bool GenericMonitor::init() ga->readSettings(); ga->updateConnections(); - kmixClient = new DCOPRef("kmix", "Mixer0"); + kmixClient = new DCOPRef("kmix", "kmix"); kmixWindow = new DCOPRef("kmix", "kmix-mainwindow#1"); tdepowersave = new DCOPRef("tdepowersave", "tdepowersaveIface"); @@ -123,114 +129,72 @@ bool GenericMonitor::init() void GenericMonitor::reconfigure(TDEConfig *config) { config->setGroup("generic monitor"); - - m_volumeDeviceIdx = config->readNumEntry("volumeDeviceIdx", -1); - m_muteDeviceIdx = config->readNumEntry("muteDeviceIdx", m_volumeDeviceIdx); - m_extraDeviceIdx = config->readNumEntry("extraDeviceIdx", -1); m_volumeStepFast = config->readNumEntry("volumeStepFast", 10); m_volumeStepSlow = config->readNumEntry("volumeStepSlow", 1); m_enabled = config->readBoolEntry("enabled", true); } -bool GenericMonitor::retrieveKmixDevices() +bool GenericMonitor::retrieveVolume(int &volume) { - if(m_volumeDeviceIdx != -1 && m_muteDeviceIdx != -1) - return true; // both indexes already set - - DCOPReply reply = kmixClient->call("masterDeviceIndex"); - if (!reply.isValid()) - { // maybe the error occurred because kmix wasn't running - _interface->displayText(i18n("Starting KMix...")); - if (kapp->startServiceByDesktopName("kmix")==0) // trying to start kmix - { - reply = kmixClient->call("masterDeviceIndex"); - if (reply.isValid()) - kmixWindow->send("hide"); - } - } - - if (!reply.isValid()) + DCOPReply reply = kmixClient->call("volume"); + if (reply.isValid()) { - kdDebug() << "KMilo: GenericMonitor could not access kmix/Mixer0 via dcop" - << endl; - _interface->displayText(i18n("It seems that KMix is not running.")); - - return false; - } else { - if (m_volumeDeviceIdx == -1) - m_volumeDeviceIdx = reply; - if (m_muteDeviceIdx == -1) - m_muteDeviceIdx = m_volumeDeviceIdx; // this is the behaviour documented in README + volume = reply; return true; } + + // maybe the error occurred because kmix wasn't running. Try to start it + _interface->displayText(i18n("Starting KMix...")); + if (kapp->startServiceByDesktopName("kmix") == 0) + { + // trying again + reply = kmixClient->call("volume"); + if (reply.isValid()) + { + volume = reply; + kmixWindow->send("hide"); + return true; + } + } + kdDebug() << "KMilo: GenericMonitor could not access kmix via dcop" << endl; + _interface->displayText(i18n("It seems that KMix is not running.")); + return false; } -bool GenericMonitor::retrieveVolume() +void GenericMonitor::volumeChange(int direction, int percentage) { - bool kmix_error = false; - - if(!retrieveKmixDevices()) - return false; - - DCOPReply reply = kmixClient->call("absoluteVolume", m_volumeDeviceIdx); - if (reply.isValid()) - m_volume = reply; - else - kmix_error = true; + int volume; + if (!direction || !retrieveVolume(volume)) + { + return; + } - if (kmix_error) // maybe the error occurred because kmix wasn't running + if (direction > 0) { - _interface->displayText(i18n("Starting KMix...")); - if (kapp->startServiceByDesktopName("kmix")==0) // trying to start kmix + volume += percentage; + if (volume > 100) { - // trying again - reply = kmixClient->call("absoluteVolume", m_volumeDeviceIdx); - if (reply.isValid()) - { - m_volume = reply; - kmix_error = false; - kmixWindow->send("hide"); - } + volume = 100; } } - - if (kmix_error) + else { - kdDebug() << "KMilo: GenericMonitor could not access kmix/Mixer0 via dcop" - << endl; - _interface->displayText(i18n("It seems that KMix is not running.")); - - return false; - } else { - reply = kmixClient->call("absoluteVolumeMax", m_volumeDeviceIdx); - m_maxVolume = reply; - reply = kmixClient->call("absoluteVolumeMin", m_volumeDeviceIdx); - m_minVolume = reply; - return true; + volume -= percentage; + if (volume < 0) + { + volume = 0; + } } -} -void GenericMonitor::volumeChange(int direction, int step) -{ - if (!retrieveVolume()) - return; + _interface->displayProgress(i18n("Volume"), volume); + kmixClient->send("setVolume", volume); - /* Following snippet of code may seem to be overcomplicated, but it works for both devices with - * volume grain < 100 (32 tested) and devices with volume grain > 100 (256 tested) while preserving - * accuracy for devices with fine grain and preserving usability for devices with rough grain. */ - int userVisibleVolume = tqRound(m_volume * 100.0 / (m_maxVolume - m_minVolume)); - userVisibleVolume += direction * step; // add requested volume step - long previousVolume = m_volume; - m_volume = tqRound(m_minVolume + userVisibleVolume * (m_maxVolume - m_minVolume) / 100.0); - if (m_volume == previousVolume) // if the change was rounded to zero - m_volume += direction; - - if (m_volume > m_maxVolume) - m_volume = m_maxVolume; - if (m_volume < m_minVolume) - m_volume = m_minVolume; - - displayVolume(); + // if mute then unmute + bool muted = false; + if (retrieveMute(muted) && muted) + { + kmixClient->send("setMute", false); + } } void GenericMonitor::slowVolumeUp() { volumeChange( 1, m_volumeStepSlow); } @@ -238,90 +202,53 @@ void GenericMonitor::slowVolumeDown() { volumeChange(-1, m_volumeStepSlow); } void GenericMonitor::fastVolumeUp() { volumeChange( 1, m_volumeStepFast); } void GenericMonitor::fastVolumeDown() { volumeChange(-1, m_volumeStepFast); } -void GenericMonitor::displayVolume() +bool GenericMonitor::retrieveMute(bool &muted) { - _interface->displayProgress(i18n("Volume"), tqRound(m_volume * 100.0 / (m_maxVolume - m_minVolume))); - - // If we got this far, the DCOP communication with kmix works, - // so we don't have to test the result. - // Also, device indexes are set to their proper values. - kmixClient->send("setAbsoluteVolume", m_volumeDeviceIdx, m_volume); - if(m_extraDeviceIdx != -1) - // for simplicity, use relative volume rather that absolute (extra precision is not needed here) - kmixClient->send("setVolume", m_extraDeviceIdx, tqRound(m_volume * 100.0 / (m_maxVolume - m_minVolume))); - - // if mute then unmute - if (m_mute) + DCOPReply reply = kmixClient->call("mute"); + if (reply.isValid()) { - m_mute = false; - kmixClient->send("setMute", m_muteDeviceIdx, m_mute); + muted = reply; + return true; } -} - -bool GenericMonitor::retrieveMute() -{ - bool kmix_error = false; - - if(!retrieveKmixDevices()) - return false; - DCOPReply reply = kmixClient->call("mute", m_muteDeviceIdx); - if (reply.isValid()) - m_mute = reply; - else - kmix_error = true; - - if (kmix_error) + // maybe the error occurred because kmix wasn't running. Try to start it + _interface->displayText(i18n("Starting KMix...")); + if (kapp->startServiceByDesktopName("kmix") == 0) { - // maybe the error occurred because kmix wasn't running - _interface->displayText(i18n("Starting KMix...")); - if (kapp->startServiceByDesktopName("kmix")==0) // trying to start kmix - { - // trying again - reply = kmixClient->call("mute", m_muteDeviceIdx); - if (reply.isValid()) - { - m_mute = reply; - kmix_error = false; - kmixWindow->send("hide"); - } - } else + // trying again + reply = kmixClient->call("mute"); + if (reply.isValid()) { + muted = reply; kmixWindow->send("hide"); - kmix_error = true; + return true; } } - - if (kmix_error) - { - kdDebug() << "KMilo: GenericMonitor could not access kmix/Mixer0 via dcop" - << endl; - _interface->displayText(i18n("It seems that KMix is not running.")); - - return false; - } else { - return true; - } + kdDebug() << "KMilo: GenericMonitor could not access kmix via dcop" << endl; + _interface->displayText(i18n("It seems that KMix is not running.")); + return false; } -void GenericMonitor::mute() +void GenericMonitor::toggleMute() { - if (!retrieveMute()) + bool muted = false; + if (!retrieveMute(muted)) + { return; + } - m_mute = !m_mute; + muted = !muted; TQString muteText; - if (m_mute) + if (muted) { - muteText = i18n("Mute on"); - } else { - muteText = i18n("Mute off"); + muteText = i18n("System muted"); + } + else + { + muteText = i18n("System unmuted"); } - kmixClient->send("setMute", m_muteDeviceIdx, m_mute); - if(m_extraDeviceIdx != -1) - kmixClient->send("setMute", m_extraDeviceIdx, m_mute); - + kmixClient->send("setMute", muted); _interface->displayText(muteText); } @@ -367,12 +294,12 @@ void GenericMonitor::brightnessChange(int direction, int step) } } -int GenericMonitor::progress() const +int GenericMonitor::progress() const { return m_progress; } -Monitor::DisplayType GenericMonitor::poll() +Monitor::DisplayType GenericMonitor::poll() { return m_displayType; } diff --git a/kmilo/generic/generic_monitor.h b/kmilo/generic/generic_monitor.h index 9305ac3..ea75593 100644 --- a/kmilo/generic/generic_monitor.h +++ b/kmilo/generic/generic_monitor.h @@ -36,15 +36,6 @@ namespace KMilo { -// now the key data (from kkeyserver_x11.h and $TQTDIR/include/tqnamespace.h) -struct ShortcutInfo -{ - const char* name; - uint symbol; - const char *slot; -}; - - class GenericMonitor : public Monitor { Q_OBJECT @@ -64,7 +55,7 @@ public slots: void slowVolumeDown(); void fastVolumeUp(); void fastVolumeDown(); - void mute(); + void toggleMute(); void brightnessUp(); void brightnessDown(); void launchMail(); @@ -80,11 +71,9 @@ public slots: void pmBattery(); private: - bool retrieveKmixDevices(); - void volumeChange(int direction, int step); - bool retrieveMute(); - bool retrieveVolume(); - void displayVolume(); + void volumeChange(int direction, int percentage); + bool retrieveMute(bool &muted); + bool retrieveVolume(int &volume); void brightnessChange(int direction, int step); void launch(TQString configKey, TQString defaultApplication); @@ -94,14 +83,9 @@ private: DCOPRef *kmixClient, *kmixWindow, *tdepowersave; int m_progress; - long m_volume; - bool m_mute; - - long m_maxVolume, m_minVolume; // following properties are read from config file: int m_volumeStepFast, m_volumeStepSlow; - int m_volumeDeviceIdx, m_muteDeviceIdx, m_extraDeviceIdx; bool m_enabled; Monitor::DisplayType m_displayType; |