• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tderandr
 

tderandr

randr.cpp
00001 /*
00002  * Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017  */
00018 
00019 #include "randr.h"
00020 #include "lowlevel_randr.h"
00021 
00022 #include <tqtimer.h>
00023 
00024 #include <kdebug.h>
00025 #include <tdelocale.h>
00026 #include <tdeglobal.h>
00027 #include <tdeapplication.h>
00028 #include <kiconloader.h>
00029 #include <dcopclient.h>
00030 #include <kipc.h>
00031 #include <kactivelabel.h>
00032 
00033 #include "ktimerdialog.h"
00034 
00035 #include <X11/Xlib.h>
00036 #define INT8 _X11INT8
00037 #define INT32 _X11INT32
00038 #include <X11/Xproto.h>
00039 #undef INT8
00040 #undef INT32
00041 #include <X11/extensions/Xrandr.h>
00042 
00043 HotPlugRule::HotPlugRule()
00044 {
00045     //
00046 }
00047 
00048 HotPlugRule::~HotPlugRule()
00049 {
00050     //
00051 }
00052 
00053 SingleScreenData::SingleScreenData()
00054 {
00055     generic_screen_detected = false;
00056     screen_connected = false;
00057 
00058     current_resolution_index = 0;
00059     current_refresh_rate_index = 0;
00060     current_color_depth_index = 0;
00061 
00062     gamma_red = 0.0;
00063     gamma_green = 0.0;
00064     gamma_blue = 0.0;
00065 
00066     current_rotation_index = 0;
00067     current_orientation_mask = 0;
00068     has_x_flip = false;
00069     has_y_flip = false;
00070     supports_transformations = false;
00071 
00072     is_primary = false;
00073     is_extended = false;
00074     absolute_x_position = 0;
00075     absolute_y_position = 0;
00076     current_x_pixel_count = 0;
00077     current_y_pixel_count = 0;
00078 
00079     has_dpms = false;
00080     enable_dpms = false;
00081     dpms_standby_delay = 0;
00082     dpms_suspend_delay = 0;
00083     dpms_off_delay = 0;
00084 }
00085 
00086 SingleScreenData::~SingleScreenData()
00087 {
00088     //
00089 }
00090 
00091 class RandRScreenPrivate
00092 {
00093 public:
00094     RandRScreenPrivate() : config(0L) {};
00095     ~RandRScreenPrivate()
00096     {
00097         if (config) {
00098             XRRFreeScreenConfigInfo(config);
00099         }
00100     }
00101 
00102     XRRScreenConfiguration* config;
00103 };
00104 
00105 KDE_EXPORT RandRScreen::RandRScreen(int screenIndex)
00106     : d(new RandRScreenPrivate())
00107     , m_screen(screenIndex)
00108     , m_shownDialog(NULL)
00109 {
00110     loadSettings();
00111     setOriginal();
00112 }
00113 
00114 KDE_EXPORT RandRScreen::~RandRScreen()
00115 {
00116     delete d;
00117 }
00118 
00119 KDE_EXPORT void RandRScreen::loadSettings()
00120 {
00121     if (d->config) {
00122         XRRFreeScreenConfigInfo(d->config);
00123     }
00124 
00125     d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen));
00126 
00127     Rotation rotation;
00128     if (d->config) {
00129         m_currentSize = m_proposedSize = XRRConfigCurrentConfiguration(d->config, &rotation);
00130         m_currentRotation = m_proposedRotation = rotation;
00131     }
00132     else {
00133         m_currentSize = m_proposedSize = 0;
00134         m_currentRotation = m_proposedRotation = 0;
00135     }
00136 
00137     m_pixelSizes.clear();
00138     m_mmSizes.clear();
00139 
00140     if (d->config) {
00141         int numSizes;
00142         XRRScreenSize* sizes = XRRSizes(tqt_xdisplay(), m_screen, &numSizes);
00143         for (int i = 0; i < numSizes; i++) {
00144             m_pixelSizes.append(TQSize(sizes[i].width, sizes[i].height));
00145             m_mmSizes.append(TQSize(sizes[i].mwidth, sizes[i].mheight));
00146         }
00147 
00148         m_rotations = XRRRotations(tqt_xdisplay(), m_screen, &rotation);
00149     }
00150     else {
00151         // Great, now we have to go after the information manually.  Ughh.
00152         ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
00153         XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info;
00154         CrtcInfo *current_crtc = screeninfo->outputs[m_screen]->cur_crtc;
00155         int numSizes = output_info->nmode;
00156         for (int i = 0; i < numSizes; i++) {
00157             XRRModeInfo *xrrmode;
00158             xrrmode = internal_find_mode_by_xid (screeninfo, output_info->modes[i]);
00159             TQSize newSize = TQSize(xrrmode->width, xrrmode->height);
00160             if (!m_pixelSizes.contains(newSize)) {
00161                 m_pixelSizes.append(newSize);
00162                 m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height));
00163             }
00164         }
00165         if (current_crtc) {
00166             m_rotations = current_crtc->rotations;
00167             m_currentRotation = m_proposedRotation = current_crtc->cur_rotation;
00168         }
00169     }
00170 
00171     if (d->config) {
00172         m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex(m_currentSize, XRRConfigCurrentRate(d->config));
00173     }
00174     else {
00175         m_currentRefreshRate = m_proposedRefreshRate = 0;
00176     }
00177 }
00178 
00179 KDE_EXPORT void RandRScreen::setOriginal()
00180 {
00181     m_originalSize = m_currentSize;
00182     m_originalRotation = m_currentRotation;
00183     m_originalRefreshRate = m_currentRefreshRate;
00184 }
00185 
00186 KDE_EXPORT bool RandRScreen::applyProposed()
00187 {
00188     //kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl;
00189 
00190     Status status;
00191 
00192     if (!d->config) {
00193         d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen));
00194         Q_ASSERT(d->config);
00195     }
00196 
00197     if (d->config) {
00198         if (proposedRefreshRate() < 0)
00199             status = XRRSetScreenConfig(tqt_xdisplay(), d->config, DefaultRootWindow(tqt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime);
00200         else {
00201             if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) {
00202                 m_proposedRefreshRate = 0;
00203             }
00204             status = XRRSetScreenConfigAndRate(tqt_xdisplay(), d->config, DefaultRootWindow(tqt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime);
00205         }
00206     }
00207     else {
00208         // Great, now we have to set the information manually.  Ughh.
00209         // FIXME--this does not work!
00210         ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
00211         screeninfo->cur_width = (*m_pixelSizes.at(proposedSize())).width();
00212         screeninfo->cur_height = (*m_pixelSizes.at(proposedSize())).height();
00213         internal_main_low_apply(screeninfo);
00214 
00215         status = RRSetConfigSuccess;
00216     }
00217 
00218     //kdDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), screen)) << endl;
00219 
00220     if (status == RRSetConfigSuccess) {
00221         m_currentSize = m_proposedSize;
00222         m_currentRotation = m_proposedRotation;
00223         m_currentRefreshRate = m_proposedRefreshRate;
00224         return true;
00225     }
00226 
00227     return false;
00228 }
00229 
00230 KDE_EXPORT bool RandRScreen::applyProposedAndConfirm()
00231 {
00232     if (proposedChanged()) {
00233         setOriginal();
00234 
00235         if (applyProposed()) {
00236             if (!confirm()) {
00237                 proposeOriginal();
00238                 applyProposed();
00239                 return false;
00240             }
00241         } else {
00242             return false;
00243         }
00244     }
00245 
00246     return true;
00247 }
00248 
00249 KDE_EXPORT bool RandRScreen::confirm()
00250 {
00251     // uncomment the line below and edit out the KTimerDialog stuff to get
00252     // a version which works on today's tdelibs (no accept dialog is presented)
00253 
00254     // FIXME remember to put the dialog on the right screen
00255 
00256     KTimerDialog acceptDialog ( 15000, KTimerDialog::CountDown,
00257                 TDEApplication::kApplication()->mainWidget(),
00258                                             "mainKTimerDialog",
00259                                             true,
00260                                             i18n("Confirm Display Setting Change"),
00261                                             KTimerDialog::Ok|KTimerDialog::Cancel,
00262                                             KTimerDialog::Cancel);
00263 
00264     acceptDialog.setButtonOK(KGuiItem(i18n("&Accept Configuration"), "button_ok"));
00265     acceptDialog.setButtonCancel(KGuiItem(i18n("&Return to Previous Configuration"), "button_cancel"));
00266 
00267     KActiveLabel *label = new KActiveLabel(i18n("Your screen orientation, size and refresh rate "
00268                     "have been changed to the requested settings. Please indicate whether you wish to "
00269                     "keep this configuration. In 15 seconds the display will revert to your previous "
00270                     "settings."), &acceptDialog, "userSpecifiedLabel");
00271 
00272     acceptDialog.setMainWidget(label);
00273 
00274     KDialog::centerOnScreen(&acceptDialog, m_screen);
00275 
00276     m_shownDialog = &acceptDialog;
00277     connect( m_shownDialog, TQT_SIGNAL( destroyed()), this, TQT_SLOT( shownDialogDestroyed()));
00278     connect( kapp->desktop(), TQT_SIGNAL( resized(int)), this, TQT_SLOT( desktopResized()));
00279 
00280         return acceptDialog.exec();
00281 }
00282 
00283 KDE_EXPORT void RandRScreen::shownDialogDestroyed()
00284 {
00285     m_shownDialog = NULL;
00286     disconnect( kapp->desktop(), TQT_SIGNAL( resized(int)), this, TQT_SLOT( desktopResized()));
00287 }
00288 
00289 KDE_EXPORT void RandRScreen::desktopResized()
00290 {
00291     if( m_shownDialog != NULL )
00292         KDialog::centerOnScreen(m_shownDialog, m_screen);
00293 }
00294 
00295 KDE_EXPORT TQString RandRScreen::changedMessage() const
00296 {
00297     if (currentRefreshRate() == -1)
00298         return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3")
00299             .arg(currentPixelWidth())
00300             .arg(currentPixelHeight())
00301             .arg(currentRotationDescription());
00302     else
00303         return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3\nRefresh rate: %4")
00304             .arg(currentPixelWidth())
00305             .arg(currentPixelHeight())
00306             .arg(currentRotationDescription())
00307             .arg(currentRefreshRateDescription());
00308 }
00309 
00310 KDE_EXPORT bool RandRScreen::changedFromOriginal() const
00311 {
00312     return m_currentSize != m_originalSize || m_currentRotation != m_originalRotation || m_currentRefreshRate != m_originalRefreshRate;
00313 }
00314 
00315 KDE_EXPORT void RandRScreen::proposeOriginal()
00316 {
00317     m_proposedSize = m_originalSize;
00318     m_proposedRotation = m_originalRotation;
00319     m_proposedRefreshRate = m_originalRefreshRate;
00320 }
00321 
00322 KDE_EXPORT bool RandRScreen::proposedChanged() const
00323 {
00324     return m_currentSize != m_proposedSize || m_currentRotation != m_proposedRotation || m_currentRefreshRate != m_proposedRefreshRate;
00325 }
00326 
00327 KDE_EXPORT TQString RandRScreen::rotationName(int rotation, bool pastTense, bool capitalised)
00328 {
00329     if (!pastTense)
00330         switch (rotation) {
00331             case RR_Rotate_0:
00332                 return i18n("Normal");
00333             case RR_Rotate_90:
00334                 return i18n("Left (90 degrees)");
00335             case RR_Rotate_180:
00336                 return i18n("Upside-down (180 degrees)");
00337             case RR_Rotate_270:
00338                 return i18n("Right (270 degrees)");
00339             case RR_Reflect_X:
00340                 return i18n("Mirror horizontally");
00341             case RR_Reflect_Y:
00342                 return i18n("Mirror vertically");
00343             default:
00344                 return i18n("Unknown orientation");
00345         }
00346 
00347     switch (rotation) {
00348         case RR_Rotate_0:
00349             return i18n("Normal");
00350         case RR_Rotate_90:
00351             return i18n("Rotated 90 degrees counterclockwise");
00352         case RR_Rotate_180:
00353             return i18n("Rotated 180 degrees counterclockwise");
00354         case RR_Rotate_270:
00355             return i18n("Rotated 270 degrees counterclockwise");
00356         default:
00357             if (rotation & RR_Reflect_X)
00358                 if (rotation & RR_Reflect_Y)
00359                     if (capitalised)
00360                         return i18n("Mirrored horizontally and vertically");
00361                     else
00362                         return i18n("mirrored horizontally and vertically");
00363                 else
00364                     if (capitalised)
00365                         return i18n("Mirrored horizontally");
00366                     else
00367                         return i18n("mirrored horizontally");
00368             else if (rotation & RR_Reflect_Y)
00369                 if (capitalised)
00370                     return i18n("Mirrored vertically");
00371                 else
00372                     return i18n("mirrored vertically");
00373             else
00374                 if (capitalised)
00375                     return i18n("Unknown orientation");
00376                 else
00377                     return i18n("unknown orientation");
00378     }
00379 }
00380 
00381 KDE_EXPORT TQPixmap RandRScreen::rotationIcon(int rotation) const
00382 {
00383     // Adjust icons for current screen orientation
00384     if (!(m_currentRotation & RR_Rotate_0) && rotation & (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)) {
00385         int currentAngle = m_currentRotation & (RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
00386         switch (currentAngle) {
00387             case RR_Rotate_90:
00388                 rotation <<= 3;
00389                 break;
00390             case RR_Rotate_180:
00391                 rotation <<= 2;
00392                 break;
00393             case RR_Rotate_270:
00394                 rotation <<= 1;
00395                 break;
00396         }
00397 
00398         // Fix overflow
00399         if (rotation > RR_Rotate_270) {
00400             rotation >>= 4;
00401         }
00402     }
00403 
00404     switch (rotation) {
00405         case RR_Rotate_0:
00406             return SmallIcon("go-up");
00407         case RR_Rotate_90:
00408             return SmallIcon("back");
00409         case RR_Rotate_180:
00410             return SmallIcon("go-down");
00411         case RR_Rotate_270:
00412             return SmallIcon("forward");
00413         case RR_Reflect_X:
00414         case RR_Reflect_Y:
00415         default:
00416             return SmallIcon("process-stop");
00417     }
00418 }
00419 
00420 KDE_EXPORT TQString RandRScreen::currentRotationDescription() const
00421 {
00422     TQString ret = rotationName(m_currentRotation & RotateMask);
00423 
00424     if (m_currentRotation != (m_currentRotation & RotateMask)) {
00425         if (m_currentRotation & RR_Rotate_0) {
00426             ret = rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, true);
00427         }
00428         else {
00429             ret += ", " + rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, false);
00430         }
00431     }
00432 
00433     return ret;
00434 }
00435 
00436 KDE_EXPORT int RandRScreen::rotationIndexToDegree(int rotation) const
00437 {
00438     switch (rotation & RotateMask) {
00439         case RR_Rotate_90:
00440             return 90;
00441 
00442         case RR_Rotate_180:
00443             return 180;
00444 
00445         case RR_Rotate_270:
00446             return 270;
00447 
00448         default:
00449             return 0;
00450     }
00451 }
00452 
00453 KDE_EXPORT int RandRScreen::rotationDegreeToIndex(int degree) const
00454 {
00455     switch (degree) {
00456         case 90:
00457             return RR_Rotate_90;
00458 
00459         case 180:
00460             return RR_Rotate_180;
00461 
00462         case 270:
00463             return RR_Rotate_270;
00464 
00465         default:
00466             return RR_Rotate_0;
00467     }
00468 }
00469 
00470 KDE_EXPORT int RandRScreen::currentPixelWidth() const
00471 {
00472     return m_pixelSizes[m_currentSize].width();
00473 }
00474 
00475 KDE_EXPORT int RandRScreen::currentPixelHeight() const
00476 {
00477     return m_pixelSizes[m_currentSize].height();
00478 }
00479 
00480 KDE_EXPORT int RandRScreen::currentMMWidth() const
00481 {
00482     return m_pixelSizes[m_currentSize].width();
00483 }
00484 
00485 KDE_EXPORT int RandRScreen::currentMMHeight() const
00486 {
00487     return m_pixelSizes[m_currentSize].height();
00488 }
00489 
00490 KDE_EXPORT TQStringList RandRScreen::refreshRates(int size) const
00491 {
00492     int nrates;
00493     TQStringList ret;
00494 
00495     if (d->config) {
00496         short* rates = XRRRates(tqt_xdisplay(), m_screen, (SizeID)size, &nrates);
00497 
00498         for (int i = 0; i < nrates; i++)
00499             ret << refreshRateDirectDescription(rates[i]);
00500     }
00501     else {
00502         // Great, now we have to go after the information manually.  Ughh.
00503         ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
00504         int numSizes = screeninfo->res->nmode;
00505         for (int i = 0; i < numSizes; i++) {
00506             int refresh_rate = ((screeninfo->res->modes[i].dotClock*1.0)/((screeninfo->res->modes[i].hTotal)*(screeninfo->res->modes[i].vTotal)*1.0));
00507             TQString newRate = refreshRateDirectDescription(refresh_rate);
00508             if (!ret.contains(newRate)) {
00509                 ret.append(newRate);
00510             }
00511         }
00512     }
00513 
00514     return ret;
00515 }
00516 
00517 KDE_EXPORT TQString RandRScreen::refreshRateDirectDescription(int rate) const
00518 {
00519     return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(rate);
00520 }
00521 
00522 KDE_EXPORT TQString RandRScreen::refreshRateIndirectDescription(int size, int index) const
00523 {
00524     return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(refreshRateIndexToHz(size, index));
00525 }
00526 
00527 KDE_EXPORT TQString RandRScreen::refreshRateDescription(int size, int index) const
00528 {
00529     return refreshRates(size)[index];
00530 }
00531 
00532 KDE_EXPORT bool RandRScreen::proposeRefreshRate(int index)
00533 {
00534     if (index >= 0 && (int)refreshRates(proposedSize()).count() > index) {
00535         m_proposedRefreshRate = index;
00536         return true;
00537     }
00538 
00539     return false;
00540 }
00541 
00542 KDE_EXPORT int RandRScreen::currentRefreshRate() const
00543 {
00544     return m_currentRefreshRate;
00545 }
00546 
00547 KDE_EXPORT TQString RandRScreen::currentRefreshRateDescription() const
00548 {
00549     return refreshRateIndirectDescription(m_currentSize, m_currentRefreshRate);
00550 }
00551 
00552 KDE_EXPORT int RandRScreen::proposedRefreshRate() const
00553 {
00554     return m_proposedRefreshRate;
00555 }
00556 
00557 KDE_EXPORT int RandRScreen::refreshRateHzToIndex(int size, int hz) const
00558 {
00559     int nrates;
00560     short* rates = XRRRates(tqt_xdisplay(), m_screen, (SizeID)size, &nrates);
00561 
00562     for (int i = 0; i < nrates; i++)
00563         if (hz == rates[i])
00564             return i;
00565 
00566     if (nrates != 0)
00567         // Wrong input Hz!
00568         Q_ASSERT(false);
00569 
00570     return -1;
00571 }
00572 
00573 KDE_EXPORT int RandRScreen::refreshRateIndexToHz(int size, int index) const
00574 {
00575     int nrates;
00576     short* rates = XRRRates(tqt_xdisplay(), m_screen, (SizeID)size, &nrates);
00577 
00578     if (nrates == 0 || index < 0)
00579         return 0;
00580 
00581     // Wrong input Hz!
00582     if(index >= nrates)
00583         return 0;
00584 
00585     return rates[index];
00586 }
00587 
00588 KDE_EXPORT int RandRScreen::numSizes() const
00589 {
00590     return m_pixelSizes.count();
00591 }
00592 
00593 KDE_EXPORT const TQSize& RandRScreen::pixelSize(int index) const
00594 {
00595     return m_pixelSizes[index];
00596 }
00597 
00598 KDE_EXPORT const TQSize& RandRScreen::mmSize(int index) const
00599 {
00600     return m_mmSizes[index];
00601 }
00602 
00603 KDE_EXPORT int RandRScreen::sizeIndex(TQSize pixelSize) const
00604 {
00605     for (uint i = 0; i < m_pixelSizes.count(); i++)
00606         if (m_pixelSizes[i] == pixelSize)
00607             return i;
00608 
00609     return -1;
00610 }
00611 
00612 KDE_EXPORT int RandRScreen::rotations() const
00613 {
00614     return m_rotations;
00615 }
00616 
00617 KDE_EXPORT int RandRScreen::currentRotation() const
00618 {
00619     return m_currentRotation;
00620 }
00621 
00622 KDE_EXPORT int RandRScreen::currentSize() const
00623 {
00624     return m_currentSize;
00625 }
00626 
00627 KDE_EXPORT int RandRScreen::proposedRotation() const
00628 {
00629     return m_proposedRotation;
00630 }
00631 
00632 KDE_EXPORT void RandRScreen::proposeRotation(int newRotation)
00633 {
00634     m_proposedRotation = newRotation & OrientationMask;
00635 }
00636 
00637 KDE_EXPORT int RandRScreen::proposedSize() const
00638 {
00639     return m_proposedSize;
00640 }
00641 
00642 KDE_EXPORT bool RandRScreen::proposeSize(int newSize)
00643 {
00644     if ((int)m_pixelSizes.count() > newSize) {
00645         m_proposedSize = newSize;
00646         return true;
00647     }
00648 
00649     return false;
00650 }
00651 
00652 KDE_EXPORT void RandRScreen::load(TDEConfig& config)
00653 {
00654     config.setGroup(TQString("Screen%1").arg(m_screen));
00655 
00656     if (proposeSize(sizeIndex(TQSize(config.readNumEntry("width", currentPixelWidth()), config.readNumEntry("height", currentPixelHeight())))))
00657         proposeRefreshRate(refreshRateHzToIndex(proposedSize(), config.readNumEntry("refresh", currentRefreshRate())));
00658 
00659     proposeRotation(rotationDegreeToIndex(config.readNumEntry("rotation", 0)) + (config.readBoolEntry("reflectX") ? ReflectX : 0) + (config.readBoolEntry("reflectY") ? ReflectY : 0));
00660 }
00661 
00662 KDE_EXPORT void RandRScreen::save(TDEConfig& config) const
00663 {
00664     config.setGroup(TQString("Screen%1").arg(m_screen));
00665     config.writeEntry("width", currentPixelWidth());
00666     config.writeEntry("height", currentPixelHeight());
00667     config.writeEntry("refresh", refreshRateIndexToHz(currentSize(), currentRefreshRate()));
00668     config.writeEntry("rotation", rotationIndexToDegree(currentRotation()));
00669     config.writeEntry("reflectX", (bool)(currentRotation() & ReflectMask) == ReflectX);
00670     config.writeEntry("reflectY", (bool)(currentRotation() & ReflectMask) == ReflectY);
00671 }
00672 
00673 KDE_EXPORT RandRDisplay::RandRDisplay()
00674     : m_valid(true)
00675 {
00676     // Check extension
00677     Status s = XRRQueryExtension(tqt_xdisplay(), &m_eventBase, &m_errorBase);
00678     if (!s) {
00679         m_errorCode = TQString("%1, base %1").arg(s).arg(m_errorBase);
00680         m_valid = false;
00681         return;
00682     }
00683 
00684     // Sometimes the extension is available but does not return any screens (!)
00685     // Check for that case
00686     Display *randr_display = XOpenDisplay(NULL);
00687     int screen_num;
00688     Window root_window;
00689 
00690     screen_num = DefaultScreen (randr_display);
00691     root_window = RootWindow (randr_display, screen_num);
00692     if (XRRGetScreenResources (randr_display, root_window) == NULL) {
00693         m_errorCode = i18n("No screens detected");
00694         m_valid = false;
00695         return;
00696     }
00697 
00698     int major_version, minor_version;
00699     XRRQueryVersion(tqt_xdisplay(), &major_version, &minor_version);
00700 
00701     m_version = TQString("X Resize and Rotate extension version %1.%1").arg(major_version).arg(minor_version);
00702 
00703     m_numScreens = ScreenCount(tqt_xdisplay());
00704 
00705     // This assumption is WRONG with Xinerama
00706     // Q_ASSERT(TQApplication::desktop()->numScreens() == ScreenCount(tqt_xdisplay()));
00707 
00708     m_screens.setAutoDelete(true);
00709     for (int i = 0; i < m_numScreens; i++) {
00710         m_screens.append(new RandRScreen(i));
00711     }
00712 
00713     setCurrentScreen(TQApplication::desktop()->primaryScreen());
00714 }
00715 
00716 KDE_EXPORT bool RandRDisplay::isValid() const
00717 {
00718     return m_valid;
00719 }
00720 
00721 KDE_EXPORT const TQString& RandRDisplay::errorCode() const
00722 {
00723     return m_errorCode;
00724 }
00725 
00726 KDE_EXPORT int RandRDisplay::eventBase() const
00727 {
00728     return m_eventBase;
00729 }
00730 
00731 KDE_EXPORT int RandRDisplay::screenChangeNotifyEvent() const
00732 {
00733     return m_eventBase + RRScreenChangeNotify;
00734 }
00735 
00736 KDE_EXPORT int RandRDisplay::errorBase() const
00737 {
00738     return m_errorBase;
00739 }
00740 
00741 KDE_EXPORT const TQString& RandRDisplay::version() const
00742 {
00743     return m_version;
00744 }
00745 
00746 KDE_EXPORT void RandRDisplay::setCurrentScreen(int index)
00747 {
00748     m_currentScreenIndex = index;
00749     m_currentScreen = m_screens.at(m_currentScreenIndex);
00750     Q_ASSERT(m_currentScreen);
00751 }
00752 
00753 KDE_EXPORT int RandRDisplay::screenIndexOfWidget(TQWidget* widget)
00754 {
00755     int ret = TQApplication::desktop()->screenNumber(widget);
00756     return ret != -1 ? ret : TQApplication::desktop()->primaryScreen();
00757 }
00758 
00759 KDE_EXPORT int RandRDisplay::currentScreenIndex() const
00760 {
00761     return m_currentScreenIndex;
00762 }
00763 
00764 KDE_EXPORT void RandRDisplay::refresh()
00765 {
00766     for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
00767         s->loadSettings();
00768 }
00769 
00770 KDE_EXPORT int RandRDisplay::numScreens() const
00771 {
00772     return m_numScreens;
00773 }
00774 
00775 KDE_EXPORT RandRScreen* RandRDisplay::screen(int index)
00776 {
00777     return m_screens.at(index);
00778 }
00779 
00780 KDE_EXPORT RandRScreen* RandRDisplay::currentScreen()
00781 {
00782     return m_currentScreen;
00783 }
00784 
00785 KDE_EXPORT bool RandRDisplay::loadDisplay(TDEConfig& config, bool loadScreens)
00786 {
00787     if (loadScreens)
00788         for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
00789             s->load(config);
00790 
00791     return applyOnStartup(config);
00792 }
00793 
00794 KDE_EXPORT bool RandRDisplay::applyOnStartup(TDEConfig& config)
00795 {
00796     config.setGroup("Display");
00797     return config.readBoolEntry("ApplyOnStartup", false);
00798 }
00799 
00800 KDE_EXPORT bool RandRDisplay::syncTrayApp(TDEConfig& config)
00801 {
00802     config.setGroup("Display");
00803     return config.readBoolEntry("SyncTrayApp", false);
00804 }
00805 
00806 KDE_EXPORT void RandRDisplay::saveDisplay(TDEConfig& config, bool applyOnStartup, bool syncTrayApp)
00807 {
00808     Q_ASSERT(!config.isReadOnly());
00809 
00810     config.setGroup("Display");
00811     config.writeEntry("ApplyOnStartup", applyOnStartup);
00812     config.writeEntry("SyncTrayApp", syncTrayApp);
00813 
00814     for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
00815         s->save(config);
00816 }
00817 
00818 KDE_EXPORT void RandRDisplay::applyProposed(bool confirm)
00819 {
00820     for (int screenIndex = 0; screenIndex < numScreens(); screenIndex++) {
00821         if (screen(screenIndex)->proposedChanged()) {
00822             if (confirm)
00823                     screen(screenIndex)->applyProposedAndConfirm();
00824             else
00825                     screen(screenIndex)->applyProposed();
00826         }
00827     }
00828 }
00829 
00830 KDE_EXPORT bool RandRDisplay::showTestConfigurationDialog()
00831 {
00832     RandRScreen* firstScreen = screen(0);
00833     if (firstScreen) {
00834         return firstScreen->showTestConfigurationDialog();
00835     }
00836     else {
00837         return false;
00838     }
00839 }
00840 
00841 KDE_EXPORT bool RandRScreen::showTestConfigurationDialog()
00842 {
00843     // uncomment the line below and edit out the KTimerDialog stuff to get
00844     // a version which works on today's tdelibs (no accept dialog is presented)
00845 
00846     // FIXME remember to put the dialog on the right screen
00847 
00848     KTimerDialog acceptDialog ( 15000, KTimerDialog::CountDown,
00849                 TDEApplication::kApplication()->mainWidget(),
00850                                             "mainKTimerDialog",
00851                                             true,
00852                                             i18n("Confirm Display Settings"),
00853                                             KTimerDialog::Ok|KTimerDialog::Cancel,
00854                                             KTimerDialog::Cancel);
00855 
00856     acceptDialog.setButtonOK(KGuiItem(i18n("&Accept Configuration"), "button_ok"));
00857     acceptDialog.setButtonCancel(KGuiItem(i18n("&Return to Previous Configuration"), "button_cancel"));
00858 
00859     KActiveLabel *label = new KActiveLabel(i18n("Your display devices has been configured "
00860                     "to match the settings shown above. Please indicate whether you wish to "
00861                     "keep this configuration. In 15 seconds the display will revert to your previous "
00862                     "settings."), &acceptDialog, "userSpecifiedLabel");
00863 
00864     acceptDialog.setMainWidget(label);
00865 
00866     KDialog::centerOnScreen(&acceptDialog, 0);
00867 
00868     m_shownDialog = &acceptDialog;
00869     connect( m_shownDialog, TQT_SIGNAL( destroyed()), this, TQT_SLOT( shownDialogDestroyed()));
00870     connect( kapp->desktop(), TQT_SIGNAL( resized(int)), this, TQT_SLOT( desktopResized()));
00871 
00872         return acceptDialog.exec();
00873 }
00874 
00875 KDE_EXPORT int RandRScreen::pixelCount( int index ) const
00876 {
00877     TQSize sz = pixelSize(index);
00878     return sz.width() * sz.height();
00879 }
00880 
00881 #include "randr.moc"

tderandr

Skip menu "tderandr"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tderandr

Skip menu "tderandr"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tderandr by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.