00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "solid-powermanagement.h"
00021
00022
00023 #include <QString>
00024 #include <QStringList>
00025 #include <QMetaProperty>
00026 #include <QMetaEnum>
00027 #include <QTimer>
00028
00029 #include <kcomponentdata.h>
00030 #include <kcmdlineargs.h>
00031 #include <klocale.h>
00032 #include <k3socketaddress.h>
00033 #include <kdebug.h>
00034
00035 #include <solid/device.h>
00036 #include <solid/genericinterface.h>
00037 #include <solid/storageaccess.h>
00038 #include <solid/opticaldrive.h>
00039
00040 #include <solid/control/powermanager.h>
00041
00042 #include <kjob.h>
00043
00044
00045 #include <iostream>
00046 using namespace std;
00047
00048 static const char appName[] = "solid-powermanagement";
00049 static const char programName[] = I18N_NOOP("solid-powermanagement");
00050
00051 static const char description[] = I18N_NOOP("KDE tool for querying and controlling your power management options from the command line");
00052
00053 static const char version[] = "0.1";
00054
00055 std::ostream &operator<<(std::ostream &out, const QString &msg)
00056 {
00057 return (out << msg.toLocal8Bit().constData());
00058 }
00059
00060 std::ostream &operator<<(std::ostream &out, const QVariant &value)
00061 {
00062 switch (value.type())
00063 {
00064 case QVariant::StringList:
00065 {
00066 out << "{";
00067
00068 QStringList list = value.toStringList();
00069
00070 QStringList::ConstIterator it = list.constBegin();
00071 QStringList::ConstIterator end = list.constEnd();
00072
00073 for (; it!=end; ++it)
00074 {
00075 out << "'" << *it << "'";
00076
00077 if (it+1!=end)
00078 {
00079 out << ", ";
00080 }
00081 }
00082
00083 out << "} (string list)";
00084 break;
00085 }
00086 case QVariant::Bool:
00087 out << (value.toBool()?"true":"false") << " (bool)";
00088 break;
00089 case QVariant::Int:
00090 out << value.toString()
00091 << " (0x" << QString::number(value.toInt(), 16) << ") (int)";
00092 break;
00093 default:
00094 out << "'" << value.toString() << "' (string)";
00095 break;
00096 }
00097
00098 return out;
00099 }
00100
00101 std::ostream &operator<<(std::ostream &out, const Solid::Device &device)
00102 {
00103 out << " parent = " << QVariant(device.parentUdi()) << endl;
00104 out << " vendor = " << QVariant(device.vendor()) << endl;
00105 out << " product = " << QVariant(device.product()) << endl;
00106
00107 int index = Solid::DeviceInterface::staticMetaObject.indexOfEnumerator("Type");
00108 QMetaEnum typeEnum = Solid::DeviceInterface::staticMetaObject.enumerator(index);
00109
00110 for (int i=0; i<typeEnum.keyCount(); i++)
00111 {
00112 Solid::DeviceInterface::Type type = (Solid::DeviceInterface::Type)typeEnum.value(i);
00113 const Solid::DeviceInterface *interface = device.asDeviceInterface(type);
00114
00115 if (interface)
00116 {
00117 const QMetaObject *meta = interface->metaObject();
00118
00119 for (int i=meta->propertyOffset(); i<meta->propertyCount(); i++)
00120 {
00121 QMetaProperty property = meta->property(i);
00122 out << " " << QString(meta->className()).mid(7) << "." << property.name()
00123 << " = ";
00124
00125 QVariant value = property.read(interface);
00126
00127 if (property.isEnumType()) {
00128 QMetaEnum metaEnum = property.enumerator();
00129 out << "'" << metaEnum.valueToKeys(value.toInt()).constData() << "'"
00130 << " (0x" << QString::number(value.toInt(), 16) << ") ";
00131 if (metaEnum.isFlag()) {
00132 out << "(flag)";
00133 } else {
00134 out << "(enum)";
00135 }
00136 out << endl;
00137 } else {
00138 out << value << endl;
00139 }
00140 }
00141 }
00142 }
00143
00144 return out;
00145 }
00146
00147 std::ostream &operator<<(std::ostream &out, const QMap<QString,QVariant> &properties)
00148 {
00149 foreach (const QString& key, properties.keys())
00150 {
00151 out << " " << key << " = " << properties[key] << endl;
00152 }
00153
00154 return out;
00155 }
00156
00157 void checkArgumentCount(int min, int max)
00158 {
00159 int count = KCmdLineArgs::parsedArgs()->count();
00160
00161 if (count < min)
00162 {
00163 cerr << i18n("Syntax Error: Not enough arguments") << endl;
00164 ::exit(1);
00165 }
00166
00167 if ((max > 0) && (count > max))
00168 {
00169 cerr << i18n("Syntax Error: Too many arguments") << endl;
00170 ::exit(1);
00171 }
00172 }
00173
00174 int main(int argc, char **argv)
00175 {
00176 KCmdLineArgs::init(argc, argv, appName, 0, ki18n(programName), version, ki18n(description), false);
00177
00178
00179 KCmdLineOptions options;
00180
00181 options.add("commands", ki18n("Show available commands"));
00182
00183 options.add("+command", ki18n("Command (see --commands)"));
00184
00185 options.add("+[arg(s)]", ki18n("Arguments for command"));
00186
00187 KCmdLineArgs::addCmdLineOptions(options);
00188
00189 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00190
00191 KComponentData componentData(appName);
00192
00193 if (args->isSet("commands"))
00194 {
00195 KCmdLineArgs::enable_i18n();
00196
00197 cout << endl << i18n("Syntax:") << endl << endl;
00198
00199 cout << " solid-powermanagement query (suspend|scheme|cpufreq)" << endl;
00200 cout << i18n(" # List a particular set of information regarding power management.\n"
00201 " # - If the 'suspend' option is specified, give the list of suspend\n"
00202 " # method supported by the system\n"
00203 " # - If the 'scheme' option is specified, give the list of\n"
00204 " # supported power management schemes by this system\n"
00205 " # - If the 'cpufreq' option is specified, give the list of\n"
00206 " # supported CPU frequency policy\n") << endl;
00207
00208 cout << " solid-powermanagement set (scheme|cpufreq) 'value'" << endl;
00209 cout << i18n(" # Set power management options of the system.\n"
00210 " # - If the 'scheme' option is specified, the power management\n"
00211 " # scheme set corresponds to 'value'\n"
00212 " # - If the 'cpufreq' option is specified, the CPU frequency policy\n"
00213 " # set corresponds to 'value'\n") << endl;
00214
00215 cout << " solid-powermanagement suspend 'method'" << endl;
00216 cout << i18n(" # Suspend the computer using the given 'method'.\n") << endl;
00217
00218 cout << " solid-powermanagement brightness (set|get) 'value'" << endl;
00219 cout << i18n(" # Set and get brightness options of the system.\n"
00220 " # - If the 'set' option is specified, the brightness is\n"
00221 " # set to 'value' (as a percentage)\n"
00222 " # - If the 'get' option is specified, the current brightness\n"
00223 " # is returned (as a percentage)'\n") << endl;
00224
00225 cout << endl;
00226
00227 return 0;
00228 }
00229
00230 return SolidPowermanagement::doIt() ? 0 : 1;
00231 }
00232
00233 bool SolidPowermanagement::doIt()
00234 {
00235 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00236 checkArgumentCount(1, 0);
00237
00238 QString command(args->arg(0));
00239
00240 int fake_argc = 0;
00241 char **fake_argv = 0;
00242 SolidPowermanagement shell(fake_argc, fake_argv);
00243
00244 if (command == "suspend")
00245 {
00246 checkArgumentCount(2, 2);
00247 QString method(args->arg(1));
00248
00249 return shell.powerSuspend(method);
00250 }
00251 else if (command == "query")
00252 {
00253 checkArgumentCount(2, 2);
00254 QString type(args->arg(1));
00255
00256 if (type == "suspend")
00257 {
00258 return shell.powerQuerySuspendMethods();
00259 }
00260 else if (type == "scheme")
00261 {
00262 return shell.powerQuerySchemes();
00263 }
00264 else if (type == "cpufreq")
00265 {
00266 return shell.powerQueryCpuPolicies();
00267 }
00268 else
00269 {
00270 cerr << i18n("Syntax Error: Unknown option '%1'" , type) << endl;
00271 }
00272 }
00273 else if (command == "set")
00274 {
00275 checkArgumentCount(3, 3);
00276 QString type(args->arg(1));
00277 QString value(args->arg(2));
00278
00279 if (type == "scheme")
00280 {
00281 return shell.powerChangeScheme(value);
00282 }
00283 else if (type == "cpufreq")
00284 {
00285 return shell.powerChangeCpuPolicy(value);
00286 }
00287 else
00288 {
00289 cerr << i18n("Syntax Error: Unknown option '%1'" , type) << endl;
00290 }
00291 }
00292 else if (command == "brightness")
00293 {
00294 QString request(args->arg(1));
00295 if (request == "get")
00296 {
00297 cout << endl << "Brightness is " << shell.powerGetBrightness() << "%" << endl;
00298 }
00299 else if (request == "set")
00300 {
00301 return shell.powerSetBrightness(args->arg(2).toInt());
00302 }
00303 }
00304 else
00305 {
00306 cerr << i18n("Syntax Error: Unknown command '%1'" , command) << endl;
00307 }
00308
00309 return false;
00310 }
00311
00312 bool SolidPowermanagement::powerQuerySuspendMethods()
00313 {
00314 Solid::Control::PowerManager::SuspendMethods methods = Solid::Control::PowerManager::supportedSuspendMethods();
00315
00316 if (methods & Solid::Control::PowerManager::ToDisk)
00317 {
00318 cout << "to_disk" << endl;
00319 }
00320
00321 if (methods & Solid::Control::PowerManager::ToRam)
00322 {
00323 cout << "to_ram" << endl;
00324 }
00325
00326 if (methods & Solid::Control::PowerManager::Standby)
00327 {
00328 cout << "standby" << endl;
00329 }
00330
00331 return true;
00332 }
00333
00334 bool SolidPowermanagement::powerSuspend(const QString &strMethod)
00335 {
00336 Solid::Control::PowerManager::SuspendMethods supported
00337 = Solid::Control::PowerManager::supportedSuspendMethods();
00338
00339 Solid::Control::PowerManager::SuspendMethod method = Solid::Control::PowerManager::UnknownSuspendMethod;
00340
00341 if (strMethod == "to_disk" && (supported & Solid::Control::PowerManager::ToDisk))
00342 {
00343 method = Solid::Control::PowerManager::ToDisk;
00344 }
00345 else if (strMethod == "to_ram" && (supported & Solid::Control::PowerManager::ToRam))
00346 {
00347 method = Solid::Control::PowerManager::ToRam;
00348 }
00349 else if (strMethod == "standby" && (supported & Solid::Control::PowerManager::Standby))
00350 {
00351 method = Solid::Control::PowerManager::Standby;
00352 }
00353 else
00354 {
00355 cerr << i18n("Unsupported suspend method: %1" , strMethod) << endl;
00356 return false;
00357 }
00358
00359 KJob *job = Solid::Control::PowerManager::suspend(method);
00360
00361 if (job==0)
00362 {
00363 cerr << i18n("Error: unsupported operation!") << endl;
00364 return false;
00365 }
00366
00367 connectJob(job);
00368
00369 job->start();
00370 m_loop.exec();
00371
00372 if (m_error)
00373 {
00374 cerr << i18n("Error: %1" , m_errorString) << endl;
00375 return false;
00376 }
00377 else
00378 {
00379 return true;
00380 }
00381 }
00382
00383 bool SolidPowermanagement::powerQuerySchemes()
00384 {
00385 QString current = Solid::Control::PowerManager::scheme();
00386 QStringList schemes = Solid::Control::PowerManager::supportedSchemes();
00387
00388 foreach (const QString& scheme, schemes)
00389 {
00390 cout << scheme << " (" << Solid::Control::PowerManager::schemeDescription(scheme) << ")";
00391
00392 if (scheme==current)
00393 {
00394 cout << " [*]" << endl;
00395 }
00396 else
00397 {
00398 cout << endl;
00399 }
00400 }
00401
00402 return true;
00403 }
00404
00405 bool SolidPowermanagement::powerChangeScheme(const QString &schemeName)
00406 {
00407 QStringList supported = Solid::Control::PowerManager::supportedSchemes();
00408
00409 if (!supported.contains(schemeName))
00410 {
00411 cerr << i18n("Unsupported scheme: %1" , schemeName) << endl;
00412 return false;
00413 }
00414
00415 return Solid::Control::PowerManager::setScheme(schemeName);
00416 }
00417
00418 bool SolidPowermanagement::powerQueryCpuPolicies()
00419 {
00420 Solid::Control::PowerManager::CpuFreqPolicy current = Solid::Control::PowerManager::cpuFreqPolicy();
00421 Solid::Control::PowerManager::CpuFreqPolicies policies = Solid::Control::PowerManager::supportedCpuFreqPolicies();
00422
00423 QList<Solid::Control::PowerManager::CpuFreqPolicy> all_policies;
00424 all_policies << Solid::Control::PowerManager::OnDemand
00425 << Solid::Control::PowerManager::Userspace
00426 << Solid::Control::PowerManager::Powersave
00427 << Solid::Control::PowerManager::Performance
00428 << Solid::Control::PowerManager::Conservative;
00429
00430 foreach (Solid::Control::PowerManager::CpuFreqPolicy policy, all_policies)
00431 {
00432 if (policies & policy)
00433 {
00434 switch (policy)
00435 {
00436 case Solid::Control::PowerManager::OnDemand:
00437 cout << "ondemand";
00438 break;
00439 case Solid::Control::PowerManager::Userspace:
00440 cout << "userspace";
00441 break;
00442 case Solid::Control::PowerManager::Powersave:
00443 cout << "powersave";
00444 break;
00445 case Solid::Control::PowerManager::Performance:
00446 cout << "performance";
00447 break;
00448 case Solid::Control::PowerManager::Conservative:
00449 cout << "conservative";
00450 break;
00451 case Solid::Control::PowerManager::UnknownCpuFreqPolicy:
00452 break;
00453 }
00454
00455 if (policy==current)
00456 {
00457 cout << " [*]" << endl;
00458 }
00459 else
00460 {
00461 cout << endl;
00462 }
00463 }
00464 }
00465
00466 return true;
00467 }
00468
00469 bool SolidPowermanagement::powerChangeCpuPolicy(const QString &policyName)
00470 {
00471 Solid::Control::PowerManager::CpuFreqPolicies supported
00472 = Solid::Control::PowerManager::supportedCpuFreqPolicies();
00473
00474 Solid::Control::PowerManager::CpuFreqPolicy policy = Solid::Control::PowerManager::UnknownCpuFreqPolicy;
00475
00476 if (policyName == "ondemand" && (supported & Solid::Control::PowerManager::OnDemand))
00477 {
00478 policy = Solid::Control::PowerManager::OnDemand;
00479 }
00480 else if (policyName == "userspace" && (supported & Solid::Control::PowerManager::Userspace))
00481 {
00482 policy = Solid::Control::PowerManager::Userspace;
00483 }
00484 else if (policyName == "performance" && (supported & Solid::Control::PowerManager::Performance))
00485 {
00486 policy = Solid::Control::PowerManager::Performance;
00487 }
00488 else if (policyName == "powersave" && (supported & Solid::Control::PowerManager::Powersave))
00489 {
00490 policy = Solid::Control::PowerManager::Powersave;
00491 }
00492 else if (policyName == "conservative" && (supported & Solid::Control::PowerManager::Conservative))
00493 {
00494 policy = Solid::Control::PowerManager::Conservative;
00495 }
00496 else
00497 {
00498 cerr << i18n("Unsupported cpufreq policy: %1" , policyName) << endl;
00499 return false;
00500 }
00501
00502 return Solid::Control::PowerManager::setCpuFreqPolicy(policy);
00503 }
00504
00505 int SolidPowermanagement::powerGetBrightness()
00506 {
00507 return Solid::Control::PowerManager::brightness();
00508 }
00509
00510 bool SolidPowermanagement::powerSetBrightness(int brightness)
00511 {
00512 cout << "Setting brightness to " << brightness << "%" << endl;
00513 return Solid::Control::PowerManager::setBrightness(brightness);
00514 }
00515
00516
00517 void SolidPowermanagement::connectJob(KJob *job)
00518 {
00519 connect(job, SIGNAL(result(KJob *)),
00520 this, SLOT(slotResult(KJob *)));
00521 connect(job, SIGNAL(percent(KJob *, unsigned long)),
00522 this, SLOT(slotPercent(KJob *, unsigned long)));
00523 connect(job, SIGNAL(infoMessage(KJob *, const QString &, const QString &)),
00524 this, SLOT(slotInfoMessage(KJob *, const QString &)));
00525 }
00526
00527 void SolidPowermanagement::slotPercent(KJob *, unsigned long percent)
00528 {
00529 cout << i18n("Progress: %1%" , percent) << endl;
00530 }
00531
00532 void SolidPowermanagement::slotInfoMessage(KJob *, const QString &message)
00533 {
00534 cout << i18n("Info: %1" , message) << endl;
00535 }
00536
00537 void SolidPowermanagement::slotResult(KJob *job)
00538 {
00539 m_error = 0;
00540
00541 if (job->error())
00542 {
00543 m_error = job->error();
00544 m_errorString = job->errorString();
00545 }
00546
00547 m_loop.exit();
00548 }
00549
00550 void SolidPowermanagement::slotStorageResult(Solid::ErrorType error, const QVariant &errorData)
00551 {
00552 if (error) {
00553 m_error = 1;
00554 m_errorString = errorData.toString();
00555 }
00556 m_loop.exit();
00557 }
00558
00559 #include "solid-powermanagement.moc"