File indexing completed on 2024-05-19 16:31:48

0001 /*
0002  *  SPDX-License-Identifier: GPL-2.0-or-later
0003  *
0004  *  SPDX-FileCopyrightText: 2001 Michael v.Ostheim <MvOstheim@web.de>
0005  */
0006 
0007 #include "kgamma.h"
0008 
0009 #include "gammactrl.h"
0010 #include "xf86configpath.h"
0011 #include <unistd.h>
0012 
0013 #include <QBoxLayout>
0014 #include <QCheckBox>
0015 #include <QComboBox>
0016 #include <QDir>
0017 #include <QFormLayout>
0018 #include <QFrame>
0019 #include <QGridLayout>
0020 #include <QHBoxLayout>
0021 #include <QLabel>
0022 #include <QLayout>
0023 #include <QPixmap>
0024 #include <QProcess>
0025 #include <QStackedWidget>
0026 #include <QStandardPaths>
0027 #include <QString>
0028 #include <QStringList>
0029 #include <QTextStream>
0030 #include <QVBoxLayout>
0031 
0032 #include <KConfig>
0033 #include <KConfigGroup>
0034 #include <KLocalizedString>
0035 #include <KPluginFactory>
0036 
0037 #include "xvidextwrap.h"
0038 
0039 extern "C" {
0040 bool test_kgamma()
0041 {
0042     bool retval;
0043     (void)new XVidExtWrap(&retval, nullptr);
0044     return retval;
0045 }
0046 }
0047 
0048 K_PLUGIN_CLASS_WITH_JSON(KGamma, "kgamma.json")
0049 
0050 KGamma::KGamma(QWidget *parent_P, const QVariantList &)
0051     : KCModule(parent_P)
0052     , rootProcess(nullptr)
0053 {
0054     bool ok;
0055     GammaCorrection = false;
0056     xv = new XVidExtWrap(&ok, nullptr);
0057     if (ok) { /* KDE 4: Uneccessary test, when all KCM wrappers do conditional loading */
0058         xv->getGamma(XVidExtWrap::Red, &ok);
0059         if (ok) {
0060             ScreenCount = xv->_ScreenCount();
0061             currentScreen = xv->getScreen();
0062             xv->setGammaLimits(0.4, 3.5);
0063 
0064             for (int i = 0; i < ScreenCount; i++) {
0065                 assign << 0;
0066                 rgamma << QString();
0067                 ggamma << QString();
0068                 bgamma << QString();
0069 
0070                 // Store the current gamma values
0071                 xv->setScreen(i);
0072                 rbak << xv->getGamma(XVidExtWrap::Red);
0073                 gbak << xv->getGamma(XVidExtWrap::Green);
0074                 bbak << xv->getGamma(XVidExtWrap::Blue);
0075             }
0076             xv->setScreen(currentScreen);
0077 
0078             rootProcess = new QProcess;
0079             GammaCorrection = true;
0080             setupUI();
0081             saved = false;
0082 
0083             if (!loadSettings()) { // try to load gamma values from config file
0084                 // if failed, take current gamma values
0085                 for (int i = 0; i < ScreenCount; i++) {
0086                     rgamma[i].setNum(rbak[i], 'f', 2);
0087                     ggamma[i].setNum(gbak[i], 'f', 2);
0088                     bgamma[i].setNum(bbak[i], 'f', 2);
0089                 }
0090             }
0091             load();
0092         }
0093     }
0094     if (!GammaCorrection) { // something is wrong, show only error message
0095         setupUI();
0096     }
0097 }
0098 
0099 KGamma::~KGamma()
0100 {
0101     // Restore the old gamma settings, if the user has not saved
0102     // and there is no valid kgammarc.
0103     // Existing user settings overwrite system settings
0104     if (GammaCorrection) {
0105         // Do not emit signals during destruction (bug 221611)
0106         bool blocked = blockSignals(true);
0107         if (loadUserSettings()) {
0108             load();
0109         } else if (!saved) {
0110             for (int i = 0; i < ScreenCount; i++) {
0111                 xv->setScreen(i);
0112                 xv->setGamma(XVidExtWrap::Red, rbak[i]);
0113                 xv->setGamma(XVidExtWrap::Green, gbak[i]);
0114                 xv->setGamma(XVidExtWrap::Blue, bbak[i]);
0115             }
0116         }
0117         delete rootProcess;
0118         blockSignals(blocked);
0119     }
0120     delete xv;
0121 }
0122 
0123 /** User interface */
0124 void KGamma::setupUI()
0125 {
0126     QBoxLayout *topLayout = new QVBoxLayout(this);
0127     topLayout->setContentsMargins(0, 0, 0, 0);
0128 
0129     if (GammaCorrection) {
0130         QHBoxLayout *hbox = new QHBoxLayout();
0131         topLayout->addLayout(hbox);
0132         QLabel *label = new QLabel(i18n("&Select test picture:"), this);
0133         QComboBox *combo = new QComboBox(this);
0134         label->setBuddy(combo);
0135 
0136         QStringList list;
0137         list << i18n("Gray Scale") << i18n("RGB Scale") << i18n("CMY Scale") << i18n("Dark Gray") << i18n("Mid Gray") << i18n("Light Gray");
0138         combo->addItems(list);
0139 
0140         hbox->addWidget(label);
0141         hbox->addWidget(combo);
0142         hbox->addStretch();
0143 
0144         QStackedWidget *stack = new QStackedWidget(this);
0145         stack->setFrameStyle(QFrame::Box | QFrame::Raised);
0146 
0147         connect(combo, QOverload<int>::of(&QComboBox::activated), stack, &QStackedWidget::setCurrentIndex);
0148 
0149         QLabel *pic1 = new QLabel(stack);
0150         pic1->setMinimumSize(530, 171);
0151         pic1->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/greyscale.png"))));
0152         pic1->setAlignment(Qt::AlignCenter);
0153         stack->insertWidget(0, pic1);
0154 
0155         QLabel *pic2 = new QLabel(stack);
0156         pic2->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/rgbscale.png"))));
0157         pic2->setAlignment(Qt::AlignCenter);
0158         stack->insertWidget(1, pic2);
0159 
0160         QLabel *pic3 = new QLabel(stack);
0161         pic3->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/cmyscale.png"))));
0162         pic3->setAlignment(Qt::AlignCenter);
0163         stack->insertWidget(2, pic3);
0164 
0165         QLabel *pic4 = new QLabel(stack);
0166         pic4->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/darkgrey.png"))));
0167         pic4->setAlignment(Qt::AlignCenter);
0168         stack->insertWidget(3, pic4);
0169 
0170         QLabel *pic5 = new QLabel(stack);
0171         pic5->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/midgrey.png"))));
0172         pic5->setAlignment(Qt::AlignCenter);
0173         stack->insertWidget(4, pic5);
0174 
0175         QLabel *pic6 = new QLabel(stack);
0176         pic6->setPixmap(QPixmap(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kgamma/pics/lightgrey.png"))));
0177         pic6->setAlignment(Qt::AlignCenter);
0178         stack->insertWidget(5, pic6);
0179 
0180         topLayout->addWidget(stack, 10);
0181 
0182         // Sliders for gamma correction
0183 
0184         QLabel *gammalabel = new QLabel(this);
0185         gammalabel->setText(i18n("Gamma:"));
0186 
0187         QLabel *redlabel = new QLabel(this);
0188         redlabel->setText(i18n("Red:"));
0189 
0190         QLabel *greenlabel = new QLabel(this);
0191         greenlabel->setText(i18n("Green:"));
0192 
0193         QLabel *bluelabel = new QLabel(this);
0194         bluelabel->setText(i18n("Blue:"));
0195 
0196         gctrl = new GammaCtrl(this, xv);
0197         connect(gctrl, &GammaCtrl::gammaChanged, this, &KGamma::Changed);
0198         connect(gctrl, &GammaCtrl::gammaChanged, this, &KGamma::SyncScreens);
0199         gammalabel->setBuddy(gctrl);
0200 
0201         rgctrl = new GammaCtrl(this, xv, XVidExtWrap::Red);
0202         connect(rgctrl, &GammaCtrl::gammaChanged, this, &KGamma::Changed);
0203         connect(rgctrl, &GammaCtrl::gammaChanged, this, &KGamma::SyncScreens);
0204         connect(gctrl, SIGNAL(gammaChanged(int)), rgctrl, SLOT(setCtrl(int)));
0205         connect(rgctrl, &GammaCtrl::gammaChanged, gctrl, &GammaCtrl::suspend);
0206         redlabel->setBuddy(rgctrl);
0207 
0208         ggctrl = new GammaCtrl(this, xv, XVidExtWrap::Green);
0209         connect(ggctrl, &GammaCtrl::gammaChanged, this, &KGamma::Changed);
0210         connect(ggctrl, &GammaCtrl::gammaChanged, this, &KGamma::SyncScreens);
0211         connect(gctrl, SIGNAL(gammaChanged(int)), ggctrl, SLOT(setCtrl(int)));
0212         connect(ggctrl, &GammaCtrl::gammaChanged, gctrl, &GammaCtrl::suspend);
0213         greenlabel->setBuddy(ggctrl);
0214 
0215         bgctrl = new GammaCtrl(this, xv, XVidExtWrap::Blue);
0216         connect(bgctrl, &GammaCtrl::gammaChanged, this, &KGamma::Changed);
0217         connect(bgctrl, &GammaCtrl::gammaChanged, this, &KGamma::SyncScreens);
0218         connect(gctrl, SIGNAL(gammaChanged(int)), bgctrl, SLOT(setCtrl(int)));
0219         connect(bgctrl, &GammaCtrl::gammaChanged, gctrl, &GammaCtrl::suspend);
0220         bluelabel->setBuddy(bgctrl);
0221 
0222         QFormLayout *form = new QFormLayout;
0223         form->addRow(gammalabel, gctrl);
0224         form->addItem(new QSpacerItem(0, gammalabel->sizeHint().height() / 3));
0225         form->addRow(redlabel, rgctrl);
0226         form->addRow(greenlabel, ggctrl);
0227         form->addRow(bluelabel, bgctrl);
0228 
0229         topLayout->addLayout(form);
0230 
0231         // Options
0232         QWidget *options = new QWidget(this);
0233         QHBoxLayout *optionsHBoxLayout = new QHBoxLayout(options);
0234         optionsHBoxLayout->setContentsMargins(0, 0, 0, 0);
0235 
0236         xf86cfgbox = new QCheckBox(i18n("Save settings system wide"), options);
0237         optionsHBoxLayout->addWidget(xf86cfgbox);
0238         connect(xf86cfgbox, &QAbstractButton::clicked, this, &KGamma::changeConfig);
0239 
0240         syncbox = new QCheckBox(i18n("Sync screens"), options);
0241         optionsHBoxLayout->addWidget(syncbox);
0242         connect(syncbox, &QAbstractButton::clicked, this, &KGamma::SyncScreens);
0243         connect(syncbox, &QAbstractButton::clicked, this, &KGamma::Changed);
0244 
0245         screenselect = new QComboBox(options);
0246         optionsHBoxLayout->addWidget(screenselect);
0247         for (int i = 0; i < ScreenCount; i++) {
0248             screenselect->addItem(i18n("Screen %1", i + 1));
0249         }
0250         screenselect->setCurrentIndex(currentScreen);
0251         if (ScreenCount <= 1) {
0252             screenselect->setEnabled(false);
0253         } else {
0254             connect(screenselect, QOverload<int>::of(&QComboBox::activated), this, &KGamma::changeScreen);
0255         }
0256 
0257         optionsHBoxLayout->setSpacing(10);
0258         optionsHBoxLayout->setStretchFactor(xf86cfgbox, 10);
0259         optionsHBoxLayout->setStretchFactor(syncbox, 1);
0260         optionsHBoxLayout->setStretchFactor(screenselect, 1);
0261 
0262         topLayout->addWidget(options);
0263     } else {
0264         QLabel *error = new QLabel(this);
0265         error->setText(
0266             i18n("Gamma correction is not supported by your"
0267                  " graphics hardware or driver."));
0268         error->setAlignment(Qt::AlignCenter);
0269         topLayout->addWidget(error);
0270     }
0271 }
0272 
0273 /** Restore latest saved gamma values */
0274 void KGamma::load()
0275 {
0276     if (GammaCorrection) {
0277         KConfig *config = new KConfig(QStringLiteral("kgammarc"));
0278         KConfigGroup group = config->group("ConfigFile");
0279 
0280         // save checkbox status
0281         if (xf86cfgbox->isChecked()) {
0282             group.writeEntry("use", "XF86Config");
0283         } else {
0284             group.writeEntry("use", "kgammarc");
0285         }
0286 
0287         // load syncbox status
0288         group = config->group("SyncBox");
0289         if (group.readEntry("sync") == QLatin1String("yes")) {
0290             syncbox->setChecked(true);
0291         } else {
0292             syncbox->setChecked(false);
0293         }
0294 
0295         config->sync();
0296         delete config;
0297 
0298         for (int i = 0; i < ScreenCount; i++) {
0299             xv->setScreen(i);
0300             if (rgamma[i] == ggamma[i] && rgamma[i] == bgamma[i]) {
0301                 if (i == currentScreen) {
0302                     gctrl->setGamma(rgamma[i]);
0303                 } else {
0304                     xv->setGamma(XVidExtWrap::Value, rgamma[i].toFloat());
0305                 }
0306             } else {
0307                 if (i == currentScreen) {
0308                     rgctrl->setGamma(rgamma[i]);
0309                     ggctrl->setGamma(ggamma[i]);
0310                     bgctrl->setGamma(bgamma[i]);
0311                     gctrl->suspend();
0312                 } else {
0313                     xv->setGamma(XVidExtWrap::Red, rgamma[i].toFloat());
0314                     xv->setGamma(XVidExtWrap::Green, ggamma[i].toFloat());
0315                     xv->setGamma(XVidExtWrap::Blue, bgamma[i].toFloat());
0316                 }
0317             }
0318         }
0319         xv->setScreen(currentScreen);
0320 
0321         Q_EMIT changed(false);
0322     }
0323 }
0324 
0325 void KGamma::save()
0326 {
0327     if (GammaCorrection) {
0328         for (int i = 0; i < ScreenCount; i++) {
0329             xv->setScreen(i);
0330             rgamma[i] = rgctrl->gamma(2);
0331             ggamma[i] = ggctrl->gamma(2);
0332             bgamma[i] = bgctrl->gamma(2);
0333         }
0334         xv->setScreen(currentScreen);
0335 
0336         KConfig *config = new KConfig(QStringLiteral("kgammarc"));
0337         KConfigGroup group = config->group("SyncBox");
0338         if (syncbox->isChecked()) {
0339             group.writeEntry("sync", "yes");
0340         } else {
0341             group.writeEntry("sync", "no");
0342         }
0343 
0344         if (!xf86cfgbox->isChecked()) { // write gamma settings to the users config
0345             for (int i = 0; i < ScreenCount; i++) {
0346                 KConfigGroup screenGroup = config->group(QStringLiteral("Screen %1").arg(i));
0347                 screenGroup.writeEntry("rgamma", rgamma[i]);
0348                 screenGroup.writeEntry("ggamma", ggamma[i]);
0349                 screenGroup.writeEntry("bgamma", bgamma[i]);
0350             }
0351             KConfigGroup confGroup = config->group("ConfigFile");
0352             confGroup.writeEntry("use", "kgammarc");
0353         } else { // write gamma settings to section "Monitor" of XF86Config
0354             KConfigGroup x86group = config->group("ConfigFile");
0355             x86group.writeEntry("use", "XF86Config");
0356 
0357             if (!(rootProcess->state() == QProcess::Running)) {
0358                 QString Arguments = QStringLiteral("xf86gammacfg ");
0359                 for (int i = 0; i < ScreenCount; i++) {
0360                     Arguments += rgamma[assign[i]] + QLatin1Char(' ') + ggamma[assign[i]] + QLatin1Char(' ') + bgamma[assign[i]] + QLatin1Char(' ');
0361                 }
0362                 rootProcess->setProgram(QStandardPaths::findExecutable(QStringLiteral("kdesu")));
0363                 rootProcess->setArguments(Arguments.split(QLatin1Char(' ')));
0364                 rootProcess->start();
0365             }
0366         }
0367         config->sync();
0368         delete config;
0369         saved = true;
0370         Q_EMIT changed(false);
0371     }
0372 }
0373 
0374 void KGamma::defaults()
0375 {
0376     if (GammaCorrection) {
0377         for (int i = 0; i < ScreenCount; i++) {
0378             xv->setScreen(i);
0379             gctrl->setGamma(QStringLiteral("1.00"));
0380         }
0381         xv->setScreen(currentScreen);
0382     }
0383     xf86cfgbox->setChecked(false);
0384     syncbox->setChecked(false);
0385 }
0386 
0387 bool KGamma::loadSettings()
0388 {
0389     KConfig *config = new KConfig(QStringLiteral("kgammarc"));
0390     KConfigGroup grp = config->group("ConfigFile");
0391     QString ConfigFile(grp.readEntry("use"));
0392     KConfigGroup syncGroup = config->group("SyncBox");
0393     if (syncGroup.readEntry("sync") == QLatin1String("yes")) {
0394         syncbox->setChecked(true);
0395     }
0396     delete config;
0397 
0398     if (ConfigFile == QLatin1String("XF86Config")) { // parse XF86Config
0399         bool validGlobalConfig = loadSystemSettings();
0400         xf86cfgbox->setChecked(validGlobalConfig);
0401         return (validGlobalConfig);
0402     } else { // get gamma settings from user config
0403         return (loadUserSettings());
0404     }
0405 }
0406 
0407 bool KGamma::loadUserSettings()
0408 {
0409     KConfig *config = new KConfig(QStringLiteral("kgammarc"));
0410 
0411     for (int i = 0; i < ScreenCount; i++) {
0412         KConfigGroup screenGroup = config->group(QStringLiteral("Screen %1").arg(i));
0413         rgamma[i] = screenGroup.readEntry("rgamma");
0414         ggamma[i] = screenGroup.readEntry("ggamma");
0415         bgamma[i] = screenGroup.readEntry("bgamma");
0416     }
0417     delete config;
0418 
0419     return (validateGammaValues());
0420 }
0421 
0422 bool KGamma::loadSystemSettings()
0423 {
0424     QStringList Monitor, Screen, ScreenLayout, ScreenMonitor, Gamma;
0425     QList<int> ScreenNr;
0426     QString Section;
0427     XF86ConfigPath Path;
0428     QFile f(QString::fromUtf8(Path.get()));
0429     if (f.open(QIODevice::ReadOnly)) {
0430         QTextStream t(&f);
0431         QString s;
0432         int sn = 0;
0433         bool gm = false;
0434 
0435         // Analyze Screen<->Monitor assignments of multi-head configurations
0436         while (!t.atEnd()) {
0437             s = (t.readLine()).simplified();
0438             QStringList words = s.split(QLatin1Char(' '));
0439             if (!words.empty()) {
0440                 if (words[0] == QLatin1String("Section") && words.size() > 1) {
0441                     if ((Section = words[1]) == QLatin1String("\"Monitor\"")) {
0442                         gm = false;
0443                     }
0444                 } else if (words[0] == QLatin1String("EndSection")) {
0445                     if (Section == QLatin1String("\"Monitor\"") && !gm) {
0446                         Gamma << QString();
0447                         gm = false;
0448                     }
0449                     Section = QString();
0450                 } else if (words[0] == QLatin1String("Identifier") && words.size() > 1) {
0451                     if (Section == QLatin1String("\"Monitor\"")) {
0452                         Monitor << words[1];
0453                     } else if (Section == QLatin1String("\"Screen\"")) {
0454                         Screen << words[1];
0455                     }
0456                 } else if (words[0] == QLatin1String("Screen") && words.size() > 1) {
0457                     if (Section == QLatin1String("\"ServerLayout\"")) {
0458                         bool ok;
0459                         int i = words[1].toInt(&ok);
0460                         if (ok && words.size() > 2) {
0461                             ScreenNr << i;
0462                             ScreenLayout << words[2];
0463                         } else {
0464                             ScreenNr << sn++;
0465                             ScreenLayout << words[1];
0466                         }
0467                     }
0468                 } else if (words[0] == QLatin1String("Monitor") && words.size() > 1) {
0469                     if (Section == QLatin1String("\"Screen\"")) {
0470                         ScreenMonitor << words[1];
0471                     }
0472                 } else if (words[0] == QLatin1String("Gamma")) {
0473                     if (Section == QLatin1String("\"Monitor\"")) {
0474                         Gamma << s;
0475                         gm = true;
0476                     }
0477                 }
0478             }
0479         } // End while
0480         f.close();
0481         if (!Monitor.isEmpty() && !ScreenMonitor.isEmpty() && !ScreenLayout.isEmpty()) {
0482             for (int i = 0; i < ScreenCount; i++) {
0483                 for (int j = 0; j < ScreenCount; j++) {
0484                     if (ScreenLayout[i] == Screen[j]) {
0485                         for (int k = 0; k < ScreenCount; k++) {
0486                             if (Monitor[k] == ScreenMonitor[j]) {
0487                                 assign[ScreenNr[i]] = k;
0488                             }
0489                         }
0490                     }
0491                 }
0492             }
0493             // Extract gamma values
0494             if (gm) {
0495                 for (int i = 0; i < ScreenCount; i++) {
0496                     rgamma[i] = ggamma[i] = bgamma[i] = QString();
0497 
0498                     QStringList words = Gamma[assign[i]].split(QLatin1Char(' '));
0499                     QStringList::ConstIterator it = words.constBegin();
0500                     if (words.size() < 4) {
0501                         rgamma[i] = ggamma[i] = bgamma[i] = *(++it); // single gamma value
0502                     } else {
0503                         rgamma[i] = *(++it); // eventually rgb gamma values
0504                         ggamma[i] = *(++it);
0505                         bgamma[i] = *(++it);
0506                     }
0507                 }
0508             }
0509         }
0510     }
0511     return (validateGammaValues());
0512 }
0513 
0514 bool KGamma::validateGammaValues()
0515 {
0516     bool rOk, gOk, bOk, result;
0517 
0518     result = true;
0519     for (int i = 0; i < ScreenCount; i++) {
0520         rgamma[i].toFloat(&rOk);
0521         ggamma[i].toFloat(&gOk);
0522         bgamma[i].toFloat(&bOk);
0523 
0524         if (!(rOk && gOk && bOk)) {
0525             if (rOk) {
0526                 ggamma[i] = bgamma[i] = rgamma[i];
0527             } else {
0528                 result = false;
0529             }
0530         }
0531     }
0532     return (result);
0533 }
0534 
0535 void KGamma::changeConfig()
0536 {
0537     bool Ok = false;
0538 
0539     if (xf86cfgbox->isChecked()) {
0540         Ok = loadSystemSettings();
0541     } else {
0542         Ok = loadUserSettings();
0543     }
0544 
0545     if (!Ok) {
0546         for (int i = 0; i < ScreenCount; i++) {
0547             xv->setScreen(i);
0548             rgamma[i].setNum(xv->getGamma(XVidExtWrap::Red), 'f', 2);
0549             ggamma[i].setNum(xv->getGamma(XVidExtWrap::Green), 'f', 2);
0550             bgamma[i].setNum(xv->getGamma(XVidExtWrap::Blue), 'f', 2);
0551         }
0552         xv->setScreen(currentScreen);
0553     }
0554     load();
0555 }
0556 
0557 void KGamma::SyncScreens()
0558 {
0559     if (syncbox->isChecked()) {
0560         float rg = xv->getGamma(XVidExtWrap::Red);
0561         float gg = xv->getGamma(XVidExtWrap::Green);
0562         float bg = xv->getGamma(XVidExtWrap::Blue);
0563 
0564         for (int i = 0; i < ScreenCount; i++) {
0565             if (i != currentScreen) {
0566                 xv->setScreen(i);
0567                 xv->setGamma(XVidExtWrap::Red, rg);
0568                 xv->setGamma(XVidExtWrap::Green, gg);
0569                 xv->setGamma(XVidExtWrap::Blue, bg);
0570             }
0571         }
0572         xv->setScreen(currentScreen);
0573     }
0574 }
0575 
0576 void KGamma::changeScreen(int sn)
0577 {
0578     QString red, green, blue;
0579 
0580     xv->setScreen(sn);
0581     currentScreen = sn;
0582 
0583     red.setNum(xv->getGamma(XVidExtWrap::Red), 'f', 2);
0584     green.setNum(xv->getGamma(XVidExtWrap::Green), 'f', 2);
0585     blue.setNum(xv->getGamma(XVidExtWrap::Blue), 'f', 2);
0586 
0587     gctrl->setControl(red);
0588     rgctrl->setControl(red);
0589     ggctrl->setControl(green);
0590     bgctrl->setControl(blue);
0591     if (red != green || red != blue) {
0592         gctrl->suspend();
0593     }
0594 }
0595 
0596 int KGamma::buttons()
0597 {
0598     return Default | Apply | Help;
0599 }
0600 
0601 QString KGamma::quickHelp() const
0602 {
0603     return i18n(
0604         "<h1>Monitor Gamma</h1> This is a tool for changing monitor gamma"
0605         " correction. Use the four sliders to define the gamma correction either"
0606         " as a single value, or separately for the red, green and blue components."
0607         " You may need to correct the brightness and contrast settings of your"
0608         " monitor for good results. The test images help you to find proper"
0609         " settings.<br> You can save them system-wide to XF86Config (root access"
0610         " is required for that) or to your own KDE settings. On multi head"
0611         " systems you can correct the gamma values separately for all screens.");
0612 }
0613 
0614 // ------------------------------------------------------------------------
0615 
0616 extern "C" {
0617 // Restore the user gamma settings
0618 Q_DECL_EXPORT void kcminit()
0619 {
0620     bool ok;
0621     XVidExtWrap xv(&ok);
0622 
0623     if (ok) {
0624         xv.setGammaLimits(0.4, 3.5);
0625         float rgamma, ggamma, bgamma;
0626         KConfig *config = new KConfig(QStringLiteral("kgammarc"));
0627 
0628         for (int i = 0; i < xv._ScreenCount(); i++) {
0629             xv.setScreen(i);
0630             KConfigGroup screenGroup = config->group(QStringLiteral("Screen %1").arg(i));
0631 
0632             if ((rgamma = screenGroup.readEntry("rgamma").toFloat())) {
0633                 xv.setGamma(XVidExtWrap::Red, rgamma);
0634             }
0635             if ((ggamma = screenGroup.readEntry("ggamma").toFloat())) {
0636                 xv.setGamma(XVidExtWrap::Green, ggamma);
0637             }
0638             if ((bgamma = screenGroup.readEntry("bgamma").toFloat())) {
0639                 xv.setGamma(XVidExtWrap::Blue, bgamma);
0640             }
0641         }
0642         delete config;
0643     }
0644 }
0645 }
0646 
0647 #include "kgamma.moc"