diff options
Diffstat (limited to 'src/cpufreqd/cpufreqd.cpp')
-rw-r--r-- | src/cpufreqd/cpufreqd.cpp | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/cpufreqd/cpufreqd.cpp b/src/cpufreqd/cpufreqd.cpp new file mode 100644 index 0000000..833db29 --- /dev/null +++ b/src/cpufreqd/cpufreqd.cpp @@ -0,0 +1,156 @@ +/*************************************************************************** + * Copyright (C) 2006 by Valentine Sinitsyn * + * [email protected] * + * * + * 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 "cpufreqd.h" +#include <qdir.h> +#include <qkeysequence.h> +#include <qstringlist.h> +#include <klocale.h> + +#define CHUNK_SIZE 4096 + +/** + * cpufreqd control module main class + *@author: Valentine Sinitsyn ([email protected]) + *@todo: We assume that cpufreqd is in dynamic mode when applet is started because as for now it has + * no means to detect mode. This could lead to inconsistency if, ex. applet is restarted after making + * some changes to cpufreqd state. + */ + +CPUFreqd::CPUFreqd() { + m_menu = new QPopupMenu(); + QObject::connect(m_menu, SIGNAL(aboutToShow()), this, SLOT(updateMenu())); + + m_dynamic = new QAction(i18n("Select dynamically"), QKeySequence(), this); + QObject::connect(m_dynamic, SIGNAL(activated()), this, SLOT(setDynamic())); + m_dynamic->setToggleAction(true); + m_dynamic->setOn(true); + + m_items = new QActionGroup(this); + m_items->setExclusive(true); + + m_actions = new QPtrList<QAction>(); + m_actions->setAutoDelete(true); + + m_mapper = new QSignalMapper(this); + QObject::connect(m_mapper, SIGNAL(mapped(int)), this, SLOT(setProfile(int))); +} + +CPUFreqd::~CPUFreqd() { +} + +bool CPUFreqd::enabled() const { + return m_conn.available(); +} + +QValueVector<CPUFreqdProfile> & CPUFreqd::getProfiles(bool reconnect) { + char chunk[CHUNK_SIZE]; + QString buffer; + + if (!m_profiles.empty()) + m_profiles.clear(); + + if (!m_conn.open()) + if (reconnect) { + m_dynamic->setOn(m_conn.lookup()); + return getProfiles(false); + } else { + return m_profiles; + } + + if (!m_conn.write(CMD_LIST_PROFILES, 0)) + return m_profiles; + + int bytes = 0; + while ( (bytes = m_conn.read(chunk, CHUNK_SIZE - 1)) ) { + chunk[bytes] = '\0'; + buffer.append(chunk); + } + + QStringList profiles = QStringList::split("\n", buffer); + for (QStringList::Iterator it = profiles.begin(); it != profiles.end(); it++) + m_profiles.push_back( CPUFreqdProfile(*it) ); + + m_conn.close(); + + return m_profiles; +} + +QPopupMenu* CPUFreqd::menu() { + return m_menu; +} + +void CPUFreqd::updateMenu() { + QAction *cur; + + m_menu->clear(); + m_actions->clear(); + + getProfiles(true); + if (!m_profiles.isEmpty()) { + m_dynamic->addTo(m_menu); + m_menu->insertSeparator(); + + for (unsigned int i = 0; i < m_profiles.count(); i++) + if (m_profiles[i].isValid()) { + cur = new QAction(m_profiles[i].name(), QKeySequence(), m_items); + QObject::connect(cur, SIGNAL(activated()), m_mapper, SLOT(map())); + cur->setToggleAction(true); + cur->setOn(m_profiles[i].active()); + + m_mapper->setMapping(cur, i+1); + m_actions->append(cur); + } + m_items->addTo(m_menu); + } else { + int errmsg = m_menu->insertItem(i18n("Can't talk to cpufreqd"), 0, 0); + m_menu->setItemEnabled(errmsg, false); + } +} + +void CPUFreqd::setManual() { + setMode(ARG_MANUAL); + m_dynamic->setOn(false); +} + +void CPUFreqd::setDynamic() { + setMode(ARG_DYNAMIC); + m_dynamic->setOn(true); +} + +void CPUFreqd::setProfile(int id) { + //@fixme: make it return bool and bail out if it falis + if (m_dynamic->isOn()) + setManual(); + + if (!m_conn.open()) + return; + + m_conn.write(CMD_SET_PROFILE, (uint32_t)id); + m_conn.close(); +} + +void CPUFreqd::setMode(uint32_t mode) { + if (!m_conn.open()) + return; + + m_conn.write(CMD_SET_MODE, mode); + m_conn.close(); +} |