summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kcmshell/main.cpp6
-rw-r--r--krandr/libkrandr.cc454
-rw-r--r--krandr/libkrandr.h81
-rw-r--r--krandr/lowlevel_randr.c5
-rw-r--r--krandr/lowlevel_randr.h1
-rw-r--r--krandr/randr.cpp60
-rw-r--r--krandr/randr.h98
-rw-r--r--kutils/kcmoduleproxy.cpp7
-rw-r--r--tdecore/tdehardwaredevices.cpp16
9 files changed, 568 insertions, 160 deletions
diff --git a/kcmshell/main.cpp b/kcmshell/main.cpp
index 778c3b9a9..902b2397f 100644
--- a/kcmshell/main.cpp
+++ b/kcmshell/main.cpp
@@ -282,7 +282,11 @@ extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
return 0;
}
- KDialogBase::DialogType dtype = KDialogBase::Plain;
+ //KDialogBase::DialogType dtype = KDialogBase::Plain; // FIXME
+ KDialogBase::DialogType dtype = KDialogBase::IconList; // Work around a bug whereby several kcontrol modules (such as displayconfig) use an incorrect size when loaded with kcmshell in the Plain mode
+ // This bug is possibly related to kcmultidialog.cpp:266 [( new TQHBoxLayout( page ) )->setAutoAdd( true );]
+ // In fact, this method of display may be preferable to the Plain mode from a UX perspective,
+ // as the icon shows the user what the active kcontrol module is called.
if ( modules.count() < 1 )
return 0;
diff --git a/krandr/libkrandr.cc b/krandr/libkrandr.cc
index f9f60471e..04dd01be6 100644
--- a/krandr/libkrandr.cc
+++ b/krandr/libkrandr.cc
@@ -22,6 +22,7 @@
***************************************************************************/
+#include <tqdir.h>
#include <tqtimer.h>
#include <tqstringlist.h>
@@ -30,6 +31,7 @@
#include <kapplication.h>
#include <stdlib.h>
+#include <unistd.h>
#include <cmath>
#include "libkrandr.h"
@@ -177,19 +179,23 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib \"%1\"").arg(fileName);
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{
- printf("Xcalib pipe error\n\r");
+ printf("Xcalib pipe error\n\r [xcalib apply]");
}
else {
- fgets(xcalib_result, 2048, pipe_xcalib);
- pclose(pipe_xcalib);
- for (i=1;i<2048;i++) {
- if (xcalib_result[i] == 0) {
- xcalib_result[i-1]=0;
- i=2048;
+ if (fgets(xcalib_result, 2048, pipe_xcalib)) {
+ pclose(pipe_xcalib);
+ for (i=1;i<2048;i++) {
+ if (xcalib_result[i] == 0) {
+ xcalib_result[i-1]=0;
+ i=2048;
+ }
+ }
+ if (strlen(xcalib_result) > 2) {
+ return xcalib_result;
}
}
- if (strlen(xcalib_result) > 2) {
- return xcalib_result;
+ else {
+ return "";
}
}
}
@@ -242,19 +248,23 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{
- printf("Xcalib pipe error\n\r");
+ printf("Xcalib pipe error\n\r [xcalib clear]");
}
else {
- fgets(xcalib_result, 2048, pipe_xcalib);
- pclose(pipe_xcalib);
- for (i=1;i<2048;i++) {
- if (xcalib_result[i] == 0) {
- xcalib_result[i-1]=0;
- i=2048;
+ if (fgets(xcalib_result, 2048, pipe_xcalib)) {
+ pclose(pipe_xcalib);
+ for (i=1;i<2048;i++) {
+ if (xcalib_result[i] == 0) {
+ xcalib_result[i-1]=0;
+ i=2048;
+ }
+ }
+ if (strlen(xcalib_result) > 2) {
+ return xcalib_result;
}
}
- if (strlen(xcalib_result) > 2) {
- return xcalib_result;
+ else {
+ return "";
}
}
}
@@ -393,25 +403,65 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir)
icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir));
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{
- printf("Xcalib pipe error\n\r");
+ printf("Xcalib pipe error [xcalib apply]\n\r");
}
else {
- fgets(xcalib_result, 2048, pipe_xcalib);
- pclose(pipe_xcalib);
- for (i=1;i<2048;i++) {
- if (xcalib_result[i] == 0) {
- xcalib_result[i-1]=0;
- i=2048;
+ if (fgets(xcalib_result, 2048, pipe_xcalib)) {
+ pclose(pipe_xcalib);
+ for (i=1;i<2048;i++) {
+ if (xcalib_result[i] == 0) {
+ xcalib_result[i-1]=0;
+ i=2048;
+ }
+ }
+ if (strlen(xcalib_result) > 2) {
+ return xcalib_result;
}
}
- if (strlen(xcalib_result) > 2) {
- return xcalib_result;
+ else {
+ return "";
}
}
return "";
}
-void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString profilename, TQString kde_confdir, TQPtrList<SingleScreenData> 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, bool applyonstart, TQString profilename, TQString defaultprofilename, TQString kde_confdir, TQPtrList<SingleScreenData> screenInfoArray) {
int i;
TQString filename;
@@ -420,13 +470,16 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p
filename.prepend(kde_confdir.append("/"));
KSimpleConfig* display_config = new KSimpleConfig( filename );
display_config->setGroup("General");
- display_config->writeEntry("ApplySettingsOnStart", enable);
+ display_config->writeEntry("EnableDisplayControl", enable);
+ display_config->writeEntry("ApplySettingsOnStart", applyonstart);
+ display_config->writeEntry("StartupProfileName", defaultprofilename);
display_config->sync();
delete display_config;
filename = profilename;
- if (filename == "")
+ if (filename == "") {
filename = "default";
+ }
filename.prepend(kde_confdir.append("/displayconfig/"));
display_config = new KSimpleConfig( filename );
@@ -435,6 +488,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);
@@ -471,21 +525,30 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p
delete display_config;
}
-TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) {
+TQPoint KRandrSimpleAPI::applyStartupDisplayConfiguration(TQString kde_confdir) {
+ bool applyonstart = getDisplayConfigurationStartupAutoApplyEnabled(kde_confdir);
+ if (applyonstart) {
+ TQString profilename = getDisplayConfigurationStartupAutoApplyName(kde_confdir);
+ return applyDisplayConfiguration(profilename, kde_confdir);
+ }
+ else {
+ return TQPoint();
+ }
+}
+
+TQPoint KRandrSimpleAPI::applyDisplayConfiguration(TQString profilename, TQString kde_confdir) {
TQPoint ret;
- TQString filename = "displayglobals";
- filename.prepend(kde_confdir.append("/"));
- KSimpleConfig* display_config = new KSimpleConfig( filename );
- display_config->setGroup("General");
- bool enabled = display_config->readBoolEntry("ApplySettingsOnStart", false);
- delete display_config;
+ bool enabled = getDisplayConfigurationEnabled(kde_confdir);
+ if (profilename == "") {
+ profilename = "default";
+ }
if (enabled) {
TQPtrList<SingleScreenData> 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();
@@ -497,13 +560,14 @@ TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilenam
return ret;
}
-TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) {
+TQPtrList<SingleScreenData> 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 );
@@ -517,6 +581,7 @@ TQPtrList<SingleScreenData> 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");
@@ -557,16 +622,16 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(
int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
int rotationFlags = 0;
TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
- if (rotationDesired == "Normal") {
+ if (rotationDesired == ROTATION_0_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate0;
}
- else if (rotationDesired == "Rotate 90 degrees") {
+ else if (rotationDesired == ROTATION_90_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate90;
}
- else if (rotationDesired == "Rotate 180 degrees") {
+ else if (rotationDesired == ROTATION_180_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate180;
}
- else if (rotationDesired == "Rotate 270 degrees") {
+ else if (rotationDesired == ROTATION_270_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate270;
}
if (screendata->has_x_flip) {
@@ -580,7 +645,7 @@ int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
#define USE_XRANDR_PROGRAM
-bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test, TQString kde_confdir) {
+bool KRandrSimpleAPI::applyDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test, TQString kde_confdir) {
int i;
int j;
bool accepted = true;
@@ -639,28 +704,13 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
xrandr_command_output = xrandr_command_output.stripWhiteSpace();
if (test) {
if (xrandr_command_output != "") {
- applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir);
+ applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
accepted = false;
destroyScreenInformationObject(oldconfig);
KMessageBox::sorry(0, xrandr_command_output, i18n("XRandR encountered a problem"));
return accepted;
}
}
-
- // HACK
- // This is needed because Qt does not properly generate screen
- // resize events when switching screens, so KDE gets stuck in the old resolution
- // This only seems to happen with more than one screen, so check for that condition...
- // FIXME: This also only occurs when the primary display has been changed
- // FIXME: Check for that condition as well!
- if (kapp->desktop()->numScreens() > 1) {
- for (i = 0; i < screenInfoArray.count(); i++) {
- screendata = screenInfoArray.at(i);
- if (screendata->is_primary == true) {
- kapp->desktop()->emitResizedSignal(i);
- }
- }
- }
#else
randr_display = tqt_xdisplay();
randr_screen_info = read_screen_info(randr_display);
@@ -749,8 +799,8 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
#endif
}
- applySystemwideDisplayGamma(screenInfoArray);
- applySystemwideDisplayDPMS(screenInfoArray);
+ applyDisplayGamma(screenInfoArray);
+ applyDisplayDPMS(screenInfoArray);
TQString current_icc_profile = getCurrentProfile();
applySystemWideIccConfiguration(kde_confdir);
applyIccConfiguration(current_icc_profile, kde_confdir);
@@ -758,7 +808,7 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
if (test == TRUE) {
int ret = showTestConfigurationDialog();
if (!ret) {
- applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir);
+ applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
accepted = false;
}
destroyScreenInformationObject(oldconfig);
@@ -767,6 +817,18 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
return accepted;
}
+TQPtrList<SingleScreenData> KRandrSimpleAPI::copyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
+ SingleScreenData *origscreendata;
+ SingleScreenData *copyscreendata;
+ TQPtrList<SingleScreenData> retArray;
+ for ( origscreendata = screenInfoArray.first(); origscreendata; origscreendata = screenInfoArray.next() ) {
+ copyscreendata = new SingleScreenData;
+ *copyscreendata = *origscreendata;
+ retArray.append(copyscreendata);
+ }
+ return retArray;
+}
+
void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
SingleScreenData *screendata;
for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) {
@@ -792,8 +854,9 @@ void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> s
bool has_primary_monitor = false;
for (i=0;i<numberOfScreens;i++) {
screendata = screenInfoArray.at(i);
- if (screendata->is_primary)
+ if (screendata->is_primary) {
has_primary_monitor = true;
+ }
}
if (!has_primary_monitor) {
for (i=0;i<numberOfScreens;i++) {
@@ -893,7 +956,148 @@ TQPoint KRandrSimpleAPI::primaryScreenOffsetFromTLC(TQPtrList<SingleScreenData>
return TQPoint(primary_offset_x, primary_offset_y);
}
-void KRandrSimpleAPI::applySystemwideDisplayGamma(TQPtrList<SingleScreenData> 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;
+}
+
+bool KRandrSimpleAPI::getDisplayConfigurationEnabled(TQString kde_confdir) {
+ TQString filename = "displayglobals";
+ filename.prepend(kde_confdir.append("/"));
+ KSimpleConfig* display_config = new KSimpleConfig( filename );
+ display_config->setGroup("General");
+ bool enabled = display_config->readBoolEntry("EnableDisplayControl", false);
+ delete display_config;
+
+ return enabled;
+}
+
+bool KRandrSimpleAPI::getDisplayConfigurationStartupAutoApplyEnabled(TQString kde_confdir) {
+ TQString filename = "displayglobals";
+ filename.prepend(kde_confdir.append("/"));
+ KSimpleConfig* display_config = new KSimpleConfig( filename );
+ display_config->setGroup("General");
+ bool applyonstart = display_config->readBoolEntry("ApplySettingsOnStart", false);
+ delete display_config;
+
+ return applyonstart;
+}
+
+TQString KRandrSimpleAPI::getDisplayConfigurationStartupAutoApplyName(TQString kde_confdir) {
+ TQString filename = "displayglobals";
+ filename.prepend(kde_confdir.append("/"));
+ KSimpleConfig* display_config = new KSimpleConfig( filename );
+ display_config->setGroup("General");
+ TQString profilename = display_config->readEntry("StartupProfileName", "");
+ delete display_config;
+
+ return profilename;
+}
+
+void KRandrSimpleAPI::applyHotplugRules(TQString kde_confdir) {
+ bool enabled = getDisplayConfigurationEnabled(kde_confdir);
+ if (!enabled) {
+ return;
+ }
+
+ HotPlugRulesList rules = getHotplugRules(kde_confdir);
+ TQPtrList<SingleScreenData> 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;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ for (j=0; j<(*it).outputs.count(); j++) {
+ if ((*it).outputs[j] != screendata->screenUniqueName) {
+ 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<SingleScreenData> screenInfoArray) {
int i;
Display *randr_display;
XRROutputInfo *output_info;
@@ -945,7 +1149,7 @@ void KRandrSimpleAPI::applySystemwideDisplayGamma(TQPtrList<SingleScreenData> sc
}
}
-void KRandrSimpleAPI::applySystemwideDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray) {
+void KRandrSimpleAPI::applyDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray) {
int i;
Display *randr_display;
XRROutputInfo *output_info;
@@ -1019,6 +1223,7 @@ TQPtrList<SingleScreenData> 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;
@@ -1105,42 +1310,53 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
// RandRScreen::ReflectX
// RandRScreen::ReflectY
- screendata->rotations.append(i18n("Normal"));
- screendata->rotations.append(i18n("Rotate 90 degrees"));
- screendata->rotations.append(i18n("Rotate 180 degrees"));
- screendata->rotations.append(i18n("Rotate 270 degrees"));
- screendata->current_orientation_mask = cur_screen->proposedRotation();
- switch (screendata->current_orientation_mask & RandRScreen::RotateMask) {
- case RandRScreen::Rotate0:
- screendata->current_rotation_index = 0;
- break;
- case RandRScreen::Rotate90:
- screendata->current_rotation_index = 1;
- break;
- case RandRScreen::Rotate180:
- screendata->current_rotation_index = 2;
- break;
- case RandRScreen::Rotate270:
- screendata->current_rotation_index = 3;
- break;
- default:
- // Shouldn't hit this one
- Q_ASSERT(screendata->current_orientation_mask & RandRScreen::RotateMask);
- break;
- }
- screendata->has_x_flip = (screendata->current_orientation_mask & RandRScreen::ReflectX);
- screendata->has_y_flip = (screendata->current_orientation_mask & RandRScreen::ReflectY);
+ screendata->rotations.append(i18n(ROTATION_0_DEGREES_STRING));
+ screendata->rotations.append(i18n(ROTATION_90_DEGREES_STRING));
+ screendata->rotations.append(i18n(ROTATION_180_DEGREES_STRING));
+ screendata->rotations.append(i18n(ROTATION_270_DEGREES_STRING));
screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0);
+ if (screendata->supports_transformations) {
+ screendata->current_orientation_mask = cur_screen->proposedRotation();
+ switch (screendata->current_orientation_mask & RandRScreen::RotateMask) {
+ case RandRScreen::Rotate0:
+ screendata->current_rotation_index = 0;
+ break;
+ case RandRScreen::Rotate90:
+ screendata->current_rotation_index = 1;
+ break;
+ case RandRScreen::Rotate180:
+ screendata->current_rotation_index = 2;
+ break;
+ case RandRScreen::Rotate270:
+ screendata->current_rotation_index = 3;
+ break;
+ default:
+ // Shouldn't hit this one
+ Q_ASSERT(screendata->current_orientation_mask & RandRScreen::RotateMask);
+ screendata->current_rotation_index = 0;
+ break;
+ }
+ screendata->has_x_flip = (screendata->current_orientation_mask & RandRScreen::ReflectX);
+ screendata->has_y_flip = (screendata->current_orientation_mask & RandRScreen::ReflectY);
+ }
+ else {
+ screendata->has_x_flip = false;
+ screendata->has_y_flip = false;
+ screendata->current_rotation_index = 0;
+ }
// Determine if this display is primary and/or extended
RROutput primaryoutput = XRRGetOutputPrimary(tqt_xdisplay(), DefaultRootWindow(tqt_xdisplay()));
- if (primaryoutput == randr_screen_info->outputs[i]->id)
+ if (primaryoutput == randr_screen_info->outputs[i]->id) {
screendata->is_primary = false;
- else
+ }
+ else {
screendata->is_primary = true;
+ }
screendata->is_extended = screen_active;
- if (!screendata->is_extended)
+ if (!screendata->is_extended) {
screendata->is_primary = false;
+ }
// Get this screen's absolute position
screendata->absolute_x_position = 0;
@@ -1257,10 +1473,21 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
numberOfScreens++;
}
- // [FIXME]
- // Set this on the real primary monitor only!
- screendata = screenInfoArray.at(0);
- screendata->is_primary = true;
+ bool primary_set = false;
+ for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
+ if (screendata->is_primary) {
+ primary_set = true;
+ break;
+ }
+ }
+ // If there is no primary monitor set, xrandr is probably not functioning correctly!
+ Q_ASSERT(primary_set);
+ if (!primary_set) {
+ // [FIXME]
+ // Set this on the real primary monitor only!
+ screendata = screenInfoArray.at(0);
+ screendata->is_primary = true;
+ }
return screenInfoArray;
}
@@ -1276,19 +1503,23 @@ TQString KRandrSimpleAPI::clearIccConfiguration() {
icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{
- printf("Xcalib pipe error\n\r");
+ printf("Xcalib pipe error [xcalib clear]\n\r");
}
else {
- fgets(xcalib_result, 2048, pipe_xcalib);
- pclose(pipe_xcalib);
- for (i=1;i<2048;i++) {
- if (xcalib_result[i] == 0) {
- xcalib_result[i-1]=0;
- i=2048;
+ if (fgets(xcalib_result, 2048, pipe_xcalib)) {
+ pclose(pipe_xcalib);
+ for (i=1;i<2048;i++) {
+ if (xcalib_result[i] == 0) {
+ xcalib_result[i-1]=0;
+ i=2048;
+ }
+ }
+ if (strlen(xcalib_result) > 2) {
+ return xcalib_result;
}
}
- if (strlen(xcalib_result) > 2) {
- return xcalib_result;
+ else {
+ return "";
}
}
return "";
@@ -1364,6 +1595,11 @@ int KRandrSimpleAPI::main_low_apply (ScreenInfo *screen_info)
return internal_main_low_apply (screen_info);
}
+void KRandrSimpleAPI::set_primary_output (ScreenInfo *screen_info, RROutput output_id)
+{
+ internal_output_set_primary(screen_info, output_id);
+}
+
bool KRandrSimpleAPI::kRandrHasRandr(void)
{
return isValid();
diff --git a/krandr/libkrandr.h b/krandr/libkrandr.h
index f29383f02..3e00d73f7 100644
--- a/krandr/libkrandr.h
+++ b/krandr/libkrandr.h
@@ -35,6 +35,11 @@
#include <ksimpleconfig.h>
#include <tdelibs_export.h>
+#define ROTATION_0_DEGREES_STRING "0 degrees"
+#define ROTATION_90_DEGREES_STRING "90 degrees"
+#define ROTATION_180_DEGREES_STRING "180 degrees"
+#define ROTATION_270_DEGREES_STRING "270 degrees"
+
/**
* Simple API covering most of the uses of libkrandr.
*
@@ -159,6 +164,11 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
int main_low_apply (ScreenInfo *screen_info);
/**
+ * Sets the primary output device to the specified output_id
+ */
+ void set_primary_output (ScreenInfo *screen_info, RROutput output_id);
+
+ /**
* Gets the binary monitor EDID for the specified card and display
*/
TQByteArray getEDID(int card, TQString displayname);
@@ -169,42 +179,101 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
TQString getEDIDMonitorName(int card, TQString displayname);
/**
+ * Returns true if the specified configuration directory has enabled display configuration
+ */
+ bool getDisplayConfigurationEnabled(TQString kde_confdir);
+
+ /**
+ * Returns true if the specified configuration directory has enabled automatic profile application on startup
+ */
+ bool getDisplayConfigurationStartupAutoApplyEnabled(TQString kde_confdir);
+
+ /**
+ * Returns the name of the automatically applied startup profile in the specified configuration directory
+ */
+ TQString getDisplayConfigurationStartupAutoApplyName(TQString kde_confdir);
+
+ /**
+ * 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<SingleScreenData> screenInfoArray);
+ void saveDisplayConfiguration(bool enable, bool applyonstart, TQString profilename, TQString defaultprofilename, TQString kde_confdir, TQPtrList<SingleScreenData> 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<SingleScreenData> loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir);
+ TQPtrList<SingleScreenData> loadDisplayConfiguration(TQString profilename, TQString kde_confdir);
+
+ /**
+ * Applies the startup display configuration profile if enabled
+ * Returns the offset of the primary screen's top left corner
+ */
+ TQPoint applyStartupDisplayConfiguration(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<SingleScreenData> screenInfoArray, bool test=TRUE, TQString kde_confdir="");
+ bool applyDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test=TRUE, TQString kde_confdir="");
/**
* Applies the gamma contained within the systemwide display configuration screenInfoArray to the hardware
*/
- void applySystemwideDisplayGamma(TQPtrList<SingleScreenData> screenInfoArray);
+ void applyDisplayGamma(TQPtrList<SingleScreenData> screenInfoArray);
/**
* Applies the DPMS settings contained within the systemwide display configuration screenInfoArray to the hardware
*/
- void applySystemwideDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray);
+ void applyDisplayDPMS(TQPtrList<SingleScreenData> screenInfoArray);
+
+ /**
+ * Copies a screen information object
+ */
+ TQPtrList<SingleScreenData> copyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray);
/**
* Destroys a screen information object
diff --git a/krandr/lowlevel_randr.c b/krandr/lowlevel_randr.c
index 251d3bef5..c7a2edc2a 100644
--- a/krandr/lowlevel_randr.c
+++ b/krandr/lowlevel_randr.c
@@ -673,3 +673,8 @@ void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *out
screen_info->cur_crtc = NULL;
output->off_set = 1;
}
+
+void internal_output_set_primary (struct ScreenInfo *screen_info, RROutput output_id)
+{
+ XRRSetOutputPrimary(screen_info->dpy, screen_info->window, output_id);
+} \ No newline at end of file
diff --git a/krandr/lowlevel_randr.h b/krandr/lowlevel_randr.h
index 54538aa44..b5825e450 100644
--- a/krandr/lowlevel_randr.h
+++ b/krandr/lowlevel_randr.h
@@ -85,6 +85,7 @@ struct ScreenInfo* internal_read_screen_info (Display *);
int internal_set_screen_size (struct ScreenInfo *screen_info);
void internal_output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *output);
+void internal_output_set_primary (struct ScreenInfo *screen_info, RROutput output_id);
struct CrtcInfo* internal_auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
XRRModeInfo *internal_find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id);
diff --git a/krandr/randr.cpp b/krandr/randr.cpp
index 3a8e77169..0300801ca 100644
--- a/krandr/randr.cpp
+++ b/krandr/randr.cpp
@@ -40,14 +40,63 @@
#undef INT32
#include <X11/extensions/Xrandr.h>
+HotPlugRule::HotPlugRule()
+{
+ //
+}
+
+HotPlugRule::~HotPlugRule()
+{
+ //
+}
+
+SingleScreenData::SingleScreenData()
+{
+ generic_screen_detected = false;
+ screen_connected = false;
+
+ current_resolution_index = 0;
+ current_refresh_rate_index = 0;
+ current_color_depth_index = 0;
+
+ gamma_red = 0.0;
+ gamma_green = 0.0;
+ gamma_blue = 0.0;
+
+ current_rotation_index = 0;
+ current_orientation_mask = 0;
+ has_x_flip = false;
+ has_y_flip = false;
+ supports_transformations = false;
+
+ is_primary = false;
+ is_extended = false;
+ absolute_x_position = 0;
+ absolute_y_position = 0;
+ current_x_pixel_count = 0;
+ current_y_pixel_count = 0;
+
+ has_dpms = false;
+ enable_dpms = false;
+ dpms_standby_delay = 0;
+ dpms_suspend_delay = 0;
+ dpms_off_delay = 0;
+}
+
+SingleScreenData::~SingleScreenData()
+{
+ //
+}
+
class RandRScreenPrivate
{
public:
RandRScreenPrivate() : config(0L) {};
~RandRScreenPrivate()
{
- if (config)
+ if (config) {
XRRFreeScreenConfigInfo(config);
+ }
}
XRRScreenConfiguration* config;
@@ -69,8 +118,9 @@ KDE_EXPORT RandRScreen::~RandRScreen()
KDE_EXPORT void RandRScreen::loadSettings()
{
- if (d->config)
+ if (d->config) {
XRRFreeScreenConfigInfo(d->config);
+ }
d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen));
@@ -102,9 +152,11 @@ KDE_EXPORT void RandRScreen::loadSettings()
ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info;
CrtcInfo *current_crtc = screeninfo->outputs[m_screen]->cur_crtc;
- int numSizes = screeninfo->res->nmode;
+ int numSizes = output_info->nmode;
for (int i = 0; i < numSizes; i++) {
- TQSize newSize = TQSize(screeninfo->res->modes[i].width, screeninfo->res->modes[i].height);
+ XRRModeInfo *xrrmode;
+ xrrmode = internal_find_mode_by_xid (screeninfo, output_info->modes[i]);
+ TQSize newSize = TQSize(xrrmode->width, xrrmode->height);
if (!m_pixelSizes.contains(newSize)) {
m_pixelSizes.append(newSize);
m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height));
diff --git a/krandr/randr.h b/krandr/randr.h
index 5e77016f2..b4c830f02 100644
--- a/krandr/randr.h
+++ b/krandr/randr.h
@@ -29,42 +29,68 @@
class KTimerDialog;
class RandRScreenPrivate;
-struct SingleScreenData {
- TQString screenFriendlyName;
- bool generic_screen_detected;
- bool screen_connected;
-
- TQStringList resolutions;
- TQStringList refresh_rates;
- TQStringList color_depths;
- TQStringList rotations;
-
- int current_resolution_index;
- int current_refresh_rate_index;
- int current_color_depth_index;
-
- float gamma_red;
- float gamma_green;
- float gamma_blue;
-
- int current_rotation_index;
- int current_orientation_mask;
- bool has_x_flip;
- bool has_y_flip;
- bool supports_transformations;
-
- bool is_primary;
- bool is_extended;
- int absolute_x_position;
- int absolute_y_position;
- int current_x_pixel_count;
- int current_y_pixel_count;
-
- bool has_dpms;
- bool enable_dpms;
- unsigned int dpms_standby_delay;
- unsigned int dpms_suspend_delay;
- unsigned int dpms_off_delay;
+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;
+
+ TQStringList resolutions;
+ TQStringList refresh_rates;
+ TQStringList color_depths;
+ TQStringList rotations;
+
+ int current_resolution_index;
+ int current_refresh_rate_index;
+ int current_color_depth_index;
+
+ float gamma_red;
+ float gamma_green;
+ float gamma_blue;
+
+ int current_rotation_index;
+ int current_orientation_mask;
+ bool has_x_flip;
+ bool has_y_flip;
+ bool supports_transformations;
+
+ bool is_primary;
+ bool is_extended;
+ int absolute_x_position;
+ int absolute_y_position;
+ int current_x_pixel_count;
+ int current_y_pixel_count;
+
+ bool has_dpms;
+ bool enable_dpms;
+ unsigned int dpms_standby_delay;
+ unsigned int dpms_suspend_delay;
+ unsigned int dpms_off_delay;
};
class RandRScreen : public TQObject
diff --git a/kutils/kcmoduleproxy.cpp b/kutils/kcmoduleproxy.cpp
index e0074defe..2323cd262 100644
--- a/kutils/kcmoduleproxy.cpp
+++ b/kutils/kcmoduleproxy.cpp
@@ -195,9 +195,10 @@ KCModule * KCModuleProxy::realModule() const
d->topLayout->addWidget( d->kcm );
- if ( !d->rootInfo && /* If it's already done */
- moduleInfo().needsRootPrivileges() /* root, anyone? */ &&
- !KUser().isSuperUser() ) /* Not necessary if we're root */
+ if ( !d->rootInfo && /* If the message was not yet created */
+ d->kcm->useRootOnlyMsg() /* and the module requests the message */ &&
+ moduleInfo().needsRootPrivileges() /* and the module wants root access */ &&
+ !KUser().isSuperUser() ) /* and we are not currently root */
{
d->rootInfo = new TQLabel( that, "rootInfo" );
diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp
index e143e00d5..c0c97679a 100644
--- a/tdecore/tdehardwaredevices.cpp
+++ b/tdecore/tdehardwaredevices.cpp
@@ -2002,7 +2002,18 @@ void TDEHardwareDevices::processHotPluggedHardware() {
emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
}
- break;
+ }
+ else if ((hwdevice->type() == TDEGenericDeviceType::Monitor)
+ && (hwdevice->systemPath().contains(systempath))) {
+ if (!hwdevice->blacklistedForUpdate()) {
+ struct udev_device *slavedev;
+ slavedev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
+ classifyUnknownDevice(slavedev, hwdevice, false);
+ udev_device_unref(slavedev);
+ updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
+ emit hardwareUpdated(hwdevice);
+ emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
+ }
}
}
}
@@ -4289,6 +4300,9 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
mdevice->internalSetVendorModel(monitor_info.second);
mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
}
+ else {
+ mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
+ }
mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
}
else {