Darrell Anderson 12 years ago
commit 2c10a4aac7

@ -282,7 +282,11 @@ extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
return 0; 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 ) if ( modules.count() < 1 )
return 0; return 0;

@ -22,6 +22,7 @@
***************************************************************************/ ***************************************************************************/
#include <tqdir.h>
#include <tqtimer.h> #include <tqtimer.h>
#include <tqstringlist.h> #include <tqstringlist.h>
@ -30,6 +31,7 @@
#include <kapplication.h> #include <kapplication.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <cmath> #include <cmath>
#include "libkrandr.h" #include "libkrandr.h"
@ -177,19 +179,23 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib \"%1\"").arg(fileName); icc_command = TQString("xcalib \"%1\"").arg(fileName);
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error\n\r [xcalib apply]");
} }
else { else {
fgets(xcalib_result, 2048, pipe_xcalib); if (fgets(xcalib_result, 2048, pipe_xcalib)) {
pclose(pipe_xcalib); pclose(pipe_xcalib);
for (i=1;i<2048;i++) { for (i=1;i<2048;i++) {
if (xcalib_result[i] == 0) { if (xcalib_result[i] == 0) {
xcalib_result[i-1]=0; xcalib_result[i-1]=0;
i=2048; i=2048;
}
}
if (strlen(xcalib_result) > 2) {
return xcalib_result;
} }
} }
if (strlen(xcalib_result) > 2) { else {
return xcalib_result; return "";
} }
} }
} }
@ -242,19 +248,23 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib -c"); icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error\n\r [xcalib clear]");
} }
else { else {
fgets(xcalib_result, 2048, pipe_xcalib); if (fgets(xcalib_result, 2048, pipe_xcalib)) {
pclose(pipe_xcalib); pclose(pipe_xcalib);
for (i=1;i<2048;i++) { for (i=1;i<2048;i++) {
if (xcalib_result[i] == 0) { if (xcalib_result[i] == 0) {
xcalib_result[i-1]=0; xcalib_result[i-1]=0;
i=2048; i=2048;
}
}
if (strlen(xcalib_result) > 2) {
return xcalib_result;
} }
} }
if (strlen(xcalib_result) > 2) { else {
return xcalib_result; return "";
} }
} }
} }
@ -393,25 +403,65 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir)
icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir)); icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir));
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error [xcalib apply]\n\r");
} }
else { else {
fgets(xcalib_result, 2048, pipe_xcalib); if (fgets(xcalib_result, 2048, pipe_xcalib)) {
pclose(pipe_xcalib); pclose(pipe_xcalib);
for (i=1;i<2048;i++) { for (i=1;i<2048;i++) {
if (xcalib_result[i] == 0) { if (xcalib_result[i] == 0) {
xcalib_result[i-1]=0; xcalib_result[i-1]=0;
i=2048; i=2048;
}
}
if (strlen(xcalib_result) > 2) {
return xcalib_result;
} }
} }
if (strlen(xcalib_result) > 2) { else {
return xcalib_result; return "";
} }
} }
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; int i;
TQString filename; TQString filename;
@ -420,13 +470,16 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p
filename.prepend(kde_confdir.append("/")); filename.prepend(kde_confdir.append("/"));
KSimpleConfig* display_config = new KSimpleConfig( filename ); KSimpleConfig* display_config = new KSimpleConfig( filename );
display_config->setGroup("General"); 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(); display_config->sync();
delete display_config; delete display_config;
filename = profilename; filename = profilename;
if (filename == "") if (filename == "") {
filename = "default"; filename = "default";
}
filename.prepend(kde_confdir.append("/displayconfig/")); filename.prepend(kde_confdir.append("/displayconfig/"));
display_config = new KSimpleConfig( filename ); display_config = new KSimpleConfig( filename );
@ -435,6 +488,7 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p
SingleScreenData *screendata; SingleScreenData *screendata;
for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) { for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
display_config->setGroup(TQString("SCREEN %1").arg(i)); display_config->setGroup(TQString("SCREEN %1").arg(i));
display_config->writeEntry("ScreenUniqueName", screendata->screenUniqueName);
display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName); display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName);
display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected); display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected);
display_config->writeEntry("ScreenConnected", screendata->screen_connected); display_config->writeEntry("ScreenConnected", screendata->screen_connected);
@ -471,21 +525,30 @@ void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(bool enable, TQString p
delete display_config; 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; TQPoint ret;
TQString filename = "displayglobals"; bool enabled = getDisplayConfigurationEnabled(kde_confdir);
filename.prepend(kde_confdir.append("/")); if (profilename == "") {
KSimpleConfig* display_config = new KSimpleConfig( filename ); profilename = "default";
display_config->setGroup("General"); }
bool enabled = display_config->readBoolEntry("ApplySettingsOnStart", false);
delete display_config;
if (enabled) { if (enabled) {
TQPtrList<SingleScreenData> screenInfoArray; TQPtrList<SingleScreenData> screenInfoArray;
screenInfoArray = loadSystemwideDisplayConfiguration(profilename, kde_confdir); screenInfoArray = loadDisplayConfiguration(profilename, kde_confdir);
if (screenInfoArray.count() > 0) { if (screenInfoArray.count() > 0) {
applySystemwideDisplayConfiguration(screenInfoArray, FALSE, kde_confdir); applyDisplayConfiguration(screenInfoArray, FALSE, kde_confdir);
} }
destroyScreenInformationObject(screenInfoArray); destroyScreenInformationObject(screenInfoArray);
screenInfoArray = readCurrentDisplayConfiguration(); screenInfoArray = readCurrentDisplayConfiguration();
@ -497,13 +560,14 @@ TQPoint KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQString profilenam
return ret; return ret;
} }
TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) { TQPtrList<SingleScreenData> KRandrSimpleAPI::loadDisplayConfiguration(TQString profilename, TQString kde_confdir) {
int i; int i;
TQString filename; TQString filename;
filename = profilename; filename = profilename;
if (filename == "") if (filename == "") {
filename = "default"; filename = "default";
}
filename.prepend(kde_confdir.append("/displayconfig/")); filename.prepend(kde_confdir.append("/displayconfig/"));
KSimpleConfig* display_config = new KSimpleConfig( filename ); KSimpleConfig* display_config = new KSimpleConfig( filename );
@ -517,6 +581,7 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(
i = ((*it).remove("SCREEN ")).toInt(); i = ((*it).remove("SCREEN ")).toInt();
screendata = new SingleScreenData; screendata = new SingleScreenData;
screenInfoArray.append(screendata); screenInfoArray.append(screendata);
screendata->screenUniqueName = display_config->readEntry("ScreenUniqueName");
screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName"); screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName");
screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected"); screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected");
screendata->screen_connected = display_config->readBoolEntry("ScreenConnected"); screendata->screen_connected = display_config->readBoolEntry("ScreenConnected");
@ -557,16 +622,16 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(
int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) { int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
int rotationFlags = 0; int rotationFlags = 0;
TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index); TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
if (rotationDesired == "Normal") { if (rotationDesired == ROTATION_0_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate0; rotationFlags = rotationFlags | RandRScreen::Rotate0;
} }
else if (rotationDesired == "Rotate 90 degrees") { else if (rotationDesired == ROTATION_90_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate90; rotationFlags = rotationFlags | RandRScreen::Rotate90;
} }
else if (rotationDesired == "Rotate 180 degrees") { else if (rotationDesired == ROTATION_180_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate180; rotationFlags = rotationFlags | RandRScreen::Rotate180;
} }
else if (rotationDesired == "Rotate 270 degrees") { else if (rotationDesired == ROTATION_270_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate270; rotationFlags = rotationFlags | RandRScreen::Rotate270;
} }
if (screendata->has_x_flip) { if (screendata->has_x_flip) {
@ -580,7 +645,7 @@ int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
#define USE_XRANDR_PROGRAM #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 i;
int j; int j;
bool accepted = true; bool accepted = true;
@ -639,28 +704,13 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
xrandr_command_output = xrandr_command_output.stripWhiteSpace(); xrandr_command_output = xrandr_command_output.stripWhiteSpace();
if (test) { if (test) {
if (xrandr_command_output != "") { if (xrandr_command_output != "") {
applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir); applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
accepted = false; accepted = false;
destroyScreenInformationObject(oldconfig); destroyScreenInformationObject(oldconfig);
KMessageBox::sorry(0, xrandr_command_output, i18n("XRandR encountered a problem")); KMessageBox::sorry(0, xrandr_command_output, i18n("XRandR encountered a problem"));
return accepted; 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 #else
randr_display = tqt_xdisplay(); randr_display = tqt_xdisplay();
randr_screen_info = read_screen_info(randr_display); randr_screen_info = read_screen_info(randr_display);
@ -749,8 +799,8 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
#endif #endif
} }
applySystemwideDisplayGamma(screenInfoArray); applyDisplayGamma(screenInfoArray);
applySystemwideDisplayDPMS(screenInfoArray); applyDisplayDPMS(screenInfoArray);
TQString current_icc_profile = getCurrentProfile(); TQString current_icc_profile = getCurrentProfile();
applySystemWideIccConfiguration(kde_confdir); applySystemWideIccConfiguration(kde_confdir);
applyIccConfiguration(current_icc_profile, kde_confdir); applyIccConfiguration(current_icc_profile, kde_confdir);
@ -758,7 +808,7 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
if (test == TRUE) { if (test == TRUE) {
int ret = showTestConfigurationDialog(); int ret = showTestConfigurationDialog();
if (!ret) { if (!ret) {
applySystemwideDisplayConfiguration(oldconfig, FALSE, kde_confdir); applyDisplayConfiguration(oldconfig, FALSE, kde_confdir);
accepted = false; accepted = false;
} }
destroyScreenInformationObject(oldconfig); destroyScreenInformationObject(oldconfig);
@ -767,6 +817,18 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
return accepted; 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) { void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
SingleScreenData *screendata; SingleScreenData *screendata;
for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) { for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) {
@ -792,8 +854,9 @@ void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> s
bool has_primary_monitor = false; bool has_primary_monitor = false;
for (i=0;i<numberOfScreens;i++) { for (i=0;i<numberOfScreens;i++) {
screendata = screenInfoArray.at(i); screendata = screenInfoArray.at(i);
if (screendata->is_primary) if (screendata->is_primary) {
has_primary_monitor = true; has_primary_monitor = true;
}
} }
if (!has_primary_monitor) { if (!has_primary_monitor) {
for (i=0;i<numberOfScreens;i++) { for (i=0;i<numberOfScreens;i++) {
@ -893,7 +956,148 @@ TQPoint KRandrSimpleAPI::primaryScreenOffsetFromTLC(TQPtrList<SingleScreenData>
return TQPoint(primary_offset_x, primary_offset_y); 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; int i;
Display *randr_display; Display *randr_display;
XRROutputInfo *output_info; 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; int i;
Display *randr_display; Display *randr_display;
XRROutputInfo *output_info; XRROutputInfo *output_info;
@ -1019,6 +1223,7 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
// Create new data object // Create new data object
screendata = new SingleScreenData; screendata = new SingleScreenData;
screenInfoArray.append(screendata); 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->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; screendata->generic_screen_detected = false;
@ -1105,42 +1310,53 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
// RandRScreen::ReflectX // RandRScreen::ReflectX
// RandRScreen::ReflectY // RandRScreen::ReflectY
screendata->rotations.append(i18n("Normal")); screendata->rotations.append(i18n(ROTATION_0_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 90 degrees")); screendata->rotations.append(i18n(ROTATION_90_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 180 degrees")); screendata->rotations.append(i18n(ROTATION_180_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 270 degrees")); screendata->rotations.append(i18n(ROTATION_270_DEGREES_STRING));
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->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0); 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 // Determine if this display is primary and/or extended
RROutput primaryoutput = XRRGetOutputPrimary(tqt_xdisplay(), DefaultRootWindow(tqt_xdisplay())); 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; screendata->is_primary = false;
else }
else {
screendata->is_primary = true; screendata->is_primary = true;
}
screendata->is_extended = screen_active; screendata->is_extended = screen_active;
if (!screendata->is_extended) if (!screendata->is_extended) {
screendata->is_primary = false; screendata->is_primary = false;
}
// Get this screen's absolute position // Get this screen's absolute position
screendata->absolute_x_position = 0; screendata->absolute_x_position = 0;
@ -1257,10 +1473,21 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
numberOfScreens++; numberOfScreens++;
} }
// [FIXME] bool primary_set = false;
// Set this on the real primary monitor only! for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
screendata = screenInfoArray.at(0); if (screendata->is_primary) {
screendata->is_primary = true; 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; return screenInfoArray;
} }
@ -1276,19 +1503,23 @@ TQString KRandrSimpleAPI::clearIccConfiguration() {
icc_command = TQString("xcalib -c"); icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error [xcalib clear]\n\r");
} }
else { else {
fgets(xcalib_result, 2048, pipe_xcalib); if (fgets(xcalib_result, 2048, pipe_xcalib)) {
pclose(pipe_xcalib); pclose(pipe_xcalib);
for (i=1;i<2048;i++) { for (i=1;i<2048;i++) {
if (xcalib_result[i] == 0) { if (xcalib_result[i] == 0) {
xcalib_result[i-1]=0; xcalib_result[i-1]=0;
i=2048; i=2048;
}
}
if (strlen(xcalib_result) > 2) {
return xcalib_result;
} }
} }
if (strlen(xcalib_result) > 2) { else {
return xcalib_result; return "";
} }
} }
return ""; return "";
@ -1364,6 +1595,11 @@ int KRandrSimpleAPI::main_low_apply (ScreenInfo *screen_info)
return internal_main_low_apply (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) bool KRandrSimpleAPI::kRandrHasRandr(void)
{ {
return isValid(); return isValid();

@ -35,6 +35,11 @@
#include <ksimpleconfig.h> #include <ksimpleconfig.h>
#include <tdelibs_export.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. * Simple API covering most of the uses of libkrandr.
* *
@ -158,6 +163,11 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
*/ */
int main_low_apply (ScreenInfo *screen_info); 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 * Gets the binary monitor EDID for the specified card and display
*/ */
@ -168,43 +178,102 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
*/ */
TQString getEDIDMonitorName(int card, TQString displayname); 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 * Saves the systemwide display configuration screenInfoArray to the specified profile
* If profilename is empty, the default profile is utilized * If profilename is empty, the default profile is utilized
* If enable is set to true, the default profile will be applied at system startup * 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 * Reads the systemwide display configuration screenInfoArray from the specified profile
* If profilename is empty, the default profile is utilized * If profilename is empty, the default profile is utilized
* WARNING: The calling application must free the returned objects when it is done using them * 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 * Applies the systemwide display configuration screenInfoArray from the specified profile
* If profilename is empty, the default profile is utilized * If profilename is empty, the default profile is utilized
* Returns the offset of the primary screen's top left corner * 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 * 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 * 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 * 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 * 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 * 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 * Destroys a screen information object

@ -673,3 +673,8 @@ void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *out
screen_info->cur_crtc = NULL; screen_info->cur_crtc = NULL;
output->off_set = 1; 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);
}

@ -85,6 +85,7 @@ struct ScreenInfo* internal_read_screen_info (Display *);
int internal_set_screen_size (struct ScreenInfo *screen_info); int internal_set_screen_size (struct ScreenInfo *screen_info);
void internal_output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_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_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); 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); XRRModeInfo *internal_find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id);

@ -40,14 +40,63 @@
#undef INT32 #undef INT32
#include <X11/extensions/Xrandr.h> #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 class RandRScreenPrivate
{ {
public: public:
RandRScreenPrivate() : config(0L) {}; RandRScreenPrivate() : config(0L) {};
~RandRScreenPrivate() ~RandRScreenPrivate()
{ {
if (config) if (config) {
XRRFreeScreenConfigInfo(config); XRRFreeScreenConfigInfo(config);
}
} }
XRRScreenConfiguration* config; XRRScreenConfiguration* config;
@ -69,8 +118,9 @@ KDE_EXPORT RandRScreen::~RandRScreen()
KDE_EXPORT void RandRScreen::loadSettings() KDE_EXPORT void RandRScreen::loadSettings()
{ {
if (d->config) if (d->config) {
XRRFreeScreenConfigInfo(d->config); XRRFreeScreenConfigInfo(d->config);
}
d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen)); 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()); ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info; XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info;
CrtcInfo *current_crtc = screeninfo->outputs[m_screen]->cur_crtc; 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++) { 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)) { if (!m_pixelSizes.contains(newSize)) {
m_pixelSizes.append(newSize); m_pixelSizes.append(newSize);
m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height)); m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height));

@ -29,42 +29,68 @@
class KTimerDialog; class KTimerDialog;
class RandRScreenPrivate; class RandRScreenPrivate;
struct SingleScreenData { class KRANDR_EXPORT HotPlugRule {
TQString screenFriendlyName; public:
bool generic_screen_detected; enum states {
bool screen_connected; AnyState = 0,
Connected = 1,
TQStringList resolutions; Disconnected = 2
TQStringList refresh_rates; };
TQStringList color_depths;
TQStringList rotations; public:
HotPlugRule();
int current_resolution_index; virtual ~HotPlugRule();
int current_refresh_rate_index;
int current_color_depth_index; public:
TQStringList outputs;
float gamma_red; TQValueList< int > states;
float gamma_green; TQString profileName;
float gamma_blue; };
int current_rotation_index; typedef TQValueList< HotPlugRule > HotPlugRulesList;
int current_orientation_mask;
bool has_x_flip; class KRANDR_EXPORT SingleScreenData {
bool has_y_flip; public:
bool supports_transformations; SingleScreenData();
virtual ~SingleScreenData();
bool is_primary;
bool is_extended; public:
int absolute_x_position; TQString screenUniqueName;
int absolute_y_position; TQString screenFriendlyName;
int current_x_pixel_count; bool generic_screen_detected;
int current_y_pixel_count; bool screen_connected;
bool has_dpms; TQStringList resolutions;
bool enable_dpms; TQStringList refresh_rates;
unsigned int dpms_standby_delay; TQStringList color_depths;
unsigned int dpms_suspend_delay; TQStringList rotations;
unsigned int dpms_off_delay;
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 class RandRScreen : public TQObject

@ -195,9 +195,10 @@ KCModule * KCModuleProxy::realModule() const
d->topLayout->addWidget( d->kcm ); d->topLayout->addWidget( d->kcm );
if ( !d->rootInfo && /* If it's already done */ if ( !d->rootInfo && /* If the message was not yet created */
moduleInfo().needsRootPrivileges() /* root, anyone? */ && d->kcm->useRootOnlyMsg() /* and the module requests the message */ &&
!KUser().isSuperUser() ) /* Not necessary if we're root */ moduleInfo().needsRootPrivileges() /* and the module wants root access */ &&
!KUser().isSuperUser() ) /* and we are not currently root */
{ {
d->rootInfo = new TQLabel( that, "rootInfo" ); d->rootInfo = new TQLabel( that, "rootInfo" );

@ -2002,7 +2002,18 @@ void TDEHardwareDevices::processHotPluggedHardware() {
emit hardwareUpdated(hwdevice); emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID()); 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->internalSetVendorModel(monitor_info.second);
mdevice->m_friendlyName = monitor_info.first + " " + 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())); mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
} }
else { else {

Loading…
Cancel
Save