File indexing completed on 2025-03-09 04:06:53

0001 /*
0002  *  SPDX-FileCopyrightText: 2019 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "KisDlgCustomTabletResolution.h"
0008 #include "ui_KisDlgCustomTabletResolution.h"
0009 
0010 #include <QSettings>
0011 #include "kis_debug.h"
0012 
0013 #include <QGuiApplication>
0014 #include <QScreen>
0015 #include <QStandardPaths>
0016 #include <qpa/qplatformscreen.h>
0017 
0018 #include <kstandardguiitem.h>
0019 
0020 namespace {
0021 QString rectToString(const QRect &rc) {
0022     return QString("%1, %2 %3 x %4")
0023             .arg(rc.x())
0024             .arg(rc.y())
0025             .arg(rc.width())
0026             .arg(rc.height());
0027 }
0028 }
0029 
0030 KisDlgCustomTabletResolution::KisDlgCustomTabletResolution(QWidget *parent) :
0031     QDialog(parent),
0032     ui(new Ui::KisDlgCustomTabletResolution)
0033 {
0034     ui->setupUi(this);
0035     KGuiItem::assign(ui->btnBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
0036     KGuiItem::assign(ui->btnBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
0037     connect(ui->btnBox, SIGNAL(rejected()), this, SLOT(reject()));
0038     connect(ui->btnBox, SIGNAL(accepted()), this, SLOT(accept()));
0039 
0040     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->lblXOffset, SLOT(setEnabled(bool)));
0041     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->lblYOffset, SLOT(setEnabled(bool)));
0042     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->lblWidth, SLOT(setEnabled(bool)));
0043     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->lblHeight, SLOT(setEnabled(bool)));
0044 
0045     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->intXOffset, SLOT(setEnabled(bool)));
0046     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->intYOffset, SLOT(setEnabled(bool)));
0047     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->intWidth, SLOT(setEnabled(bool)));
0048     connect(ui->radioCustomMapping, SIGNAL(toggled(bool)), ui->intHeight, SLOT(setEnabled(bool)));
0049 
0050     const QRect virtualScreenRect = calcNativeScreenRect();
0051 
0052     ui->radioMapToEntireScreen->setText(i18nc("@option:radio", "Map to entire virtual screen (%1)", rectToString(virtualScreenRect)));
0053 
0054     QRect nativeScreenRect;
0055     QPlatformScreen *screen = qGuiApp->primaryScreen()->handle();
0056     Q_FOREACH (QPlatformScreen *scr, screen->virtualSiblings()) {
0057         nativeScreenRect |= scr->geometry();
0058     }
0059 
0060     QRect customScreenRect = virtualScreenRect;
0061     Mode mode = getTabletMode(&customScreenRect);
0062 
0063     if (mode == USE_CUSTOM) {
0064         ui->radioCustomMapping->setChecked(true);
0065     } else if (mode == USE_VIRTUAL_SCREEN) {
0066         ui->radioMapToEntireScreen->setChecked(true);
0067     } else {
0068         ui->radioMapAsWintab->setChecked(true);
0069     }
0070 
0071     ui->intXOffset->setValue(customScreenRect.x());
0072     ui->intYOffset->setValue(customScreenRect.y());
0073     ui->intWidth->setValue(customScreenRect.width());
0074     ui->intHeight->setValue(customScreenRect.height());
0075 }
0076 
0077 void KisDlgCustomTabletResolution::accept()
0078 {
0079     const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
0080     QSettings cfg(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
0081 
0082     if (ui->radioMapAsWintab->isChecked()) {
0083         cfg.setValue("wintabResolutionMode", "wintab");
0084     } else if (ui->radioMapToEntireScreen->isChecked()) {
0085         cfg.setValue("wintabResolutionMode", "virtual-screen");
0086     } else if (ui->radioCustomMapping->isChecked()) {
0087         cfg.setValue("wintabResolutionMode", "custom");
0088 
0089         cfg.setValue("wintabCustomResolutionX", ui->intXOffset->value());
0090         cfg.setValue("wintabCustomResolutionY", ui->intYOffset->value());
0091         cfg.setValue("wintabCustomResolutionWidth", ui->intWidth->value());
0092         cfg.setValue("wintabCustomResolutionHeight", ui->intHeight->value());
0093     }
0094 
0095     // apply the mode right now
0096     {
0097         QRect customTabletRect;
0098         const Mode tabletMode = getTabletMode(&customTabletRect);
0099         applyConfiguration(tabletMode, customTabletRect);
0100     }
0101 
0102     QDialog::accept();
0103 }
0104 
0105 KisDlgCustomTabletResolution::~KisDlgCustomTabletResolution()
0106 {
0107     delete ui;
0108 }
0109 
0110 QRect KisDlgCustomTabletResolution::calcNativeScreenRect()
0111 {
0112     QRect nativeScreenRect;
0113     QPlatformScreen *screen = qGuiApp->primaryScreen()->handle();
0114     Q_FOREACH (QPlatformScreen *scr, screen->virtualSiblings()) {
0115         nativeScreenRect |= scr->geometry();
0116     }
0117     return nativeScreenRect;
0118 }
0119 
0120 KisDlgCustomTabletResolution::Mode KisDlgCustomTabletResolution::getTabletMode(QRect *customRect)
0121 {
0122     const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
0123     QSettings cfg(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
0124 
0125     const QString mode = cfg.value("wintabResolutionMode", QString("wintab")).toString();
0126     Mode modeValue = USE_WINTAB;
0127 
0128     if (mode == "custom") {
0129         modeValue = USE_CUSTOM;
0130     } else if (mode == "virtual-screen") {
0131         modeValue = USE_VIRTUAL_SCREEN;
0132     } else {
0133         modeValue = USE_WINTAB;
0134     }
0135 
0136     if (mode == "custom") {
0137         customRect->setX(cfg.value("wintabCustomResolutionX", customRect->x()).toInt());
0138         customRect->setY(cfg.value("wintabCustomResolutionY", customRect->y()).toInt());
0139         customRect->setWidth(cfg.value("wintabCustomResolutionWidth", customRect->width()).toInt());
0140         customRect->setHeight(cfg.value("wintabCustomResolutionHeight", customRect->height()).toInt());
0141     }
0142 
0143     return modeValue;
0144 }
0145 
0146 void KisDlgCustomTabletResolution::applyConfiguration(KisDlgCustomTabletResolution::Mode tabletMode, const QRect &customTabletRect)
0147 {
0148     if (tabletMode == KisDlgCustomTabletResolution::USE_CUSTOM) {
0149         qputenv("QT_WINTAB_DESKTOP_RECT",
0150                 QString("%1;%2;%3;%4")
0151                 .arg(customTabletRect.x())
0152                 .arg(customTabletRect.y())
0153                 .arg(customTabletRect.width())
0154                 .arg(customTabletRect.height()).toLatin1());
0155         qunsetenv("QT_IGNORE_WINTAB_MAPPING");
0156     } else if (tabletMode == KisDlgCustomTabletResolution::USE_VIRTUAL_SCREEN) {
0157         qputenv("QT_IGNORE_WINTAB_MAPPING", "1");
0158         qunsetenv("QT_WINTAB_DESKTOP_RECT");
0159     } else {
0160         qunsetenv("QT_WINTAB_DESKTOP_RECT");
0161         qunsetenv("QT_IGNORE_WINTAB_MAPPING");
0162     }
0163 }