summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-23 07:52:47 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-23 07:52:47 +0000
commit2eb906099dece64705e51f4e79bfef0ac1c54843 (patch)
tree3e2373375d1f8a6bc47a974dce29717633474692
parentec0ac5ba48e15d1df22f3cdd427b773c7e5b6988 (diff)
downloadtdelibs-2eb90609.tar.gz
tdelibs-2eb90609.zip
Increase libkrandr functionality
Part 1/2 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1248961 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r--krandr/libkrandr.cc566
-rw-r--r--krandr/libkrandr.h52
-rw-r--r--krandr/randr.cpp39
-rw-r--r--krandr/randr.h31
4 files changed, 688 insertions, 0 deletions
diff --git a/krandr/libkrandr.cc b/krandr/libkrandr.cc
index 326ff0b13..0abe3f6ee 100644
--- a/krandr/libkrandr.cc
+++ b/krandr/libkrandr.cc
@@ -22,8 +22,29 @@
***************************************************************************/
+#include <tqtimer.h>
+#include <tqstringlist.h>
+
+#include <klocale.h>
+#include <kapplication.h>
+
#include "libkrandr.h"
+// This routine is courtsey of an answer on "Stack Overflow"
+// It takes an LSB-first int and makes it an MSB-first int (or vice versa)
+unsigned int reverse_bits(register unsigned int x)
+{
+ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+ x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+ x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+ x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+ return((x >> 16) | (x << 16));
+}
+
+TQString capitalizeString(TQString in) {
+ return in.left(1).upper() + in.right(in.length()-1);
+}
+
TQString KRandrSimpleAPI::getIccFileName(TQString profileName, TQString screenName, TQString kde_confdir) {
KSimpleConfig *t_config;
KSimpleConfig *t_systemconfig;
@@ -244,6 +265,77 @@ TQString KRandrSimpleAPI::applyIccConfiguration(TQString profileName, TQString k
return "";
}
+TQString KRandrSimpleAPI::getEDIDMonitorName(int card, TQString displayname) {
+ TQString edid;
+ TQByteArray binaryedid = getEDID(card, displayname);
+ if (binaryedid.isNull())
+ return TQString();
+
+ // Get the manufacturer ID
+ unsigned char letter_1 = ((binaryedid[8]>>2) & 0x1F) + 0x40;
+ unsigned char letter_2 = (((binaryedid[8] & 0x03) << 3) | ((binaryedid[9]>>5) & 0x07)) + 0x40;
+ unsigned char letter_3 = (binaryedid[9] & 0x1F) + 0x40;
+ TQChar qletter_1 = TQChar(letter_1);
+ TQChar qletter_2 = TQChar(letter_2);
+ TQChar qletter_3 = TQChar(letter_3);
+ TQString manufacturer_id = TQString("%1%2%3").arg(qletter_1).arg(qletter_2).arg(qletter_3);
+
+ // Get the model ID
+ unsigned int raw_model_id = (((binaryedid[10] << 8) | binaryedid[11]) << 16) & 0xFFFF0000;
+ // Reverse the bit order
+ unsigned int model_id = reverse_bits(raw_model_id);
+
+ // Try to get the model name
+ bool has_friendly_name = false;
+ unsigned char descriptor_block[18];
+ int i;
+ for (i=72;i<90;i++) {
+ descriptor_block[i-72] = binaryedid[i] & 0xFF;
+ }
+ if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
+ for (i=90;i<108;i++) {
+ descriptor_block[i-90] = binaryedid[i] & 0xFF;
+ }
+ if ((descriptor_block[0] != 0) || (descriptor_block[1] != 0) || (descriptor_block[3] != 0xFC)) {
+ for (i=108;i<126;i++) {
+ descriptor_block[i-108] = binaryedid[i] & 0xFF;
+ }
+ }
+ }
+
+ TQString monitor_name;
+ if ((descriptor_block[0] == 0) && (descriptor_block[1] == 0) && (descriptor_block[3] == 0xFC)) {
+ char* pos = strchr((char *)(descriptor_block+5), '\n');
+ if (pos) {
+ *pos = 0;
+ has_friendly_name = true;
+ monitor_name = TQString((char *)(descriptor_block+5));
+ }
+ else {
+ has_friendly_name = false;
+ }
+ }
+
+ // [FIXME]
+ // Look up manudacturer names if possible!
+
+ if (has_friendly_name)
+ edid = TQString("%1 %2").arg(manufacturer_id).arg(monitor_name);
+ else
+ edid = TQString("%1 0x%2").arg(manufacturer_id).arg(model_id, 0, 16);
+
+ return edid;
+}
+
+TQByteArray KRandrSimpleAPI::getEDID(int card, TQString displayname) {
+ TQFile file(TQString("/sys/class/drm/card%1-%2/edid").arg(card).arg(displayname));
+ if (!file.open (IO_ReadOnly))
+ return TQByteArray();
+ TQByteArray binaryedid = file.readAll();
+ file.close();
+ return binaryedid;
+}
+
TQString KRandrSimpleAPI::getCurrentProfile () {
TQString profileName;
KSimpleConfig *t_config;
@@ -283,6 +375,480 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir)
return "";
}
+void KRandrSimpleAPI::saveSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir, TQPtrList<SingleScreenData> screenInfoArray) {
+ int i;
+
+ TQString filename;
+ filename = profilename;
+ if (filename == "")
+ filename = "default";
+ filename.prepend(kde_confdir.append("/displayconfig/"));
+
+ KSimpleConfig* display_config = new KSimpleConfig( filename );
+
+ i=0;
+ SingleScreenData *screendata;
+ for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
+ display_config->setGroup(TQString("SCREEN %1").arg(i));
+ display_config->writeEntry("ScreenFriendlyName", screendata->screenFriendlyName);
+ display_config->writeEntry("GenericScreenDetected", screendata->generic_screen_detected);
+ display_config->writeEntry("ScreenConnected", screendata->screen_connected);
+ display_config->writeEntry("Resolutions", screendata->resolutions);
+ display_config->writeEntry("RefreshRates", screendata->refresh_rates);
+ display_config->writeEntry("ColorDepths", screendata->color_depths);
+ display_config->writeEntry("AvailableRotations", screendata->rotations);
+ display_config->writeEntry("CurrentResolution", screendata->current_resolution_index);
+ display_config->writeEntry("CurrentRefreshRate", screendata->current_refresh_rate_index);
+ display_config->writeEntry("CurrentColorDepth", screendata->current_color_depth_index);
+ display_config->writeEntry("CurrentRotation", screendata->current_rotation_index);
+ display_config->writeEntry("CurrentOrientiation", screendata->current_orientation_mask);
+ display_config->writeEntry("CurrentXFlip", screendata->has_x_flip);
+ display_config->writeEntry("CurrentYFlip", screendata->has_y_flip);
+ display_config->writeEntry("SupportsTransformation", screendata->supports_transformations);
+ display_config->writeEntry("IsPrimary", screendata->is_primary);
+ display_config->writeEntry("IsExtended", screendata->is_extended);
+ display_config->writeEntry("AbsXPos", screendata->absolute_x_position);
+ display_config->writeEntry("AbsYPos", screendata->absolute_y_position);
+ display_config->writeEntry("CurrentXPixelCount", screendata->current_x_pixel_count);
+ display_config->writeEntry("CurrentYPixelCount", screendata->current_y_pixel_count);
+ i++;
+ }
+
+ display_config->sync();
+ delete display_config;
+}
+
+TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(TQString profilename, TQString kde_confdir) {
+ int i;
+
+ TQString filename;
+ filename = profilename;
+ if (filename == "")
+ filename = "default";
+ filename.prepend(kde_confdir.append("/displayconfig/"));
+
+ KSimpleConfig* display_config = new KSimpleConfig( filename );
+
+ TQStringList grouplist;
+ SingleScreenData *screendata;
+ TQPtrList<SingleScreenData> screenInfoArray;
+ for ( TQStringList::Iterator it = grouplist.begin(); it != grouplist.end(); ++it ) {
+ if ((*it).startsWith("SCREEN ")) {
+ display_config->setGroup(*it);
+ i = ((*it).remove("SCREEN ")).toInt();
+ screendata = new SingleScreenData;
+ screenInfoArray.append(screendata);
+ screendata->screenFriendlyName = display_config->readEntry("ScreenFriendlyName");
+ screendata->generic_screen_detected = display_config->readBoolEntry("GenericScreenDetected");
+ screendata->screen_connected = display_config->readBoolEntry("ScreenConnected");
+ screendata->resolutions = display_config->readListEntry("Resolutions");
+ screendata->refresh_rates = display_config->readListEntry("RefreshRates");
+ screendata->color_depths = display_config->readListEntry("ColorDepths");
+ screendata->rotations = display_config->readListEntry("AvailableRotations");
+ screendata->current_resolution_index = display_config->readNumEntry("CurrentResolution");
+ screendata->current_refresh_rate_index = display_config->readNumEntry("CurrentRefreshRate");
+ screendata->current_color_depth_index = display_config->readNumEntry("CurrentColorDepth");
+ screendata->current_rotation_index = display_config->readNumEntry("CurrentRotation");
+ screendata->current_orientation_mask = display_config->readNumEntry("CurrentOrientiation");
+ screendata->has_x_flip = display_config->readBoolEntry("CurrentXFlip");
+ screendata->has_y_flip = display_config->readBoolEntry("CurrentYFlip");
+ screendata->supports_transformations = display_config->readBoolEntry("SupportsTransformation");
+ screendata->is_primary = display_config->readBoolEntry("IsPrimary");
+ screendata->is_extended = display_config->readBoolEntry("IsExtended");
+ screendata->absolute_x_position = display_config->readNumEntry("AbsXPos");
+ screendata->absolute_y_position = display_config->readNumEntry("AbsYPos");
+ screendata->current_x_pixel_count = display_config->readNumEntry("CurrentXPixelCount");
+ screendata->current_y_pixel_count = display_config->readNumEntry("CurrentYPixelCount");
+ }
+ }
+
+ delete display_config;
+
+ return screenInfoArray;
+}
+
+int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
+ int rotationFlags = 0;
+ TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
+ if (rotationDesired == "Normal") {
+ rotationFlags = rotationFlags | RandRScreen::Rotate0;
+ }
+ else if (rotationDesired == "Rotate 90 degrees") {
+ rotationFlags = rotationFlags | RandRScreen::Rotate90;
+ }
+ else if (rotationDesired == "Rotate 180 degrees") {
+ rotationFlags = rotationFlags | RandRScreen::Rotate180;
+ }
+ else if (rotationDesired == "Rotate 270 degrees") {
+ rotationFlags = rotationFlags | RandRScreen::Rotate270;
+ }
+ if (screendata->has_x_flip) {
+ rotationFlags = rotationFlags | RandRScreen::ReflectX;
+ }
+ if (screendata->has_y_flip) {
+ rotationFlags = rotationFlags | RandRScreen::ReflectY;
+ }
+ return rotationFlags;
+}
+
+bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreenData> screenInfoArray, bool test) {
+ int i;
+ int j;
+ bool accepted = true;
+ Display *randr_display;
+ XRROutputInfo *output_info;
+ ScreenInfo *randr_screen_info;
+
+ SingleScreenData *screendata;
+
+ TQPtrList<SingleScreenData> oldconfig;
+ if (test == TRUE) {
+ oldconfig = readCurrentDisplayConfiguration();
+ }
+
+ if (isValid() == true) {
+ randr_display = XOpenDisplay(NULL);
+ randr_screen_info = read_screen_info(randr_display);
+ // Turn off all displays
+ for (i = 0; i < randr_screen_info->n_output; i++) {
+ screendata = screenInfoArray.at(i);
+ output_info = randr_screen_info->outputs[i]->info;
+
+ randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
+ randr_screen_info->cur_output = randr_screen_info->outputs[i];
+ randr_screen_info->cur_output->auto_set = 0;
+ randr_screen_info->cur_output->off_set = 1;
+ output_off (randr_screen_info, randr_screen_info->cur_output);
+ j=main_low_apply(randr_screen_info);
+ }
+ randr_screen_info = read_screen_info(randr_display);
+ // Turn on the primary display
+ for (i = 0; i < randr_screen_info->n_output; i++) {
+ screendata = screenInfoArray.at(i);
+ output_info = randr_screen_info->outputs[i]->info;
+
+ if (screendata->is_primary == true) {
+ randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
+ randr_screen_info->cur_output = randr_screen_info->outputs[i];
+ randr_screen_info->cur_output->auto_set = 1;
+ randr_screen_info->cur_output->off_set = 0;
+ output_auto (randr_screen_info, randr_screen_info->cur_output);
+ j=main_low_apply(randr_screen_info);
+ }
+ }
+ // Handle the remaining displays
+ randr_screen_info = read_screen_info(randr_display);
+ for (i = 0; i < randr_screen_info->n_output; i++) {
+ screendata = screenInfoArray.at(i);
+ output_info = randr_screen_info->outputs[i]->info;
+
+ // Activate or deactivate the screens as necessary
+ randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
+ randr_screen_info->cur_output = randr_screen_info->outputs[i];
+ if (screendata->is_primary == false) {
+ if (screendata->is_primary || screendata->is_extended) {
+ randr_screen_info->cur_output->auto_set = 1;
+ randr_screen_info->cur_output->off_set = 0;
+ output_auto (randr_screen_info, randr_screen_info->cur_output);
+ j=main_low_apply(randr_screen_info);
+ }
+ else {
+ randr_screen_info->cur_output->auto_set = 0;
+ randr_screen_info->cur_output->off_set = 1;
+ output_off (randr_screen_info, randr_screen_info->cur_output);
+ j=main_low_apply(randr_screen_info);
+ }
+ }
+ }
+ randr_screen_info = read_screen_info(randr_display);
+ for (i = 0; i < randr_screen_info->n_output; i++) {
+ screendata = screenInfoArray.at(i);
+ output_info = randr_screen_info->outputs[i]->info;
+
+ if (screendata->is_primary || screendata->is_extended) {
+ // Set rotation, refresh rate, and size
+ screen(i)->proposeSize(screendata->current_resolution_index);
+ screen(i)->proposeRefreshRate(screendata->current_refresh_rate_index);
+ screen(i)->proposeRotation(getHardwareRotationFlags(screendata));
+ screen(i)->applyProposed();
+
+ // Force data reload
+ randr_screen_info = read_screen_info(randr_display);
+ output_info = randr_screen_info->outputs[i]->info;
+
+ // Finally, set the screen's position
+ randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc;
+ randr_screen_info->cur_crtc->cur_x = screendata->absolute_x_position;
+ randr_screen_info->cur_crtc->cur_y = screendata->absolute_y_position;
+ j=main_low_apply(randr_screen_info);
+ }
+ }
+ }
+
+ if (test == TRUE) {
+ int ret = showTestConfigurationDialog();
+ if (!ret) {
+ applySystemwideDisplayConfiguration(oldconfig, FALSE);
+ accepted = false;
+ }
+ destroyScreenInformationObject(oldconfig);
+ }
+
+ return accepted;
+}
+
+void KRandrSimpleAPI::destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray) {
+ SingleScreenData *screendata;
+ for ( screendata = screenInfoArray.first(); screendata; screendata = screenInfoArray.next() ) {
+ screenInfoArray.remove(screendata);
+ delete screendata;
+ }
+}
+
+void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> screenInfoArray) {
+ int i;
+ SingleScreenData *screendata;
+
+ int numberOfScreens = screenInfoArray.count();
+
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ if (!screendata->screen_connected) {
+ screendata->is_primary = false;
+ screendata->is_extended = false;
+ }
+ }
+
+ bool has_primary_monitor = false;
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ if (screendata->is_primary)
+ has_primary_monitor = true;
+ }
+ if (!has_primary_monitor) {
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ if (!has_primary_monitor) {
+ if (screendata->is_extended) {
+ screendata->is_primary = true;
+ screendata->is_extended = true;
+ has_primary_monitor = true;
+ }
+ }
+ }
+ }
+ if (!has_primary_monitor) {
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ if (!has_primary_monitor) {
+ if (screendata->screen_connected) {
+ screendata->is_primary = true;
+ screendata->is_extended = true;
+ has_primary_monitor = true;
+ }
+ }
+ }
+ }
+
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ if (screendata->is_primary) {
+ screendata->absolute_x_position = 0;
+ screendata->absolute_y_position = 0;
+ screendata->is_extended = true;
+ }
+ }
+
+ for (i=0;i<numberOfScreens;i++) {
+ screendata = screenInfoArray.at(i);
+ TQString resolutionstring = screendata->resolutions[screendata->current_resolution_index];
+ int separator_pos = resolutionstring.find(" x ");
+ TQString x_res_string = resolutionstring.left(separator_pos);
+ TQString y_res_string = resolutionstring.right(resolutionstring.length()-separator_pos-3);
+ screendata->current_x_pixel_count = x_res_string.toInt();
+ screendata->current_y_pixel_count = y_res_string.toInt();
+ screendata->current_orientation_mask = getHardwareRotationFlags(screendata);
+ }
+}
+
+TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
+ // Discover display information
+ int i;
+ int j;
+
+ XRROutputInfo *output_info;
+ SingleScreenData *screendata;
+ TQPtrList<SingleScreenData> screenInfoArray;
+
+ Display *randr_display;
+ ScreenInfo *randr_screen_info;
+
+ // Clear existing info
+ destroyScreenInformationObject(screenInfoArray);
+
+ int numberOfScreens = 0;
+ if (isValid() == true) {
+ randr_display = XOpenDisplay(NULL);
+ randr_screen_info = read_screen_info(randr_display);
+ for (i = 0; i < randr_screen_info->n_output; i++) {
+ output_info = randr_screen_info->outputs[i]->info;
+
+ // Create new data object
+ screendata = new SingleScreenData;
+ screenInfoArray.append(screendata);
+ 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;
+
+ // Attempt to use KMS to find screen EDID and name
+ TQString edid = getEDIDMonitorName(0, output_info->name); // [FIXME] Don't hardwire to card 0!
+ if (!edid.isNull()) {
+ screendata->screenFriendlyName = TQString(i18n("%1. %2 on %3 on card %4")).arg(i+1).arg(edid).arg(capitalizeString(output_info->name)).arg("0"); // [FIXME] How can I get the name of the Xorg graphics driver currently in use?
+ }
+
+ // Get resolutions
+ RandRScreen *cur_screen = screen(i);
+ if (cur_screen) {
+ screendata->screen_connected = true;
+ for (int j = 0; j < cur_screen->numSizes(); j++) {
+ screendata->resolutions.append(i18n("%1 x %2").tqarg(cur_screen->pixelSize(j).width()).tqarg(cur_screen->pixelSize(j).height()));
+ }
+ screendata->current_resolution_index = cur_screen->proposedSize();
+
+ // Get refresh rates
+ TQStringList rr = cur_screen->refreshRates(screendata->current_resolution_index);
+ for (TQStringList::Iterator it = rr.begin(); it != rr.end(); ++it) {
+ screendata->refresh_rates.append(*it);
+ }
+ screendata->current_refresh_rate_index = cur_screen->proposedRefreshRate();
+
+ // Get color depths
+ // [FIXME]
+ screendata->color_depths.append(i18n("Default"));
+ screendata->current_color_depth_index = 0;
+
+ // Get orientation flags
+ // RandRScreen::Rotate0
+ // RandRScreen::Rotate90
+ // RandRScreen::Rotate180
+ // RandRScreen::Rotate270
+ // 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->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0);
+
+ // Determine if this display is primary and/or extended
+ // [FIXME]
+ screendata->is_primary = false;
+ screendata->is_extended = false;
+
+ // Get this screen's absolute position
+ // [FIXME]
+ screendata->absolute_x_position = 0;
+ screendata->absolute_y_position = 0;
+
+ // Get this screen's current resolution
+ screendata->current_x_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).width();
+ screendata->current_y_pixel_count = cur_screen->pixelSize(screendata->current_resolution_index).height();
+ }
+ else {
+ // Fill in generic data for this disconnected output
+ screendata->screenFriendlyName = screendata->screenFriendlyName + TQString(" (") + i18n("disconnected") + TQString(")");
+ screendata->screen_connected = false;
+
+ screendata->resolutions = i18n("Default");
+ screendata->refresh_rates = i18n("Default");
+ screendata->color_depths = i18n("Default");
+ screendata->rotations = i18n("N/A");
+
+ screendata->current_resolution_index = 0;
+ screendata->current_refresh_rate_index = 0;
+ screendata->current_color_depth_index = 0;
+
+ screendata->current_rotation_index = 0;
+ screendata->current_orientation_mask = 0;
+ screendata->has_x_flip = false;
+ screendata->has_y_flip = false;
+ screendata->supports_transformations = false;
+
+ screendata->is_primary = false;
+ screendata->is_extended = false;
+ screendata->absolute_x_position = 0;
+ screendata->absolute_y_position = 0;
+ screendata->current_x_pixel_count = 640;
+ screendata->current_y_pixel_count = 480;
+ }
+
+ // Check for more screens...
+ numberOfScreens++;
+ }
+ }
+ else {
+ screendata = new SingleScreenData;
+ screenInfoArray.append(screendata);
+
+ // Fill in a bunch of generic data
+ screendata->screenFriendlyName = i18n("Default output on generic video card");
+ screendata->generic_screen_detected = true;
+ screendata->screen_connected = true;
+
+ screendata->resolutions = i18n("Default");
+ screendata->refresh_rates = i18n("Default");
+ screendata->color_depths = i18n("Default");
+ screendata->rotations = i18n("N/A");
+
+ screendata->current_resolution_index = 0;
+ screendata->current_refresh_rate_index = 0;
+ screendata->current_color_depth_index = 0;
+
+ screendata->current_rotation_index = 0;
+ screendata->current_orientation_mask = 0;
+ screendata->has_x_flip = false;
+ screendata->has_y_flip = false;
+ screendata->supports_transformations = false;
+
+ screendata->is_primary = true;
+ screendata->is_extended = true;
+ screendata->absolute_x_position = 0;
+ screendata->absolute_y_position = 0;
+ screendata->current_x_pixel_count = 640;
+ screendata->current_y_pixel_count = 480;
+
+ numberOfScreens++;
+ }
+
+ // [FIXME]
+ // Set this on the real primary monitor only!
+ screendata = screenInfoArray.at(0);
+ screendata->is_primary = true;
+
+ return screenInfoArray;
+}
+
TQString KRandrSimpleAPI::clearIccConfiguration() {
// Clear ICC settings with XCalib
TQString icc_command;
diff --git a/krandr/libkrandr.h b/krandr/libkrandr.h
index 55566a020..d4e9fbea8 100644
--- a/krandr/libkrandr.h
+++ b/krandr/libkrandr.h
@@ -29,6 +29,8 @@
#ifdef __cplusplus
+#include <tqfile.h>
+
#include <kconfig.h>
#include <ksimpleconfig.h>
#include <kdelibs_export.h>
@@ -151,6 +153,56 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
int main_low_apply (ScreenInfo *screen_info);
/**
+ * Gets the binary monitor EDID for the specified card and display
+ */
+ TQByteArray getEDID(int card, TQString displayname);
+
+ /**
+ * Gets the monitor EDID name for the specified card and display
+ */
+ TQString getEDIDMonitorName(int card, TQString displayname);
+
+ /**
+ * Saves the systemwide display configuration screenInfoArray to the specified profile
+ * If profilename is empty, the default profile is utilized
+ */
+ void saveSystemwideDisplayConfiguration(TQString profilename, 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);
+
+ /**
+ * 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);
+
+ /**
+ * Destroys a screen information object
+ */
+ void destroyScreenInformationObject(TQPtrList<SingleScreenData> screenInfoArray);
+
+ /**
+ * Ensures that the data contained within screenInfoArray is self consistent
+ */
+ void ensureMonitorDataConsistency(TQPtrList<SingleScreenData> screenInfoArray);
+
+ /**
+ * Reads the current display configuration screenInfoArray from the hardware
+ */
+ TQPtrList<SingleScreenData> readCurrentDisplayConfiguration();
+
+ /**
+ * Returns the hardware rotation flags given a valid SingleScreenData structure
+ */
+ int getHardwareRotationFlags(SingleScreenData*);
+
+ /**
* Returns whether or not the system supports XRandR
*/
bool kRandrHasRandr();
diff --git a/krandr/randr.cpp b/krandr/randr.cpp
index 5987d8808..378a1fdb7 100644
--- a/krandr/randr.cpp
+++ b/krandr/randr.cpp
@@ -708,6 +708,45 @@ void RandRDisplay::applyProposed(bool confirm)
}
}
+bool RandRDisplay::showTestConfigurationDialog()
+{
+ return screen(0)->showTestConfigurationDialog();
+}
+
+bool RandRScreen::showTestConfigurationDialog()
+{
+ // uncomment the line below and edit out the KTimerDialog stuff to get
+ // a version which works on today's kdelibs (no accept dialog is presented)
+
+ // FIXME remember to put the dialog on the right screen
+
+ KTimerDialog acceptDialog ( 15000, KTimerDialog::CountDown,
+ KApplication::kApplication()->mainWidget(),
+ "mainKTimerDialog",
+ true,
+ i18n("Confirm Display Settings"),
+ KTimerDialog::Ok|KTimerDialog::Cancel,
+ KTimerDialog::Cancel);
+
+ acceptDialog.setButtonOK(KGuiItem(i18n("&Accept Configuration"), "button_ok"));
+ acceptDialog.setButtonCancel(KGuiItem(i18n("&Return to Previous Configuration"), "button_cancel"));
+
+ KActiveLabel *label = new KActiveLabel(i18n("Your display devices has been configured "
+ "to match the settings shown above. Please indicate whether you wish to "
+ "keep this configuration. In 15 seconds the display will revert to your previous "
+ "settings."), &acceptDialog, "userSpecifiedLabel");
+
+ acceptDialog.setMainWidget(label);
+
+ KDialog::centerOnScreen(&acceptDialog, 0);
+
+ m_shownDialog = &acceptDialog;
+ connect( m_shownDialog, TQT_SIGNAL( destroyed()), this, TQT_SLOT( shownDialogDestroyed()));
+ connect( kapp->desktop(), TQT_SIGNAL( resized(int)), this, TQT_SLOT( desktopResized()));
+
+ return acceptDialog.exec();
+}
+
int RandRScreen::pixelCount( int index ) const
{
TQSize sz = pixelSize(index);
diff --git a/krandr/randr.h b/krandr/randr.h
index 591a42f45..8f3d14a33 100644
--- a/krandr/randr.h
+++ b/krandr/randr.h
@@ -29,6 +29,34 @@
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;
+
+ 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;
+};
+
class RandRScreen : public TQObject
{
Q_OBJECT
@@ -63,6 +91,7 @@ public:
public slots:
bool confirm();
+ bool showTestConfigurationDialog();
public:
TQString changedMessage() const;
@@ -218,6 +247,8 @@ public:
void applyProposed(bool confirm = true);
+ bool showTestConfigurationDialog();
+
private:
int m_numScreens;
int m_currentScreenIndex;