/* * Copyright (c) 2007 Gustavo Pichorim Boiko * Copyright (c) 2002,2003 Hamish Rodda * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "ktimerdialog.h" #include #include #include #include #include #include #include #include #include "legacyrandrscreen.h" LegacyRandRScreen::LegacyRandRScreen(int screenIndex) : m_config(0L) , m_screen(screenIndex) , m_shownDialog(NULL) { loadSettings(); setOriginal(); } LegacyRandRScreen::~LegacyRandRScreen() { if (m_config) XRRFreeScreenConfigInfo(m_config); } void LegacyRandRScreen::loadSettings() { if (m_config) XRRFreeScreenConfigInfo(m_config); m_config = XRRGetScreenInfo(QX11Info::display(), rootWindow()); Q_ASSERT(m_config); Rotation rotation; m_currentSize = m_proposedSize = XRRConfigCurrentConfiguration(m_config, &rotation); m_currentRotation = m_proposedRotation = rotation; m_pixelSizes.clear(); m_mmSizes.clear(); int numSizes; XRRScreenSize* sizes = XRRSizes(QX11Info::display(), m_screen, &numSizes); for (int i = 0; i < numSizes; i++) { m_pixelSizes.append(QSize(sizes[i].width, sizes[i].height)); m_mmSizes.append(QSize(sizes[i].mwidth, sizes[i].mheight)); } m_rotations = XRRRotations(QX11Info::display(), m_screen, &rotation); m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex(m_currentSize, XRRConfigCurrentRate(m_config)); } void LegacyRandRScreen::setOriginal() { m_originalSize = m_currentSize; m_originalRotation = m_currentRotation; m_originalRefreshRate = m_currentRefreshRate; } bool LegacyRandRScreen::applyProposed() { //kDebug() << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()); Status status; if (proposedRefreshRate() < 0) status = XRRSetScreenConfig(QX11Info::display(), m_config, rootWindow(), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime); else { if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) { m_proposedRefreshRate = 0; } status = XRRSetScreenConfigAndRate(QX11Info::display(), m_config, rootWindow(), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime); } //kDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)); if (status == RRSetConfigSuccess) { m_currentSize = m_proposedSize; m_currentRotation = m_proposedRotation; m_currentRefreshRate = m_proposedRefreshRate; return true; } return false; } bool LegacyRandRScreen::applyProposedAndConfirm() { if (proposedChanged()) { setOriginal(); if (applyProposed()) { if (!RandR::confirm()) { proposeOriginal(); applyProposed(); return false; } } else { return false; } } return true; } Window LegacyRandRScreen::rootWindow() const { return RootWindow(QX11Info::display(), m_screen); } QString LegacyRandRScreen::changedMessage() const { if (refreshRate() == -1) return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3", currentPixelSize().width(), currentPixelSize().height(), currentRotationDescription()); else return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3\nRefresh rate: %4", currentPixelSize().width(), currentPixelSize().height(), currentRotationDescription(), currentRefreshRateDescription()); } bool LegacyRandRScreen::changedFromOriginal() const { return m_currentSize != m_originalSize || m_currentRotation != m_originalRotation || m_currentRefreshRate != m_originalRefreshRate; } void LegacyRandRScreen::proposeOriginal() { m_proposedSize = m_originalSize; m_proposedRotation = m_originalRotation; m_proposedRefreshRate = m_originalRefreshRate; } bool LegacyRandRScreen::proposedChanged() const { return m_currentSize != m_proposedSize || m_currentRotation != m_proposedRotation || m_currentRefreshRate != m_proposedRefreshRate; } QString LegacyRandRScreen::currentRotationDescription() const { QString ret = RandR::rotationName(m_currentRotation & RandR::RotateMask); if (m_currentRotation != (m_currentRotation & RandR::RotateMask)) { if (m_currentRotation & RR_Rotate_0) ret = RandR::rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, true); else ret += ", " + RandR::rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, false); } return ret; } int LegacyRandRScreen::rotationIndexToDegree(int rotation) const { switch (rotation & RandR::RotateMask) { case RR_Rotate_90: return 90; case RR_Rotate_180: return 180; case RR_Rotate_270: return 270; default: return 0; } } int LegacyRandRScreen::rotationDegreeToIndex(int degree) const { switch (degree) { case 90: return RR_Rotate_90; case 180: return RR_Rotate_180; case 270: return RR_Rotate_270; default: return RR_Rotate_0; } } const QSize& LegacyRandRScreen::currentPixelSize() const { return m_pixelSizes[m_currentSize]; } RateList LegacyRandRScreen::refreshRates(int size) const { int nrates; short* rrates = XRRRates(QX11Info::display(), m_screen, (SizeID)size, &nrates); RateList rateList; for (int i = 0; i < nrates; i++) rateList.append(rrates[i]); return rateList; } QString LegacyRandRScreen::refreshRateDirectDescription(int rate) const { return i18nc("Refresh rate in Hertz (Hz)", "%1 Hz", rate); } QString LegacyRandRScreen::refreshRateIndirectDescription(int size, int index) const { return i18nc("Refresh rate in Hertz (Hz)", "%1 Hz", refreshRateIndexToHz(size, index)); } QString LegacyRandRScreen::refreshRateDescription(int size, int index) const { return ki18n("%1 Hz").subs(refreshRates(size)[index], 0, 'f', 1).toString(); } bool LegacyRandRScreen::proposeRefreshRate(int index) { if (index >= 0 && (int)refreshRates(proposedSize()).count() > index) { m_proposedRefreshRate = index; return true; } return false; } int LegacyRandRScreen::refreshRate() const { return m_currentRefreshRate; } QString LegacyRandRScreen::currentRefreshRateDescription() const { return refreshRateIndirectDescription(m_currentSize, m_currentRefreshRate); } int LegacyRandRScreen::proposedRefreshRate() const { return m_proposedRefreshRate; } int LegacyRandRScreen::refreshRateHzToIndex(int size, int hz) const { int nrates; short* rates = XRRRates(QX11Info::display(), m_screen, (SizeID)size, &nrates); for (int i = 0; i < nrates; i++) if (hz == rates[i]) return i; if (nrates != 0) // Wrong input Hz! Q_ASSERT(false); return -1; } int LegacyRandRScreen::refreshRateIndexToHz(int size, int index) const { int nrates; short* rates = XRRRates(QX11Info::display(), m_screen, (SizeID)size, &nrates); if (nrates == 0 || index < 0) return 0; // Wrong input Hz! if(index >= nrates) return 0; return rates[index]; } int LegacyRandRScreen::numSizes() const { return m_pixelSizes.count(); } const QSize& LegacyRandRScreen::pixelSize(int index) const { return m_pixelSizes[index]; } const QSize& LegacyRandRScreen::mmSize(int index) const { return m_mmSizes[index]; } int LegacyRandRScreen::sizeIndex(const QSize &pixelSize) const { for (int i = 0; i < m_pixelSizes.count(); i++) if (m_pixelSizes[i] == pixelSize) return i; return -1; } int LegacyRandRScreen::rotations() const { return m_rotations; } int LegacyRandRScreen::rotation() const { return m_currentRotation; } int LegacyRandRScreen::size() const { return m_currentSize; } int LegacyRandRScreen::proposedRotation() const { return m_proposedRotation; } void LegacyRandRScreen::proposeRotation(int newRotation) { m_proposedRotation = newRotation & RandR::OrientationMask; } int LegacyRandRScreen::proposedSize() const { return m_proposedSize; } bool LegacyRandRScreen::proposeSize(int newSize) { if ((int)m_pixelSizes.count() > newSize) { m_proposedSize = newSize; return true; } return false; } void LegacyRandRScreen::load(KConfig& config) { KConfigGroup group = config.group(QString("Screen%1").arg(m_screen)); if (proposeSize(sizeIndex(group.readEntry("size", currentPixelSize())))) proposeRefreshRate(refreshRateHzToIndex(proposedSize(), group.readEntry("refresh", refreshRate()))); proposeRotation(rotationDegreeToIndex( group.readEntry("rotation", 0)) + (group.readEntry("reflectX", false) ? RandR::ReflectX : 0) + (group.readEntry("reflectY",false) ? RandR::ReflectY : 0)); } void LegacyRandRScreen::save(KConfig& config) const { KConfigGroup group = config.group(QString("Screen%1").arg(m_screen)); group.writeEntry("size", currentPixelSize()); group.writeEntry("refresh", refreshRateIndexToHz(size(), refreshRate())); group.writeEntry("rotation", rotationIndexToDegree(rotation())); group.writeEntry("reflectX", (bool)(rotation() & RandR::ReflectMask) == RandR::ReflectX); group.writeEntry("reflectY", (bool)(rotation() & RandR::ReflectMask) == RandR::ReflectY); } QStringList LegacyRandRScreen::startupCommands() const { QString command = QString("xrandr -s %1x%2 -r %3 ").arg( currentPixelSize().width(), currentPixelSize().height(), refreshRateIndexToHz(size(), refreshRate())); switch( rotation()) { case RR_Rotate_90: command += " -o 1 "; break; case RR_Rotate_180: command += " -o 2 "; break; case RR_Rotate_270: command += " -o 3 "; break; } if((rotation() & RandR::ReflectMask) == RandR::ReflectX) command += " -x "; if((bool)(rotation() & RandR::ReflectMask) == RandR::ReflectY) command += " -y "; return QStringList() << command; } int LegacyRandRScreen::pixelCount( int index ) const { QSize sz = pixelSize(index); return sz.width() * sz.height(); } SizeList LegacyRandRScreen::pixelSizes() const { return m_pixelSizes; } #include "moc_legacyrandrscreen.cpp"