From 67b84c91681a16d4e19e83c17d9679191d005039 Mon Sep 17 00:00:00 2001 From: tpearson Date: Tue, 23 Aug 2011 07:54:16 +0000 Subject: Increase libkrandr functionality Part 2/2 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1248962 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kcontrol/displayconfig/displayconfig.cpp | 385 +++++-------------------------- 1 file changed, 55 insertions(+), 330 deletions(-) (limited to 'kcontrol/displayconfig/displayconfig.cpp') diff --git a/kcontrol/displayconfig/displayconfig.cpp b/kcontrol/displayconfig/displayconfig.cpp index 85b5afde0..deafecb52 100644 --- a/kcontrol/displayconfig/displayconfig.cpp +++ b/kcontrol/displayconfig/displayconfig.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -62,22 +63,6 @@ K_EXPORT_COMPONENT_FACTORY( kcm_displayconfig, KDisplayCFactory("kcmdisplayconfi KSimpleConfig *systemconfig; - -// 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); -} - TQPoint moveTQRectOutsideTQRect(TQRect base, TQRect movable, int fallback_level = 0) { TQPoint final_result; @@ -455,6 +440,9 @@ void KDisplayConfig::updateDraggableMonitorInformationInternal (int monitor_id, } } + TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index); + bool isvisiblyrotated = ((rotationDesired == "Rotate 90 degrees") || (rotationDesired == "Rotate 270 degrees")); + if (screendata->is_extended) { moved_monitor->show(); } @@ -463,7 +451,10 @@ void KDisplayConfig::updateDraggableMonitorInformationInternal (int monitor_id, } // Handle resizing - moved_monitor->setFixedSize(screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor); + if (isvisiblyrotated) + moved_monitor->setFixedSize(screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor); + else + moved_monitor->setFixedSize(screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor); // Find the primary monitor for (i=0;isystemEnableSupport, TQT_SIGNAL(clicked()), TQT_SLOT(changed())); connect(base->systemEnableSupport, TQT_SIGNAL(clicked()), TQT_SLOT(processLockoutControls())); connect(base->monitorDisplaySelectDD, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + connect(base->rotationSelectDD, TQT_SIGNAL(activated(int)), TQT_SLOT(rotationInfoChanged())); + connect(base->orientationHFlip, TQT_SIGNAL(clicked()), TQT_SLOT(rotationInfoChanged())); + connect(base->orientationVFlip, TQT_SIGNAL(clicked()), TQT_SLOT(rotationInfoChanged())); connect(base->resolutionSlider, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resolutionSliderChanged(int))); connect(base->monitorDisplaySelectDD, TQT_SIGNAL(activated(int)), TQT_SLOT(selectScreen(int))); connect(base->monitorPhyArrange, TQT_SIGNAL(workspaceRelayoutNeeded()), this, TQT_SLOT(layoutDragDropDisplay())); @@ -691,6 +685,8 @@ KDisplayConfig::KDisplayConfig(TQWidget *parent, const char *name, const TQStrin connect(base->systemEnableSupport, TQT_SIGNAL(toggled(bool)), base->monitorDisplaySelectDD, TQT_SLOT(setEnabled(bool))); + connect(base->previewConfiguration, TQT_SIGNAL(clicked()), TQT_SLOT(activatePreview())); + load(); addTab( "iccconfig", i18n( "Color Profiles" ) ); // [FIXME[ No way to save settings here yet @@ -728,6 +724,10 @@ void KDisplayConfig::addProfile () { } +void KDisplayConfig::activatePreview() { + m_randrsimple->applySystemwideDisplayConfiguration(m_screenInfoArray, TRUE); +} + void KDisplayConfig::load() { load( false ); @@ -743,249 +743,8 @@ void KDisplayConfig::selectScreen (int slotNumber) { } void KDisplayConfig::updateArray (void) { - // Discover display information - int i; - int j; - - XRROutputInfo *output_info; - - // Clear existing info - SingleScreenData *screendata; - for ( screendata = m_screenInfoArray.first(); screendata; screendata = m_screenInfoArray.next() ) { - m_screenInfoArray.remove(screendata); - delete screendata; - } - - numberOfScreens = 0; - if (m_randrsimple->isValid() == true) { - randr_display = XOpenDisplay(NULL); - randr_screen_info = m_randrsimple->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; - m_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 = m_randrsimple->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; - m_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 = m_screenInfoArray.at(0); - screendata->is_primary = true; -} - -TQString KDisplayConfig::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 KDisplayConfig::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; + m_screenInfoArray = m_randrsimple->readCurrentDisplayConfiguration(); + numberOfScreens = m_screenInfoArray.count(); } void KDisplayConfig::updateDisplayedInformation () { @@ -1130,12 +889,17 @@ void KDisplayConfig::updateDragDropDisplay() { base->monitorPhyArrange->resize_factor = 0.0625; // This always needs to divide by a multiple of 2 for (i=0;irotations.at(screendata->current_rotation_index); + bool isvisiblyrotated = ((rotationDesired == "Rotate 90 degrees") || (rotationDesired == "Rotate 270 degrees")); DraggableMonitor *m = new DraggableMonitor( base->monitorPhyArrange, 0, WStyle_Customize | WDestructiveClose | WStyle_NoBorder | WX11BypassWM ); connect(m, TQT_SIGNAL(workspaceRelayoutNeeded()), this, TQT_SLOT(layoutDragDropDisplay())); connect(m, TQT_SIGNAL(monitorSelected(int)), this, TQT_SLOT(selectScreen(int))); connect(m, TQT_SIGNAL(monitorDragComplete(int)), this, TQT_SLOT(updateDraggableMonitorInformation(int))); m->screen_id = i; - m->setFixedSize(screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor); + if (isvisiblyrotated) + m->setFixedSize(screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor); + else + m->setFixedSize(screendata->current_x_pixel_count*base->monitorPhyArrange->resize_factor, screendata->current_y_pixel_count*base->monitorPhyArrange->resize_factor); m->setText(TQString("%1").arg(i+1)); m->show(); updateDraggableMonitorInformation(i); // Make sure the new monitors don't overlap @@ -1169,66 +933,7 @@ void KDisplayConfig::layoutDragDropDisplay() { } void KDisplayConfig::ensureMonitorDataConsistency() { - int i; - SingleScreenData *screendata; - - for (i=0;iscreen_connected) { - screendata->is_primary = false; - screendata->is_extended = false; - } - } - - bool has_primary_monitor = false; - for (i=0;iis_primary) - has_primary_monitor = true; - } - if (!has_primary_monitor) { - for (i=0;iis_extended) { - screendata->is_primary = true; - screendata->is_extended = true; - has_primary_monitor = true; - } - } - } - } - if (!has_primary_monitor) { - for (i=0;iscreen_connected) { - screendata->is_primary = true; - screendata->is_extended = true; - has_primary_monitor = true; - } - } - } - } - - for (i=0;iis_primary) { - screendata->absolute_x_position = 0; - screendata->absolute_y_position = 0; - screendata->is_extended = true; - } - } - - for (i=0;iresolutions[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(); - } + m_randrsimple->ensureMonitorDataConsistency(m_screenInfoArray); } void KDisplayConfig::resolutionSliderTextUpdate(int index) { @@ -1245,6 +950,21 @@ void KDisplayConfig::resolutionSliderChanged(int index) { screendata->current_resolution_index = realResolutionSliderValue(); updateDisplayedInformation(); updateDraggableMonitorInformation(base->monitorDisplaySelectDD->currentItem()); + + changed(); +} + +void KDisplayConfig::rotationInfoChanged() { + SingleScreenData *screendata; + screendata = m_screenInfoArray.at(base->monitorDisplaySelectDD->currentItem()); + + screendata->current_rotation_index = base->rotationSelectDD->currentItem(); + screendata->has_x_flip = base->orientationHFlip->isChecked(); + screendata->has_y_flip = base->orientationVFlip->isChecked(); + updateDisplayedInformation(); + updateDraggableMonitorInformation(base->monitorDisplaySelectDD->currentItem()); + + changed(); } TQString KDisplayConfig::extractFileName(TQString displayName, TQString profileName) { @@ -1331,18 +1051,23 @@ void KDisplayConfig::load(bool useDefaults ) void KDisplayConfig::save() { - int i; - int j; - KRandrSimpleAPI *m_randrsimple = new KRandrSimpleAPI(); - - // Write system configuration - systemconfig->setGroup(NULL); - systemconfig->writeEntry("EnableDisplayControl", base->systemEnableSupport->isChecked()); + if (m_randrsimple->applySystemwideDisplayConfiguration(m_screenInfoArray, TRUE)) { + m_randrsimple->saveSystemwideDisplayConfiguration("", KDE_CONFDIR, m_screenInfoArray); + // Write system configuration + systemconfig->setGroup(NULL); + systemconfig->writeEntry("EnableDisplayControl", base->systemEnableSupport->isChecked()); - systemconfig->sync(); + systemconfig->sync(); - emit changed(false); + emit changed(false); + } + else { + // Signal that settings were NOT applied + TQTimer *t = new TQTimer( this ); + connect(t, SIGNAL(timeout()), SLOT(changed()) ); + t->start( 100, FALSE ); + } } void KDisplayConfig::defaults() -- cgit v1.2.1