From 4d5797b479479c1e540b7068a3dea1a43e6d3b39 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 11 Jan 2013 14:26:36 -0600 Subject: Add profile support to libkrandr --- krandr/libkrandr.cc | 187 ++++++++++++++++++++++++++++++++++++++++++++++++---- krandr/libkrandr.h | 50 ++++++++++++-- krandr/randr.cpp | 11 +++- krandr/randr.h | 23 ++++++- 4 files changed, 250 insertions(+), 21 deletions(-) diff --git a/krandr/libkrandr.cc b/krandr/libkrandr.cc index 79faa9a88..f2aa38c7d 100644 --- a/krandr/libkrandr.cc +++ b/krandr/libkrandr.cc @@ -22,6 +22,7 @@ ***************************************************************************/ +#include #include #include @@ -30,6 +31,7 @@ #include #include +#include #include #include "libkrandr.h" @@ -423,7 +425,43 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir) return ""; } -void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString profilename, TQString kde_confdir, TQPtrList screenInfoArray) { +TQStringList KRandrSimpleAPI::getDisplayConfigurationProfiles(TQString kde_confdir) { + TQStringList ret; + + TQDir d(kde_confdir + "/displayconfig/"); + d.setFilter(TQDir::Files); + d.setSorting(TQDir::Name); + + const TQFileInfoList *list = d.entryInfoList(); + TQFileInfoListIterator it(*list); + TQFileInfo *fi; + + while ((fi = it.current()) != 0) { + if (fi->fileName() != "default") { + ret.append(fi->fileName()); + } + ++it; + } + + return ret; +} + +bool KRandrSimpleAPI::deleteDisplayConfiguration(TQString profilename, TQString kde_confdir) { + TQString fileName = kde_confdir + "/displayconfig/"; + fileName.append(profilename); + return (!unlink(fileName.ascii())); +} + +bool KRandrSimpleAPI::renameDisplayConfiguration(TQString profilename, TQString newprofilename, TQString kde_confdir) { + TQString fileName = kde_confdir + "/displayconfig/"; + TQString newFileName = fileName; + fileName.append(profilename); + newFileName.append(newprofilename); + TQDir d(kde_confdir + "/displayconfig/"); + return (d.rename(fileName, newFileName)); +} + +void KRandrSimpleAPI::saveDisplayConfiguration(bool enable, TQString profilename, TQString defaultprofilename, TQString kde_confdir, TQPtrList screenInfoArray) { int i; TQString filename; @@ -433,6 +471,7 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p KSimpleConfig* display_config = new KSimpleConfig( filename ); display_config->setGroup("General"); display_config->writeEntry("ApplySettingsOnStart", enable); + display_config->writeEntry("StartupProfileName", defaultprofilename); display_config->sync(); delete display_config; @@ -447,6 +486,7 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p SingleScreenData *screendata; for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) { display_config->setGroup(TQString("SCREEN %1").arg(i)); + display_config->writeEntry("ScreenUniqueName", screendata->screenUniqueName); display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName); display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected); display_config->writeEntry("ScreenConnected", screendata->screen_connected); @@ -483,7 +523,7 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p delete display_config; } -TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) { +TQPoint KRandrSimpleAPI::applyDisplayConfiguration(TQString profilename, TQString kde_confdir) { TQPoint ret; TQString filename = "displayglobals"; @@ -491,13 +531,16 @@ TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilenam KSimpleConfig* display_config = new KSimpleConfig( filename ); display_config->setGroup("General"); bool enabled = display_config->readBoolEntry("ApplySettingsOnStart", false); + if (profilename == "") { + profilename = display_config->readEntry("StartupProfileName", ""); + } delete display_config; if (enabled) { TQPtrList screenInfoArray; - screenInfoArray = loadSystemwideDisplayConfiguration(profilename, kde_confdir); + screenInfoArray = loadDisplayConfiguration(profilename, kde_confdir); if (screenInfoArray.count() > 0) { - applySystemwideDisplayConfiguration(screenInfoArray, FALSE, kde_confdir); + applyDisplayConfiguration(screenInfoArray, FALSE, kde_confdir); } destroyScreenInformationObject(screenInfoArray); screenInfoArray = readCurrentDisplayConfiguration(); @@ -509,13 +552,14 @@ TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilenam return ret; } -TQPtrList KRandrSimpleAPI::loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) { +TQPtrList KRandrSimpleAPI::loadDisplayConfiguration(TQString profilename, TQString kde_confdir) { int i; TQString filename; filename = profilename; - if (filename == "") + if (filename == "") { filename = "default"; + } filename.prepend(kde_confdir.append("/displayconfig/")); KSimpleConfig* display_config = new KSimpleConfig( filename ); @@ -529,6 +573,7 @@ TQPtrList KRandrSimpleAPI::loadSystemwideDisplayConfiguration( i = ((*it).remove("SCREEN ")).toInt(); screendata = new SingleScreenData; screenInfoArray.append(screendata); + screendata->screenUniqueName = display_config->readEntry("ScreenUniqueName"); screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName"); screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected"); screendata->screen_connected = display_config->readBoolEntry("ScreenConnected"); @@ -592,7 +637,7 @@ int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) { #define USE_XRANDR_PROGRAM -bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList screenInfoArray, bool test, TQString kde_confdir) { +bool KRandrSimpleAPI::applyDisplayConfiguration(TQPtrList screenInfoArray, bool test, TQString kde_confdir) { int i; int j; bool accepted = true; @@ -651,7 +696,7 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList KRandrSimpleAPI::copyScreenInformationObject(TQPtrList screenInfoArray) { + SingleScreenData *origscreendata; + SingleScreenData *copyscreendata; + TQPtrList retArray; + for ( origscreendata = screenInfoArray.first(); origscreendata; origscreendata = screenInfoArray.next() ) { + copyscreendata = new SingleScreenData; + *copyscreendata = *origscreendata; + retArray.append(copyscreendata); + } + return retArray; +} + void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList screenInfoArray) { SingleScreenData *screendata; for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) { @@ -891,7 +948,110 @@ TQPoint KRandrSimpleAPI::primaryScreenOffsetFromTLC(TQPtrList return TQPoint(primary_offset_x, primary_offset_y); } -void KRandrSimpleAPI::applySystemwideDisplayGamma(TQPtrList screenInfoArray) { +HotPlugRulesList KRandrSimpleAPI::getHotplugRules(TQString kde_confdir) { + int i; + TQString filename; + HotPlugRulesList ret; + + filename = "displayglobals"; + filename.prepend(kde_confdir.append("/")); + KSimpleConfig* display_config = new KSimpleConfig( filename ); + + TQStringList grouplist = display_config->groupList(); + for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) { + if (!(*it).startsWith("Hotplug-Rule")) { + continue; + } + HotPlugRule rule; + display_config->setGroup(*it); + rule.outputs = display_config->readListEntry("Outputs"); + rule.states = display_config->readIntListEntry("States"); + rule.profileName = display_config->readEntry("Profile"); + ret.append(rule); + } + delete display_config; + + return ret; +} + +void KRandrSimpleAPI::saveHotplugRules(HotPlugRulesList rules, TQString kde_confdir) { + int i; + TQString filename; + + filename = "displayglobals"; + filename.prepend(kde_confdir.append("/")); + KSimpleConfig* display_config = new KSimpleConfig( filename ); + TQStringList grouplist = display_config->groupList(); + for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) { + if (!(*it).startsWith("Hotplug-Rule")) { + continue; + } + display_config->deleteGroup(*it, true, false); + } + HotPlugRulesList::Iterator it; + i=0; + for (it=rules.begin(); it != rules.end(); ++it) { + display_config->setGroup(TQString("Hotplug-Rule%1").arg(i)); + display_config->writeEntry("Outputs", (*it).outputs); + display_config->writeEntry("States", (*it).states); + display_config->writeEntry("Profile", (*it).profileName); + i++; + } + display_config->sync(); + delete display_config; +} + +void KRandrSimpleAPI::applyHotplugRules(TQString kde_confdir) { + HotPlugRulesList rules = getHotplugRules(kde_confdir); + TQPtrList screenInfoArray = readCurrentDisplayConfiguration(); + + int i; + int j; + TQString bestRule; + int bestRuleMatchCount = 0; + SingleScreenData *screendata = NULL; + HotPlugRulesList::Iterator it; + for (it=rules.begin(); it != rules.end(); ++it) { + // Compare each rule against the current display configuration + // It an output matches the state given in the rule, increment matchCount + HotPlugRule rule = *it; + int matchCount = 0; + int numberOfScreens = screenInfoArray.count(); + for (i=0;iscreenUniqueName) { + continue; + } + if ((*it).states[j] == HotPlugRule::Connected) { + if (screendata->screen_connected) { + matchCount++; + } + } + else if ((*it).states[j] == HotPlugRule::Disconnected) { + if (!screendata->screen_connected) { + matchCount++; + } + } + } + } + + if (matchCount > bestRuleMatchCount) { + bestRuleMatchCount = matchCount; + bestRule = rule.profileName; + } + } + + destroyScreenInformationObject(screenInfoArray); + + if (bestRuleMatchCount > 0) { + // At least one rule matched... + // Apply the profile name in bestRule to the display hardware + applyDisplayConfiguration(bestRule, kde_confdir); + } +} + +void KRandrSimpleAPI::applyDisplayGamma(TQPtrList screenInfoArray) { int i; Display *randr_display; XRROutputInfo *output_info; @@ -943,7 +1103,7 @@ void KRandrSimpleAPI::applySystemwideDisplayGamma(TQPtrList sc } } -void KRandrSimpleAPI::applySystemwideDisplayDPMS(TQPtrList screenInfoArray) { +void KRandrSimpleAPI::applyDisplayDPMS(TQPtrList screenInfoArray) { int i; Display *randr_display; XRROutputInfo *output_info; @@ -1017,6 +1177,7 @@ TQPtrList KRandrSimpleAPI::readCurrentDisplayConfiguration() { // Create new data object screendata = new SingleScreenData; screenInfoArray.append(screendata); + screendata->screenUniqueName = TQString(i18n("%1:%2")).arg(":0").arg(capitalizeString(output_info->name)); // [FIXME] How can I get the name of the Xorg graphics driver currently in use? screendata->screenFriendlyName = TQString(i18n("%1. %2 output on %3")).arg(i+1).arg(capitalizeString(output_info->name)).arg(":0"); // [FIXME] How can I get the name of the Xorg graphics driver currently in use? screendata->generic_screen_detected = false; diff --git a/krandr/libkrandr.h b/krandr/libkrandr.h index 6f03a5c2b..201517900 100644 --- a/krandr/libkrandr.h +++ b/krandr/libkrandr.h @@ -178,43 +178,81 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay */ TQString getEDIDMonitorName(int card, TQString displayname); + /** + * Returns a HotPlugRulesList containing all hotplug rules from the specified configuration directory + */ + HotPlugRulesList getHotplugRules(TQString kde_confdir); + + /** + * Saves a HotPlugRulesList containing all hotplug rules to the specified configuration directory + */ + void saveHotplugRules(HotPlugRulesList rules, TQString kde_confdir); + + /** + * Applies all hotplug rules in the specified configuration directory to the current display configuration + */ + void applyHotplugRules(TQString kde_confdir); + + /** + * Returns a list of all profiles available in the specified configuration directory + * This list does not include the default ("") profile + */ + TQStringList getDisplayConfigurationProfiles(TQString kde_confdir); + + /** + * Deletes the specified profile from the specified configuration directory + * Returns true on success, false on failure + */ + bool deleteDisplayConfiguration(TQString profilename, TQString kde_confdir); + + /** + * Renames the specified profile in the specified configuration directory + * Returns true on success, false on failure + */ + bool renameDisplayConfiguration(TQString profilename, TQString newprofilename, TQString kde_confdir); + /** * Saves the systemwide display configuration screenInfoArray to the specified profile * If profilename is empty, the default profile is utilized * If enable is set to true, the default profile will be applied at system startup */ - void saveSystemwideDisplayConfiguration(bool enable, TQString profilename, TQString kde_confdir, TQPtrList screenInfoArray); + void saveDisplayConfiguration(bool enable, TQString profilename, TQString defaultprofilename, TQString kde_confdir, TQPtrList screenInfoArray); /** * Reads the systemwide display configuration screenInfoArray from the specified profile * If profilename is empty, the default profile is utilized * WARNING: The calling application must free the returned objects when it is done using them */ - TQPtrList loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir); + TQPtrList loadDisplayConfiguration(TQString profilename, TQString kde_confdir); /** * Applies the systemwide display configuration screenInfoArray from the specified profile * If profilename is empty, the default profile is utilized * Returns the offset of the primary screen's top left corner */ - TQPoint applySystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir); + TQPoint applyDisplayConfiguration(TQString profilename, TQString kde_confdir); /** * Applies the systemwide display configuration screenInfoArray to the hardware * If test is true, the new configuration will be loaded for a short period of time, then reverted automatically * Returns true if configuration was accepted; false if not */ - bool applySystemwideDisplayConfiguration(TQPtrList screenInfoArray, bool test=TRUE, TQString kde_confdir=""); + bool applyDisplayConfiguration(TQPtrList screenInfoArray, bool test=TRUE, TQString kde_confdir=""); /** * Applies the gamma contained within the systemwide display configuration screenInfoArray to the hardware */ - void applySystemwideDisplayGamma(TQPtrList screenInfoArray); + void applyDisplayGamma(TQPtrList screenInfoArray); /** * Applies the DPMS settings contained within the systemwide display configuration screenInfoArray to the hardware */ - void applySystemwideDisplayDPMS(TQPtrList screenInfoArray); + void applyDisplayDPMS(TQPtrList screenInfoArray); + + /** + * Copies a screen information object + */ + TQPtrList copyScreenInformationObject(TQPtrList screenInfoArray); /** * Destroys a screen information object diff --git a/krandr/randr.cpp b/krandr/randr.cpp index e118549e2..0300801ca 100644 --- a/krandr/randr.cpp +++ b/krandr/randr.cpp @@ -40,9 +40,18 @@ #undef INT32 #include +HotPlugRule::HotPlugRule() +{ + // +} + +HotPlugRule::~HotPlugRule() +{ + // +} + SingleScreenData::SingleScreenData() { -TQString screenFriendlyName; generic_screen_detected = false; screen_connected = false; diff --git a/krandr/randr.h b/krandr/randr.h index b2832ef60..b4c830f02 100644 --- a/krandr/randr.h +++ b/krandr/randr.h @@ -29,12 +29,33 @@ class KTimerDialog; class RandRScreenPrivate; -class SingleScreenData { +class KRANDR_EXPORT HotPlugRule { + public: + enum states { + AnyState = 0, + Connected = 1, + Disconnected = 2 + }; + + public: + HotPlugRule(); + virtual ~HotPlugRule(); + + public: + TQStringList outputs; + TQValueList< int > states; + TQString profileName; +}; + +typedef TQValueList< HotPlugRule > HotPlugRulesList; + +class KRANDR_EXPORT SingleScreenData { public: SingleScreenData(); virtual ~SingleScreenData(); public: + TQString screenUniqueName; TQString screenFriendlyName; bool generic_screen_detected; bool screen_connected; -- cgit v1.2.1