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

krandr

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

krandr

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

krandr

Skip menu "krandr"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for krandr by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |