summaryrefslogtreecommitdiffstats
path: root/kcontrol/randr
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit4aed2c8219774f5d797760606b8489a92ddc5163 (patch)
tree3f8c130f7d269626bf6a9447407ef6c35954426a /kcontrol/randr
downloadtdebase-4aed2c8219774f5d797760606b8489a92ddc5163.tar.gz
tdebase-4aed2c8219774f5d797760606b8489a92ddc5163.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kcontrol/randr')
-rw-r--r--kcontrol/randr/Makefile.am36
-rw-r--r--kcontrol/randr/TODO14
-rw-r--r--kcontrol/randr/configure.in.in18
-rw-r--r--kcontrol/randr/krandrapp.cpp40
-rw-r--r--kcontrol/randr/krandrapp.h39
-rw-r--r--kcontrol/randr/krandrinithack.cpp0
-rw-r--r--kcontrol/randr/krandrmodule.cpp364
-rw-r--r--kcontrol/randr/krandrmodule.h68
-rw-r--r--kcontrol/randr/krandrpassivepopup.cpp118
-rw-r--r--kcontrol/randr/krandrpassivepopup.h47
-rw-r--r--kcontrol/randr/krandrtray.cpp253
-rw-r--r--kcontrol/randr/krandrtray.desktop141
-rw-r--r--kcontrol/randr/krandrtray.h60
-rw-r--r--kcontrol/randr/ktimerdialog.cpp205
-rw-r--r--kcontrol/randr/ktimerdialog.h170
-rw-r--r--kcontrol/randr/main.cpp51
-rw-r--r--kcontrol/randr/randr.cpp703
-rw-r--r--kcontrol/randr/randr.desktop216
-rw-r--r--kcontrol/randr/randr.h235
19 files changed, 2778 insertions, 0 deletions
diff --git a/kcontrol/randr/Makefile.am b/kcontrol/randr/Makefile.am
new file mode 100644
index 000000000..6707a380d
--- /dev/null
+++ b/kcontrol/randr/Makefile.am
@@ -0,0 +1,36 @@
+AM_CPPFLAGS = $(all_includes)
+
+lib_LTLIBRARIES =
+kde_module_LTLIBRARIES = kcm_randr.la
+
+noinst_LTLIBRARIES = librandrinternal.la
+
+librandrinternal_la_SOURCES = ktimerdialog.cpp randr.cpp
+METASOURCES = AUTO
+
+kcm_randr_la_SOURCES = krandrmodule.cpp
+kcm_randr_la_LDFLAGS = -module -avoid-version $(all_libraries) -no-undefined
+kcm_randr_la_LIBADD = librandrinternal.la $(LIB_KDEUI) $(LIB_XRANDR)
+
+noinst_HEADERS = randr.h krandrmodule.h krandrtray.h krandrapp.h ktimerdialog.h \
+ krandrpassivepopup.h
+
+xdg_apps_DATA = krandrtray.desktop
+
+krandr_data_DATA = randr.desktop
+krandr_datadir = $(kde_appsdir)/.hidden
+
+
+#install-data-local: uninstall.desktop
+# $(mkinstalldirs) $(DESTDIR)$(kde_appsdir)/Settings/Desktop
+# $(INSTALL_DATA) $(srcdir)/uninstall.desktop
+# $(DESTDIR)$(kde_appsdir)/Settings/Desktop/krandrmodule.desktop
+
+bin_PROGRAMS = krandrtray
+
+krandrtray_SOURCES = main.cpp krandrtray.cpp krandrapp.cpp krandrpassivepopup.cpp
+krandrtray_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+krandrtray_LDADD = librandrinternal.la $(LIB_KFILE) $(LIB_KUTILS) $(LIB_XRANDR)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/krandr.pot
diff --git a/kcontrol/randr/TODO b/kcontrol/randr/TODO
new file mode 100644
index 000000000..1b7e03c3b
--- /dev/null
+++ b/kcontrol/randr/TODO
@@ -0,0 +1,14 @@
+Remaining known issues
+
+General
+ Not tested with multiple screens (but should support them)
+
+Qt
+ Font sizes on newly started apps after a resolution change are incorrect
+ This doesn't appear to happen with non-Xft font rendering, Xft/Qt interaction?
+
+Kwin
+ Support different sized virtual desktops
+
+RandR programs
+ Support configuring different sized virtual desktops
diff --git a/kcontrol/randr/configure.in.in b/kcontrol/randr/configure.in.in
new file mode 100644
index 000000000..24a978198
--- /dev/null
+++ b/kcontrol/randr/configure.in.in
@@ -0,0 +1,18 @@
+dnl -----------------------------------------------------
+dnl X Resize and Rotate extension library check
+dnl -----------------------------------------------------
+
+KDE_CHECK_HEADERS(X11/extensions/Xrandr.h, [xrandr_h=yes], [xrandr_h=no], [#include <X11/Xlib.h>])
+if test "$xrandr_h" = yes; then
+ KDE_CHECK_LIB(Xrandr, XRRSetScreenConfigAndRate, [
+ LIB_XRANDR=-lXrandr
+ AC_DEFINE_UNQUOTED(XRANDR_SUPPORT, 1, [Defined if your system has XRandR support])
+ RANDR_SUBDIR="randr"
+ ], [
+ RANDR_SUBDIR=""
+ ], -lXrender -lXext $X_EXTRA_LIBS)
+else
+ LIB_XRANDR=
+fi
+AC_SUBST(LIB_XRANDR)
+AM_CONDITIONAL(include_kcontrol_randr, test -n "$RANDR_SUBDIR")
diff --git a/kcontrol/randr/krandrapp.cpp b/kcontrol/randr/krandrapp.cpp
new file mode 100644
index 000000000..2d773dd22
--- /dev/null
+++ b/kcontrol/randr/krandrapp.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <kdebug.h>
+
+#include "krandrapp.h"
+#include "krandrapp.moc"
+
+#include "krandrtray.h"
+
+#include <X11/Xlib.h>
+
+KRandRApp::KRandRApp()
+ : m_tray(new KRandRSystemTray(0L, "RANDRTray"))
+{
+ m_tray->show();
+}
+
+bool KRandRApp::x11EventFilter(XEvent* e)
+{
+ if (e->type == m_tray->screenChangeNotifyEvent()) {
+ m_tray->configChanged();
+ }
+ return KApplication::x11EventFilter( e );
+}
diff --git a/kcontrol/randr/krandrapp.h b/kcontrol/randr/krandrapp.h
new file mode 100644
index 000000000..3b8895fc8
--- /dev/null
+++ b/kcontrol/randr/krandrapp.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2002 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KRANDRAPP_H
+#define KRANDRAPP_H
+
+#include <kuniqueapplication.h>
+
+class KRandRSystemTray;
+
+class KRandRApp : public KUniqueApplication
+{
+ Q_OBJECT
+
+public:
+ KRandRApp();
+
+ virtual bool x11EventFilter(XEvent * e);
+
+private:
+ KRandRSystemTray* m_tray;
+};
+
+#endif
diff --git a/kcontrol/randr/krandrinithack.cpp b/kcontrol/randr/krandrinithack.cpp
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/kcontrol/randr/krandrinithack.cpp
diff --git a/kcontrol/randr/krandrmodule.cpp b/kcontrol/randr/krandrmodule.cpp
new file mode 100644
index 000000000..d1d7ec73f
--- /dev/null
+++ b/kcontrol/randr/krandrmodule.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qdesktopwidget.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qradiobutton.h>
+#include <qvbox.h>
+#include <qvbuttongroup.h>
+#include <qwhatsthis.h>
+
+#include <kcmodule.h>
+#include <kcombobox.h>
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kgenericfactory.h>
+#include <kglobal.h>
+#include <klocale.h>
+
+#include "krandrmodule.h"
+#include "krandrmodule.moc"
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+
+// DLL Interface for kcontrol
+typedef KGenericFactory<KRandRModule, QWidget > KSSFactory;
+K_EXPORT_COMPONENT_FACTORY (kcm_randr, KSSFactory("krandr") )
+extern "C"
+
+{
+ KDE_EXPORT void init_randr()
+ {
+ KRandRModule::performApplyOnStartup();
+ }
+
+ KDE_EXPORT bool test_randr()
+ {
+ int eventBase, errorBase;
+ if( XRRQueryExtension(qt_xdisplay(), &eventBase, &errorBase ) )
+ return true;
+ return false;
+ }
+}
+
+void KRandRModule::performApplyOnStartup()
+{
+ KConfig config("kcmrandrrc", true);
+ if (RandRDisplay::applyOnStartup(config))
+ {
+ // Load settings and apply appropriate config
+ RandRDisplay display;
+ if (display.isValid() && display.loadDisplay(config))
+ display.applyProposed(false);
+ }
+}
+
+KRandRModule::KRandRModule(QWidget *parent, const char *name, const QStringList&)
+ : KCModule(parent, name)
+ , m_changed(false)
+{
+ if (!isValid()) {
+ QVBoxLayout *topLayout = new QVBoxLayout(this);
+ topLayout->addWidget(new QLabel(i18n("<qt>Your X server does not support resizing and rotating the display. Please update to version 4.3 or greater. You need the X Resize And Rotate extension (RANDR) version 1.1 or greater to use this feature.</qt>"), this));
+ kdWarning() << "Error: " << errorCode() << endl;
+ return;
+ }
+
+ QVBoxLayout* topLayout = new QVBoxLayout(this, 0, KDialog::spacingHint());
+
+ QHBox* screenBox = new QHBox(this);
+ topLayout->addWidget(screenBox);
+ QLabel *screenLabel = new QLabel(i18n("Settings for screen:"), screenBox);
+ m_screenSelector = new KComboBox(screenBox);
+
+ for (int s = 0; s < numScreens(); s++) {
+ m_screenSelector->insertItem(i18n("Screen %1").arg(s+1));
+ }
+
+ m_screenSelector->setCurrentItem(currentScreenIndex());
+ screenLabel->setBuddy( m_screenSelector );
+ QWhatsThis::add(m_screenSelector, i18n("The screen whose settings you would like to change can be selected using this drop-down list."));
+
+ connect(m_screenSelector, SIGNAL(activated(int)), SLOT(slotScreenChanged(int)));
+
+ if (numScreens() <= 1)
+ m_screenSelector->setEnabled(false);
+
+ QHBox* sizeBox = new QHBox(this);
+ topLayout->addWidget(sizeBox);
+ QLabel *sizeLabel = new QLabel(i18n("Screen size:"), sizeBox);
+ m_sizeCombo = new KComboBox(sizeBox);
+ QWhatsThis::add(m_sizeCombo, i18n("The size, otherwise known as the resolution, of your screen can be selected from this drop-down list."));
+ connect(m_sizeCombo, SIGNAL(activated(int)), SLOT(slotSizeChanged(int)));
+ sizeLabel->setBuddy( m_sizeCombo );
+
+ QHBox* refreshBox = new QHBox(this);
+ topLayout->addWidget(refreshBox);
+ QLabel *rateLabel = new QLabel(i18n("Refresh rate:"), refreshBox);
+ m_refreshRates = new KComboBox(refreshBox);
+ QWhatsThis::add(m_refreshRates, i18n("The refresh rate of your screen can be selected from this drop-down list."));
+ connect(m_refreshRates, SIGNAL(activated(int)), SLOT(slotRefreshChanged(int)));
+ rateLabel->setBuddy( m_refreshRates );
+
+ m_rotationGroup = new QButtonGroup(2, Qt::Horizontal, i18n("Orientation (degrees counterclockwise)"), this);
+ topLayout->addWidget(m_rotationGroup);
+ m_rotationGroup->setRadioButtonExclusive(true);
+ QWhatsThis::add(m_rotationGroup, i18n("The options in this section allow you to change the rotation of your screen."));
+
+ m_applyOnStartup = new QCheckBox(i18n("Apply settings on KDE startup"), this);
+ topLayout->addWidget(m_applyOnStartup);
+ QWhatsThis::add(m_applyOnStartup, i18n("If this option is enabled the size and orientation settings will be used when KDE starts."));
+ connect(m_applyOnStartup, SIGNAL(clicked()), SLOT(setChanged()));
+
+ QHBox* syncBox = new QHBox(this);
+ syncBox->layout()->addItem(new QSpacerItem(20, 1, QSizePolicy::Maximum));
+ m_syncTrayApp = new QCheckBox(i18n("Allow tray application to change startup settings"), syncBox);
+ topLayout->addWidget(syncBox);
+ QWhatsThis::add(m_syncTrayApp, i18n("If this option is enabled, options set by the system tray applet will be saved and loaded when KDE starts instead of being temporary."));
+ connect(m_syncTrayApp, SIGNAL(clicked()), SLOT(setChanged()));
+
+ topLayout->addStretch(1);
+
+ // just set the "apply settings on startup" box
+ load();
+ m_syncTrayApp->setEnabled(m_applyOnStartup->isChecked());
+
+ slotScreenChanged(QApplication::desktop()->primaryScreen());
+
+ setButtons(KCModule::Apply);
+}
+
+void KRandRModule::addRotationButton(int thisRotation, bool checkbox)
+{
+ Q_ASSERT(m_rotationGroup);
+ if (!checkbox) {
+ QRadioButton* thisButton = new QRadioButton(RandRScreen::rotationName(thisRotation), m_rotationGroup);
+ thisButton->setEnabled(thisRotation & currentScreen()->rotations());
+ connect(thisButton, SIGNAL(clicked()), SLOT(slotRotationChanged()));
+ } else {
+ QCheckBox* thisButton = new QCheckBox(RandRScreen::rotationName(thisRotation), m_rotationGroup);
+ thisButton->setEnabled(thisRotation & currentScreen()->rotations());
+ connect(thisButton, SIGNAL(clicked()), SLOT(slotRotationChanged()));
+ }
+}
+
+void KRandRModule::slotScreenChanged(int screen)
+{
+ setCurrentScreen(screen);
+
+ // Clear resolutions
+ m_sizeCombo->clear();
+
+ // Add new resolutions
+ for (int i = 0; i < currentScreen()->numSizes(); i++) {
+ m_sizeCombo->insertItem(i18n("%1 x %2").arg(currentScreen()->pixelSize(i).width()).arg(currentScreen()->pixelSize(i).height()));
+
+ // Aspect ratio
+ /* , aspect ratio %5)*/
+ /*.arg((double)currentScreen()->size(i).mwidth / (double)currentScreen()->size(i).mheight))*/
+ }
+
+ // Clear rotations
+ for (int i = m_rotationGroup->count() - 1; i >= 0; i--)
+ m_rotationGroup->remove(m_rotationGroup->find(i));
+
+ // Create rotations
+ for (int i = 0; i < RandRScreen::OrientationCount; i++)
+ addRotationButton(1 << i, i > RandRScreen::RotationCount - 1);
+
+ populateRefreshRates();
+
+ update();
+
+ setChanged();
+}
+
+void KRandRModule::slotRotationChanged()
+{
+ if (m_rotationGroup->find(0)->isOn())
+ currentScreen()->proposeRotation(RandRScreen::Rotate0);
+ else if (m_rotationGroup->find(1)->isOn())
+ currentScreen()->proposeRotation(RandRScreen::Rotate90);
+ else if (m_rotationGroup->find(2)->isOn())
+ currentScreen()->proposeRotation(RandRScreen::Rotate180);
+ else {
+ Q_ASSERT(m_rotationGroup->find(3)->isOn());
+ currentScreen()->proposeRotation(RandRScreen::Rotate270);
+ }
+
+ if (m_rotationGroup->find(4)->isOn())
+ currentScreen()->proposeRotation(currentScreen()->proposedRotation() ^ RandRScreen::ReflectX);
+
+ if (m_rotationGroup->find(5)->isOn())
+ currentScreen()->proposeRotation(currentScreen()->proposedRotation() ^ RandRScreen::ReflectY);
+
+ setChanged();
+}
+
+void KRandRModule::slotSizeChanged(int index)
+{
+ int oldProposed = currentScreen()->proposedSize();
+
+ currentScreen()->proposeSize(index);
+
+ if (currentScreen()->proposedSize() != oldProposed) {
+ currentScreen()->proposeRefreshRate(0);
+
+ populateRefreshRates();
+
+ // Item with index zero is already selected
+ }
+
+ setChanged();
+}
+
+void KRandRModule::slotRefreshChanged(int index)
+{
+ currentScreen()->proposeRefreshRate(index);
+
+ setChanged();
+}
+
+void KRandRModule::populateRefreshRates()
+{
+ m_refreshRates->clear();
+
+ QStringList rr = currentScreen()->refreshRates(currentScreen()->proposedSize());
+
+ m_refreshRates->setEnabled(rr.count());
+
+ for (QStringList::Iterator it = rr.begin(); it != rr.end(); ++it)
+ m_refreshRates->insertItem(*it);
+}
+
+
+void KRandRModule::defaults()
+{
+ load( true );
+}
+
+void KRandRModule::load()
+{
+ load( false );
+}
+
+void KRandRModule::load( bool useDefaults )
+{
+ if (!isValid())
+ return;
+
+ // Don't load screen configurations:
+ // It will be correct already if they wanted to retain their settings over KDE restarts,
+ // and if it isn't correct they have changed a) their X configuration, b) the screen
+ // with another program, or c) their hardware.
+ KConfig config("kcmrandrrc", true);
+
+ config.setReadDefaults( useDefaults );
+
+ m_oldApply = loadDisplay(config, false);
+ m_oldSyncTrayApp = syncTrayApp(config);
+
+ m_applyOnStartup->setChecked(m_oldApply);
+ m_syncTrayApp->setChecked(m_oldSyncTrayApp);
+
+ emit changed( useDefaults );
+}
+
+void KRandRModule::save()
+{
+ if (!isValid())
+ return;
+
+ apply();
+
+ m_oldApply = m_applyOnStartup->isChecked();
+ m_oldSyncTrayApp = m_syncTrayApp->isChecked();
+ KConfig config("kcmrandrrc");
+ saveDisplay(config, m_oldApply, m_oldSyncTrayApp);
+
+ setChanged();
+}
+
+void KRandRModule::setChanged()
+{
+ bool isChanged = (m_oldApply != m_applyOnStartup->isChecked()) || (m_oldSyncTrayApp != m_syncTrayApp->isChecked());
+ m_syncTrayApp->setEnabled(m_applyOnStartup->isChecked());
+
+ if (!isChanged)
+ for (int screenIndex = 0; screenIndex < numScreens(); screenIndex++) {
+ if (screen(screenIndex)->proposedChanged()) {
+ isChanged = true;
+ break;
+ }
+ }
+
+ if (isChanged != m_changed) {
+ m_changed = isChanged;
+ emit changed(m_changed);
+ }
+}
+
+void KRandRModule::apply()
+{
+ if (m_changed) {
+ applyProposed();
+
+ update();
+ }
+}
+
+
+void KRandRModule::update()
+{
+ m_sizeCombo->blockSignals(true);
+ m_sizeCombo->setCurrentItem(currentScreen()->proposedSize());
+ m_sizeCombo->blockSignals(false);
+
+ m_rotationGroup->blockSignals(true);
+ switch (currentScreen()->proposedRotation() & RandRScreen::RotateMask) {
+ case RandRScreen::Rotate0:
+ m_rotationGroup->setButton(0);
+ break;
+ case RandRScreen::Rotate90:
+ m_rotationGroup->setButton(1);
+ break;
+ case RandRScreen::Rotate180:
+ m_rotationGroup->setButton(2);
+ break;
+ case RandRScreen::Rotate270:
+ m_rotationGroup->setButton(3);
+ break;
+ default:
+ // Shouldn't hit this one
+ Q_ASSERT(currentScreen()->proposedRotation() & RandRScreen::RotateMask);
+ break;
+ }
+ m_rotationGroup->find(4)->setDown(currentScreen()->proposedRotation() & RandRScreen::ReflectX);
+ m_rotationGroup->find(5)->setDown(currentScreen()->proposedRotation() & RandRScreen::ReflectY);
+ m_rotationGroup->blockSignals(false);
+
+ m_refreshRates->blockSignals(true);
+ m_refreshRates->setCurrentItem(currentScreen()->proposedRefreshRate());
+ m_refreshRates->blockSignals(false);
+}
+
diff --git a/kcontrol/randr/krandrmodule.h b/kcontrol/randr/krandrmodule.h
new file mode 100644
index 000000000..cd50f05d5
--- /dev/null
+++ b/kcontrol/randr/krandrmodule.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2002 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KRANDRMODULE_H
+#define KRANDRMODULE_H
+
+#include "randr.h"
+
+class QButtonGroup;
+class KComboBox;
+class QCheckBox;
+
+class KRandRModule : public KCModule, public RandRDisplay
+{
+ Q_OBJECT
+
+public:
+ KRandRModule(QWidget *parent, const char *name, const QStringList& _args);
+
+ virtual void load();
+ virtual void load(bool useDefaults);
+ virtual void save();
+ virtual void defaults();
+
+ static void performApplyOnStartup();
+
+protected slots:
+ void slotScreenChanged(int screen);
+ void slotRotationChanged();
+ void slotSizeChanged(int index);
+ void slotRefreshChanged(int index);
+ void setChanged();
+
+protected:
+ void apply();
+ void update();
+
+ void addRotationButton(int thisRotation, bool checkbox);
+ void populateRefreshRates();
+
+ KComboBox* m_screenSelector;
+ KComboBox* m_sizeCombo;
+ QButtonGroup* m_rotationGroup;
+ KComboBox* m_refreshRates;
+ QCheckBox* m_applyOnStartup;
+ QCheckBox* m_syncTrayApp;
+ bool m_oldApply;
+ bool m_oldSyncTrayApp;
+
+ bool m_changed;
+};
+
+#endif
diff --git a/kcontrol/randr/krandrpassivepopup.cpp b/kcontrol/randr/krandrpassivepopup.cpp
new file mode 100644
index 000000000..858014014
--- /dev/null
+++ b/kcontrol/randr/krandrpassivepopup.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2003 Lubos Lunak <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "krandrpassivepopup.h"
+
+#include <kapplication.h>
+
+// this class is just like KPassivePopup, but it keeps track of the widget
+// it's supposed to be positioned next to, and adjust its position if that
+// widgets moves (needed because after a resolution switch Kicker will
+// reposition itself, causing normal KPassivePopup to stay at weird places)
+
+KRandrPassivePopup::KRandrPassivePopup( QWidget *parent, const char *name, WFlags f )
+ : KPassivePopup( parent, name, f )
+ {
+ connect( &update_timer, SIGNAL( timeout()), SLOT( slotPositionSelf()));
+ }
+
+KRandrPassivePopup* KRandrPassivePopup::message( const QString &caption, const QString &text,
+ const QPixmap &icon, QWidget *parent, const char *name, int timeout )
+ {
+ KRandrPassivePopup *pop = new KRandrPassivePopup( parent, name );
+ pop->setAutoDelete( true );
+ pop->setView( caption, text, icon );
+ pop->setTimeout( timeout );
+ pop->show();
+ pop->startWatchingWidget( parent );
+ return pop;
+ }
+
+void KRandrPassivePopup::startWatchingWidget( QWidget* widget_P )
+ {
+ static Atom wm_state = XInternAtom( qt_xdisplay() , "WM_STATE", False );
+ Window win = widget_P->winId();
+ bool x11_events = false;
+ for(;;)
+ {
+ Window root, parent;
+ Window* children;
+ unsigned int nchildren;
+ XQueryTree( qt_xdisplay(), win, &root, &parent, &children, &nchildren );
+ if( children != NULL )
+ XFree( children );
+ if( win == root ) // huh?
+ break;
+ win = parent;
+
+ QWidget* widget = QWidget::find( win );
+ if( widget != NULL )
+ {
+ widget->installEventFilter( this );
+ watched_widgets.append( widget );
+ }
+ else
+ {
+ XWindowAttributes attrs;
+ XGetWindowAttributes( qt_xdisplay(), win, &attrs );
+ XSelectInput( qt_xdisplay(), win, attrs.your_event_mask | StructureNotifyMask );
+ watched_windows.append( win );
+ x11_events = true;
+ }
+ Atom type;
+ int format;
+ unsigned long nitems, after;
+ unsigned char* data;
+ if( XGetWindowProperty( qt_xdisplay(), win, wm_state, 0, 0, False, AnyPropertyType,
+ &type, &format, &nitems, &after, &data ) == Success )
+ {
+ if( data != NULL )
+ XFree( data );
+ if( type != None ) // toplevel window
+ break;
+ }
+ }
+ if( x11_events )
+ kapp->installX11EventFilter( this );
+ }
+
+bool KRandrPassivePopup::eventFilter( QObject* o, QEvent* e )
+ {
+ if( e->type() == QEvent::Move && o->isWidgetType()
+ && watched_widgets.contains( static_cast< QWidget* >( o )))
+ QTimer::singleShot( 0, this, SLOT( slotPositionSelf()));
+ return false;
+ }
+
+bool KRandrPassivePopup::x11Event( XEvent* e )
+ {
+ if( e->type == ConfigureNotify && watched_windows.contains( e->xconfigure.window ))
+ {
+ if( !update_timer.isActive())
+ update_timer.start( 10, true );
+ return false;
+ }
+ return KPassivePopup::x11Event( e );
+ }
+
+void KRandrPassivePopup::slotPositionSelf()
+ {
+ positionSelf();
+ }
+
+#include "krandrpassivepopup.moc"
diff --git a/kcontrol/randr/krandrpassivepopup.h b/kcontrol/randr/krandrpassivepopup.h
new file mode 100644
index 000000000..6e86c336c
--- /dev/null
+++ b/kcontrol/randr/krandrpassivepopup.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2003 Lubos Lunak <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __RANDRPASSIVEPOPUP_H__
+#define __RANDRPASSIVEPOPUP_H__
+
+#include <kpassivepopup.h>
+#include <qvaluelist.h>
+#include <qtimer.h>
+#include <X11/Xlib.h>
+
+class KRandrPassivePopup
+ : public KPassivePopup
+ {
+ Q_OBJECT
+ public:
+ static KRandrPassivePopup *message( const QString &caption, const QString &text,
+ const QPixmap &icon, QWidget *parent, const char *name=0, int timeout = -1 );
+ protected:
+ virtual bool eventFilter( QObject* o, QEvent* e );
+ virtual bool x11Event( XEvent* e );
+ private slots:
+ void slotPositionSelf();
+ private:
+ KRandrPassivePopup( QWidget *parent=0, const char *name=0, WFlags f=0 );
+ void startWatchingWidget( QWidget* w );
+ QValueList< QWidget* > watched_widgets;
+ QValueList< Window > watched_windows;
+ QTimer update_timer;
+ };
+
+#endif
diff --git a/kcontrol/randr/krandrtray.cpp b/kcontrol/randr/krandrtray.cpp
new file mode 100644
index 000000000..8e80c7cc6
--- /dev/null
+++ b/kcontrol/randr/krandrtray.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qtimer.h>
+#include <qtooltip.h>
+
+#include <kaction.h>
+#include <kapplication.h>
+#include <kcmultidialog.h>
+#include <kdebug.h>
+#include <khelpmenu.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <kstdaction.h>
+#include <kstdguiitem.h>
+
+#include "krandrtray.h"
+#include "krandrpassivepopup.h"
+#include "krandrtray.moc"
+
+KRandRSystemTray::KRandRSystemTray(QWidget* parent, const char *name)
+ : KSystemTray(parent, name)
+ , m_popupUp(false)
+ , m_help(new KHelpMenu(this, KGlobal::instance()->aboutData(), false, actionCollection()))
+{
+ setPixmap(KSystemTray::loadIcon("randr"));
+ setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ connect(this, SIGNAL(quitSelected()), kapp, SLOT(quit()));
+ QToolTip::add(this, i18n("Screen resize & rotate"));
+}
+
+void KRandRSystemTray::mousePressEvent(QMouseEvent* e)
+{
+ // Popup the context menu with left-click
+ if (e->button() == LeftButton) {
+ contextMenuAboutToShow(contextMenu());
+ contextMenu()->popup(e->globalPos());
+ e->accept();
+ return;
+ }
+
+ KSystemTray::mousePressEvent(e);
+}
+
+void KRandRSystemTray::contextMenuAboutToShow(KPopupMenu* menu)
+{
+ int lastIndex = 0;
+
+ menu->clear();
+ menu->setCheckable(true);
+
+ if (!isValid()) {
+ lastIndex = menu->insertItem(i18n("Required X Extension Not Available"));
+ menu->setItemEnabled(lastIndex, false);
+
+ } else {
+ m_screenPopups.clear();
+ for (int s = 0; s < numScreens() /*&& numScreens() > 1 */; s++) {
+ setCurrentScreen(s);
+ if (s == screenIndexOfWidget(this)) {
+ /*lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1));
+ menu->setItemEnabled(lastIndex, false);*/
+ } else {
+ KPopupMenu* subMenu = new KPopupMenu(menu, QString("screen%1").arg(s+1).latin1());
+ m_screenPopups.append(subMenu);
+ populateMenu(subMenu);
+ lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1), subMenu);
+ connect(subMenu, SIGNAL(activated(int)), SLOT(slotScreenActivated()));
+ }
+ }
+
+ setCurrentScreen(screenIndexOfWidget(this));
+ populateMenu(menu);
+ }
+
+ menu->insertSeparator();
+
+ KAction *actPrefs = new KAction( i18n( "Configure Display..." ),
+ SmallIconSet( "configure" ), KShortcut(), this, SLOT( slotPrefs() ),
+ actionCollection() );
+ actPrefs->plug( menu );
+
+ menu->insertItem(SmallIcon("help"),KStdGuiItem::help().text(), m_help->menu());
+ KAction *quitAction = actionCollection()->action(KStdAction::name(KStdAction::Quit));
+ quitAction->plug(menu);
+}
+
+void KRandRSystemTray::slotScreenActivated()
+{
+ setCurrentScreen(m_screenPopups.find(static_cast<const KPopupMenu*>(sender())));
+}
+
+void KRandRSystemTray::configChanged()
+{
+ refresh();
+
+ static bool first = true;
+
+ if (!first)
+ KRandrPassivePopup::message(
+ i18n("Screen configuration has changed"),
+ currentScreen()->changedMessage(), SmallIcon("window_fullscreen"),
+ this, "ScreenChangeNotification");
+
+ first = false;
+}
+
+void KRandRSystemTray::populateMenu(KPopupMenu* menu)
+{
+ int lastIndex = 0;
+
+ menu->insertTitle(SmallIcon("window_fullscreen"), i18n("Screen Size"));
+
+ int numSizes = currentScreen()->numSizes();
+ int* sizeSort = new int[numSizes];
+
+ for (int i = 0; i < numSizes; i++) {
+ sizeSort[i] = currentScreen()->pixelCount(i);
+ }
+
+ for (int j = 0; j < numSizes; j++) {
+ int highest = -1, highestIndex = -1;
+
+ for (int i = 0; i < numSizes; i++) {
+ if (sizeSort[i] && sizeSort[i] > highest) {
+ highest = sizeSort[i];
+ highestIndex = i;
+ }
+ }
+ sizeSort[highestIndex] = -1;
+ Q_ASSERT(highestIndex != -1);
+
+ lastIndex = menu->insertItem(i18n("%1 x %2").arg(currentScreen()->pixelSize(highestIndex).width()).arg(currentScreen()->pixelSize(highestIndex).height()));
+
+ if (currentScreen()->proposedSize() == highestIndex)
+ menu->setItemChecked(lastIndex, true);
+
+ menu->setItemParameter(lastIndex, highestIndex);
+ menu->connectItem(lastIndex, this, SLOT(slotResolutionChanged(int)));
+ }
+ delete [] sizeSort;
+ sizeSort = 0L;
+
+ // Don't display the rotation options if there is no point (ie. none are supported)
+ // XFree86 4.3 does not include rotation support.
+ if (currentScreen()->rotations() != RandRScreen::Rotate0) {
+ menu->insertTitle(SmallIcon("reload"), i18n("Orientation"));
+
+ for (int i = 0; i < 6; i++) {
+ if ((1 << i) & currentScreen()->rotations()) {
+ lastIndex = menu->insertItem(currentScreen()->rotationIcon(1 << i), RandRScreen::rotationName(1 << i));
+
+ if (currentScreen()->proposedRotation() & (1 << i))
+ menu->setItemChecked(lastIndex, true);
+
+ menu->setItemParameter(lastIndex, 1 << i);
+ menu->connectItem(lastIndex, this, SLOT(slotOrientationChanged(int)));
+ }
+ }
+ }
+
+ QStringList rr = currentScreen()->refreshRates(currentScreen()->proposedSize());
+
+ if (rr.count())
+ menu->insertTitle(SmallIcon("clock"), i18n("Refresh Rate"));
+
+ int i = 0;
+ for (QStringList::Iterator it = rr.begin(); it != rr.end(); ++it, i++) {
+ lastIndex = menu->insertItem(*it);
+
+ if (currentScreen()->proposedRefreshRate() == i)
+ menu->setItemChecked(lastIndex, true);
+
+ menu->setItemParameter(lastIndex, i);
+ menu->connectItem(lastIndex, this, SLOT(slotRefreshRateChanged(int)));
+ }
+}
+
+void KRandRSystemTray::slotResolutionChanged(int parameter)
+{
+ if (currentScreen()->currentSize() == parameter)
+ return;
+
+ currentScreen()->proposeSize(parameter);
+
+ currentScreen()->proposeRefreshRate(-1);
+
+ if (currentScreen()->applyProposedAndConfirm()) {
+ KConfig config("kcmrandrrc");
+ if (syncTrayApp(config))
+ currentScreen()->save(config);
+ }
+}
+
+void KRandRSystemTray::slotOrientationChanged(int parameter)
+{
+ int propose = currentScreen()->currentRotation();
+
+ if (parameter & RandRScreen::RotateMask)
+ propose &= RandRScreen::ReflectMask;
+
+ propose ^= parameter;
+
+ if (currentScreen()->currentRotation() == propose)
+ return;
+
+ currentScreen()->proposeRotation(propose);
+
+ if (currentScreen()->applyProposedAndConfirm()) {
+ KConfig config("kcmrandrrc");
+ if (syncTrayApp(config))
+ currentScreen()->save(config);
+ }
+}
+
+void KRandRSystemTray::slotRefreshRateChanged(int parameter)
+{
+ if (currentScreen()->currentRefreshRate() == parameter)
+ return;
+
+ currentScreen()->proposeRefreshRate(parameter);
+
+ if (currentScreen()->applyProposedAndConfirm()) {
+ KConfig config("kcmrandrrc");
+ if (syncTrayApp(config))
+ currentScreen()->save(config);
+ }
+}
+
+void KRandRSystemTray::slotPrefs()
+{
+ KCMultiDialog *kcm = new KCMultiDialog( KDialogBase::Plain, i18n( "Configure" ), this );
+
+ kcm->addModule( "display" );
+ kcm->setPlainCaption( i18n( "Configure Display" ) );
+ kcm->exec();
+}
diff --git a/kcontrol/randr/krandrtray.desktop b/kcontrol/randr/krandrtray.desktop
new file mode 100644
index 000000000..7cb52a44b
--- /dev/null
+++ b/kcontrol/randr/krandrtray.desktop
@@ -0,0 +1,141 @@
+[Desktop Entry]
+Name=KRandRTray
+Name[be]=Змена параметраў манітора
+Name[hu]=Képernyőfelbontás
+Name[ne]=KRandR ट्रे
+Name[pt_BR]=Ícone do KRandR
+Name[sv]=Krandrtray
+Name[vi]=Khay KRandR
+GenericName=Screen Resize & Rotate
+GenericName[af]=Skerm Hervergroot & Roteer
+GenericName[be]=Змена памераў экрана і перагортванне
+GenericName[bg]=Размер и ротация на екрана
+GenericName[bn]=পর্দা মাপবদল ও আবর্তন
+GenericName[br]=Adventañ ha treiñ ar skramm
+GenericName[bs]=Veličina i rotacija ekrana
+GenericName[ca]=Amida i gira la pantalla
+GenericName[cs]=Změna velikosti a rotace obrazovky
+GenericName[csb]=Òbrócenié ë zjinaka miarë ekranu
+GenericName[cy]=Newid Maint a Cylchdroi'r Sgrîn
+GenericName[da]=Ændr størrelse på skærm & Rotér
+GenericName[de]=Bildschirmgröße & -ausrichtung ändern
+GenericName[el]=Αλλαγή μεγέθους & Περιστροφή οθόνης
+GenericName[eo]=Regrandigi kaj Turni Ekranon
+GenericName[es]=Redimensionar y rotar pantalla
+GenericName[et]=Ekraani suuruse muutmine ja pööramine
+GenericName[eu]=Pantailaren tamaina aldaketa eta biraketa
+GenericName[fa]=تغییر اندازه و چرخش پرده
+GenericName[fi]=Näytön kuvan koon muuttaminen ja kuvan kääntäminen
+GenericName[fr]=Redimensionnement et rotation de l'écran
+GenericName[fy]=Skerm rotearje en grutte wizigje
+GenericName[gl]=Rotación e Redimensionamento da Pantallla
+GenericName[he]=שינוי גודל המסך וסיבובו
+GenericName[hr]=Veličine i orijentacija zaslona
+GenericName[hu]=Képernyőbeállító
+GenericName[is]=Stærð og snúningur skjáa
+GenericName[it]=Ruota e ridimensiona lo schermo
+GenericName[ja]=スクリーンのリサイズと回転
+GenericName[ka]=ეკრანის ზომა და ორიენტაცია
+GenericName[kk]=Экранды өзгерту және бұрау
+GenericName[km]=ប្ដូរ​ទំហំ & បង្វិល​អេក្រង់
+GenericName[ko]=화면 크기 조정 및 회전
+GenericName[lt]=Ekrano dydžio keitimas ir pasukimas
+GenericName[mk]=Големина и ротација на екранот
+GenericName[ms]=Saiz Semula Skrin & Putar
+GenericName[nb]=Endre størrelsen på og rotere skjermbildet
+GenericName[nds]=Schirmgrött un -utrichten ännern
+GenericName[ne]=पर्दा रिसाइज र परिक्रमण
+GenericName[nl]=Scherm roteren en grootte wijzigen
+GenericName[nn]=Endra storleiken på og roter skjermbiletet
+GenericName[pa]=ਪਰਦਾ ਮੁੜ ਆਕਾਰ ਤੇ ਘੁੰਮਾਓ
+GenericName[pl]=Obrót i zmiana rozmiaru ekranu
+GenericName[pt]=Mudar o Tamanho e Rodar o Ecrã
+GenericName[pt_BR]=Redimensionar Tela & Rotacionar
+GenericName[ro]=Redimensionare și rotire ecran
+GenericName[ru]=Изменение размера и ориентации экрана
+GenericName[rw]=Kuhindura ingano & Kuzengurutsa Mugaragaza
+GenericName[se]=Rievdat šearbmagova sturrodaga ja jorat dan
+GenericName[sk]=Zmena veľkosti a otočenia obrazovky
+GenericName[sl]=Spreminjanje velikosti in obračanje zaslona
+GenericName[sr]=Промена величине и ротација екрана
+GenericName[sr@Latn]=Promena veličine i rotacija ekrana
+GenericName[sv]=Ändra skärmstorlek och rotera
+GenericName[ta]=திரை அளவு மாற்று & சுழற்று
+GenericName[tg]=Ивази андоза ва мавқеи экран
+GenericName[th]=ปรับขนาดและหมุนหน้าจอ
+GenericName[tr]=Ekran Boyutlandır ve Döndür
+GenericName[tt]=Küräk Ülçäme & Borılışı
+GenericName[uk]=Зміна розміру та обертання екрана
+GenericName[uz]=Ekraning oʻlchamini oʻzgartirish va burish
+GenericName[uz@cyrillic]=Экранинг ўлчамини ўзгартириш ва буриш
+GenericName[vi]=Thay đổi cỡ màn hình & Quay
+GenericName[wa]=Candjî l' grandeu del waitroûle eyet l' tourner
+GenericName[zh_CN]=屏幕大小和旋转
+GenericName[zh_TW]=螢幕調整大小及旋轉
+Comment=Resize and rotate X screens.
+Comment[af]=Hervergroot en roteer X skerms.
+Comment[ar]=غيير القياس و الدوران للشاشات X.
+Comment[be]=Змена памераў і перагортванне экранаў X.
+Comment[bg]=Размер и ротация на екрана.
+Comment[bn]=আপনার এক্স-স্ক্রীণ-এর আকৃতি এবং দিশা পরিবর্তন করুন
+Comment[br]=Adventañ ha treiñ ho diskweloù X.
+Comment[bs]=Podesite veličinu i rotirajte vaš ekran.
+Comment[ca]=Gira i amida les pantalles X.
+Comment[cs]=Změna velikosti a rotace obrazovky.
+Comment[csb]=Zjinaka miarë ë pòłożenia ekranów.
+Comment[da]=Ændrer størrelse og roterer X-skærme
+Comment[de]=Die Größe und Ausrichtung der Anzeige ändern
+Comment[el]=Αλλαγή μεγέθους και περιστροφή της οθόνης.
+Comment[eo]=Regrandigi kaj turni X ekranojn.
+Comment[es]=Ajustar el tamaño y rotar las pantallas X.
+Comment[et]=X'i ekraani muutmine ja pööramine
+Comment[eu]=Aldatu tamaina eta biratu zure X pantailak.
+Comment[fa]=تغییر‌ اندازه و چرخش پرده‌های X.
+Comment[fi]=Näytön kuvan koon muuttaminen ja kuvan kääntäminen
+Comment[fr]=Redimensionner et retourner votre affichage.
+Comment[fy]=Skermgrutte wizigje en rotearje X skermen
+Comment[ga]=Athraigh an méid agus rothlaigh scáileáin X.
+Comment[gl]=Redimensionar e rotar pantallas
+Comment[he]=שנה את גודלה של התצוגה שלך וסובב אותה.
+Comment[hr]=Promjena veličine i orijentacije X zaslona
+Comment[hu]=A képernyő átméretezése, elforgatása
+Comment[is]=Breyta stærð skjásins og snúa honum.
+Comment[it]=Ridimensiona e ruota gli schermi di X.
+Comment[ja]=X スクリーンのリサイズと回転。
+Comment[ka]=ეკრანის ზომის და ორიენტაციის შეცვლა
+Comment[kk]=Экранның өлшемін және бағытын өзгерту
+Comment[km]=ប្ដូរ​ទំហំ និង​បង្វិល​អេក្រង់ X ។
+Comment[lt]=Keisti X ekrano dydį ir orientaciją.
+Comment[mk]=Сменете ја големината и ротацијата на вашиот екран
+Comment[nb]=Endrer størrelsen på og roterer X-skjermbildet
+Comment[nds]=Grött un Utrichten vun den X-Schirm ännern
+Comment[ne]=X पर्दा रिसाइज गर्नुहोस् र घुमाउनुहोस्
+Comment[nl]=Scherm roteren en van grootte veranderen
+Comment[nn]=Endra storleiken på og roter X-skjermbiletet.
+Comment[pa]=X ਸਕਰੀਨ ਨੂੰ ਮੁੜ-ਅਕਾਰ ਅਤੇ ਘੁੰਮਾਓ।
+Comment[pl]=Zmiana rozmiaru i orientacji ekranów.
+Comment[pt]=Mudar o tamanho e rodar os ecrãs do X.
+Comment[pt_BR]=Redimensiona e rotaciona as tela do X.
+Comment[ro]=Redimensionează și rotește ecranele X.
+Comment[ru]=Изменение размера и ориентации экранов X.
+Comment[se]=Rievdat X-šearpmaid sturrodaga ja joraheami.
+Comment[sk]=Zmení veľkosť a otočí obrazovky
+Comment[sl]=Spremenite velikost in obrnite zaslon.
+Comment[sr]=Промените величину и оријентацију екрана
+Comment[sr@Latn]=Promenite veličinu i orijentaciju ekrana
+Comment[sv]=Storleksändring och rotation av X-skärmar.
+Comment[tg]=Ивази андоза ва мавқеи экранҳои Х.
+Comment[th]=ปรับแต่งการแสดงผลของ X
+Comment[tr]=Ekranı boyutlandır ve çevir.
+Comment[uk]=Зміна розміру та обертання екранів X.
+Comment[uz]=Ekraning oʻlchamini oʻzgartirish va burish
+Comment[uz@cyrillic]=Экранинг ўлчамини ўзгартириш ва буриш
+Comment[vi]=Đổi cỡ và quay màn hình X.
+Comment[wa]=Candjî l' grandeu eyet tourner les waitroûles X.
+Comment[zh_CN]=更改 X 屏幕的大小和旋转。
+Comment[zh_TW]=調整大小及旋轉 X 螢幕。
+Exec=krandrtray
+Icon=randr
+Type=Application
+OnlyShowIn=KDE;
+Categories=Qt;KDE;System;
diff --git a/kcontrol/randr/krandrtray.h b/kcontrol/randr/krandrtray.h
new file mode 100644
index 000000000..829306437
--- /dev/null
+++ b/kcontrol/randr/krandrtray.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2002 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KRANDRTRAY_H
+#define KRANDRTRAY_H
+
+#include <qptrlist.h>
+
+#include <ksystemtray.h>
+
+#include "randr.h"
+
+class KHelpMenu;
+class KPopupMenu;
+
+class KRandRSystemTray : public KSystemTray, public RandRDisplay
+{
+ Q_OBJECT
+
+public:
+ KRandRSystemTray(QWidget* parent = 0, const char *name = 0);
+
+ virtual void contextMenuAboutToShow(KPopupMenu* menu);
+
+ void configChanged();
+
+protected slots:
+ void slotScreenActivated();
+ void slotResolutionChanged(int parameter);
+ void slotOrientationChanged(int parameter);
+ void slotRefreshRateChanged(int parameter);
+ void slotPrefs();
+
+protected:
+ void mousePressEvent( QMouseEvent *e );
+
+private:
+ void populateMenu(KPopupMenu* menu);
+
+ bool m_popupUp;
+ KHelpMenu* m_help;
+ QPtrList<KPopupMenu> m_screenPopups;
+};
+
+#endif
diff --git a/kcontrol/randr/ktimerdialog.cpp b/kcontrol/randr/ktimerdialog.cpp
new file mode 100644
index 000000000..071088e9b
--- /dev/null
+++ b/kcontrol/randr/ktimerdialog.cpp
@@ -0,0 +1,205 @@
+/*
+ * This file is part of the KDE Libraries
+ * Copyright (C) 2002 Hamish Rodda <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <qhbox.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qtimer.h>
+#include <qprogressbar.h>
+#include <qlabel.h>
+
+#include <kwin.h>
+#include <kiconloader.h>
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "ktimerdialog.h"
+#include "ktimerdialog.moc"
+
+KTimerDialog::KTimerDialog( int msec, TimerStyle style, QWidget *parent,
+ const char *name, bool modal,
+ const QString &caption,
+ int buttonMask, ButtonCode defaultButton,
+ bool separator,
+ const KGuiItem &user1,
+ const KGuiItem &user2,
+ const KGuiItem &user3 )
+ : KDialogBase(parent, name, modal, caption, buttonMask, defaultButton,
+ separator, user1, user2, user3 )
+{
+ totalTimer = new QTimer( this );
+ updateTimer = new QTimer( this );
+ msecTotal = msecRemaining = msec;
+ updateInterval = 1000;
+ tStyle = style;
+ KWin::setIcons( winId(), DesktopIcon("randr"), SmallIcon("randr") );
+ // default to cancelling the dialog on timeout
+ if ( buttonMask & Cancel )
+ buttonOnTimeout = Cancel;
+
+ connect( totalTimer, SIGNAL( timeout() ), SLOT( slotInternalTimeout() ) );
+ connect( updateTimer, SIGNAL( timeout() ), SLOT( slotUpdateTime() ) );
+
+ // create the widgets
+ mainWidget = new QVBox( this, "mainWidget" );
+ timerWidget = new QHBox( mainWidget, "timerWidget" );
+ timerLabel = new QLabel( timerWidget );
+ timerProgress = new QProgressBar( timerWidget );
+ timerProgress->setTotalSteps( msecTotal );
+ timerProgress->setPercentageVisible( false );
+
+ KDialogBase::setMainWidget( mainWidget );
+
+ slotUpdateTime( false );
+}
+
+KTimerDialog::~KTimerDialog()
+{
+}
+
+void KTimerDialog::show()
+{
+ KDialogBase::show();
+ totalTimer->start( msecTotal, true );
+ updateTimer->start( updateInterval, false );
+}
+
+int KTimerDialog::exec()
+{
+ totalTimer->start( msecTotal, true );
+ updateTimer->start( updateInterval, false );
+ return KDialogBase::exec();
+}
+
+void KTimerDialog::setMainWidget( QWidget *widget )
+{
+ // yuck, here goes.
+ QVBox *newWidget = new QVBox( this );
+
+ if ( widget->parentWidget() != mainWidget ) {
+ widget->reparent( newWidget, 0, QPoint(0,0) );
+ } else {
+ newWidget->insertChild( widget );
+ }
+
+ timerWidget->reparent( newWidget, 0, QPoint(0, 0) );
+
+ delete mainWidget;
+ mainWidget = newWidget;
+ KDialogBase::setMainWidget( mainWidget );
+}
+
+void KTimerDialog::setRefreshInterval( int msec )
+{
+ updateInterval = msec;
+ if ( updateTimer->isActive() )
+ updateTimer->changeInterval( updateInterval );
+}
+
+int KTimerDialog::timeoutButton() const
+{
+ return buttonOnTimeout;
+}
+
+void KTimerDialog::setTimeoutButton( const ButtonCode newButton )
+{
+ buttonOnTimeout = newButton;
+}
+
+int KTimerDialog::timerStyle() const
+{
+ return tStyle;
+}
+
+void KTimerDialog::setTimerStyle( const TimerStyle newStyle )
+{
+ tStyle = newStyle;
+}
+
+void KTimerDialog::slotUpdateTime( bool update )
+{
+ if ( update )
+ switch ( tStyle ) {
+ case CountDown:
+ msecRemaining -= updateInterval;
+ break;
+ case CountUp:
+ msecRemaining += updateInterval;
+ break;
+ case Manual:
+ break;
+ }
+
+ timerProgress->setProgress( msecRemaining );
+
+ timerLabel->setText( i18n("1 second remaining:","%n seconds remaining:",msecRemaining/1000) );
+}
+
+void KTimerDialog::slotInternalTimeout()
+{
+ emit timerTimeout();
+ switch ( buttonOnTimeout ) {
+ case Help:
+ slotHelp();
+ break;
+ case Default:
+ slotDefault();
+ break;
+ case Ok:
+ slotOk();
+ break;
+ case Apply:
+ applyPressed();
+ break;
+ case Try:
+ slotTry();
+ break;
+ case Cancel:
+ slotCancel();
+ break;
+ case Close:
+ slotClose();
+ break;
+ /*case User1:
+ slotUser1();
+ break;
+ case User2:
+ slotUser2();
+ break;*/
+ case User3:
+ slotUser3();
+ break;
+ case No:
+ slotNo();
+ break;
+ case Yes:
+ slotCancel();
+ break;
+ case Details:
+ slotDetails();
+ break;
+ case Filler:
+ case Stretch:
+ kdDebug() << "Cannot execute button code " << buttonOnTimeout << endl;
+ break;
+ }
+}
diff --git a/kcontrol/randr/ktimerdialog.h b/kcontrol/randr/ktimerdialog.h
new file mode 100644
index 000000000..23b4a92b0
--- /dev/null
+++ b/kcontrol/randr/ktimerdialog.h
@@ -0,0 +1,170 @@
+/*
+ * This file is part of the KDE Libraries
+ * Copyright (C) 2002 Hamish Rodda <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+#ifndef _KTIMERDIALOG_H_
+#define _KTIMERDIALOG_H_
+
+#include <kdialogbase.h>
+
+class QTimer;
+class QHBox;
+class QProgressBar;
+class QLabel;
+
+/**
+ * Provides a dialog that is only available for a specified amount
+ * of time, and reports the time remaining to the user.
+ *
+ * The timer is capable of counting up or down, for any number of milliseconds.
+ *
+ * The button which is activated upon timeout can be specified, as can the
+ * update interval for the dialog box.
+ *
+ * In addition, this class retains all of the functionality of @see KDialogBase .
+ *
+ * @short A dialog with a time limit and corresponding UI features.
+ * @author Hamish Rodda <[email protected]>
+ */
+class KTimerDialog : public KDialogBase
+{
+ Q_OBJECT
+
+ public:
+
+ /**
+ * @li @p CountDown - The timer counts downwards from the seconds given.
+ * @li @p CountUp - The timer counts up to the number of seconds given.
+ * @li @p Manual - The timer is not invoked; the caller must update the
+ * progress.
+ */
+ enum TimerStyle
+ {
+ CountDown,
+ CountUp,
+ Manual
+ };
+
+ /**
+ * Constructor for the standard mode where you must specify the main
+ * widget with @ref setMainWidget() . See @see KDialogBase for further details.
+ *
+ * For the rest of the arguments, See @see KDialogBase .
+ */
+ KTimerDialog( int msec, TimerStyle style=CountDown, QWidget *parent=0,
+ const char *name=0, bool modal=true,
+ const QString &caption=QString::null,
+ int buttonMask=Ok|Apply|Cancel, ButtonCode defaultButton=Ok,
+ bool separator=false,
+ const KGuiItem &user1=KGuiItem(),
+ const KGuiItem &user2=KGuiItem(),
+ const KGuiItem &user3=KGuiItem() );
+
+ /**
+ * Destructor.
+ */
+ ~KTimerDialog();
+
+ /**
+ * Execute the dialog modelessly - see @see QDialog .
+ */
+ virtual void show();
+
+ /**
+ * Set the refresh interval for the timer progress. Defaults to one second.
+ */
+ void setRefreshInterval( int msec );
+
+ /**
+ * Retrieves the @ref ButtonCode which will be activated once the timer
+ * times out. @see setTimeoutButton
+ */
+ int timeoutButton() const;
+
+ /**
+ * Sets the @ref ButtonCode to determine which button will be activated
+ * once the timer times out. @see timeoutButton
+ */
+ void setTimeoutButton( ButtonCode newButton );
+
+ /**
+ * Retrieves the current @ref TimerStyle. @see setTimerStyle
+ */
+ int timerStyle() const;
+
+ /**
+ * Sets the @ref TimerStyle. @see timerStyle
+ */
+ void setTimerStyle( TimerStyle newStyle );
+
+ /**
+ * Overridden function which is used to set the main widget of the dialog.
+ * @see KDialogBase::setMainWidget.
+ */
+ void setMainWidget( QWidget *widget );
+
+ signals:
+ /**
+ * Signal which is emitted once the timer has timed out.
+ */
+ void timerTimeout();
+
+ public slots:
+ /**
+ * Execute the dialog modally - see @see QDialog .
+ */
+ int exec();
+
+ private slots:
+ /**
+ * Updates the dialog with the current progress levels.
+ */
+ void slotUpdateTime( bool update = true );
+
+ /**
+ * The internal
+ */
+ void slotInternalTimeout();
+
+ private:
+ /**
+ * Prepares the layout that manages the widgets of the dialog
+ */
+ void setupLayout();
+
+ QTimer *totalTimer;
+ QTimer *updateTimer;
+ int msecRemaining, updateInterval, msecTotal;
+
+ ButtonCode buttonOnTimeout;
+ TimerStyle tStyle;
+
+ QHBox *timerWidget;
+ QProgressBar *timerProgress;
+ QLabel *timerLabel;
+ QVBox *mainWidget;
+
+ class KTimerDialogPrivate;
+ KTimerDialogPrivate *d;
+};
+
+#endif
+
+
+
diff --git a/kcontrol/randr/main.cpp b/kcontrol/randr/main.cpp
new file mode 100644
index 000000000..f2de7f146
--- /dev/null
+++ b/kcontrol/randr/main.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdlib.h>
+#include <kdebug.h>
+
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+
+#include "krandrapp.h"
+
+static const char krandrtrayVersion[] = "0.5";
+static const KCmdLineOptions options[] =
+{
+ { "login", I18N_NOOP("Application is being auto-started at KDE session start"), 0L },
+ KCmdLineLastOption
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData aboutData("randr", I18N_NOOP("Resize and Rotate"), krandrtrayVersion, I18N_NOOP("Resize and Rotate System Tray App"), KAboutData::License_GPL, "(c) 2002,2003 Hamish Rodda", 0L, "");
+ aboutData.addAuthor("Hamish Rodda",I18N_NOOP("Maintainer"), "[email protected]");
+ aboutData.addCredit("Lubos Lunak",I18N_NOOP("Many fixes"), "[email protected]");
+ aboutData.setProductName("krandr/krandrtray");
+ KGlobal::locale()->setMainCatalogue("krandr");
+
+ KCmdLineArgs::init(argc,argv,&aboutData);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication::addCmdLineOptions();
+
+ KRandRApp app;
+
+ return app.exec();
+}
diff --git a/kcontrol/randr/randr.cpp b/kcontrol/randr/randr.cpp
new file mode 100644
index 000000000..63c5c0450
--- /dev/null
+++ b/kcontrol/randr/randr.cpp
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "randr.h"
+
+#include <qtimer.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <dcopclient.h>
+#include <kipc.h>
+#include <kactivelabel.h>
+
+#include "ktimerdialog.h"
+
+#include <X11/Xlib.h>
+#define INT8 _X11INT8
+#define INT32 _X11INT32
+#include <X11/Xproto.h>
+#undef INT8
+#undef INT32
+#include <X11/extensions/Xrandr.h>
+
+class RandRScreenPrivate
+{
+public:
+ RandRScreenPrivate() : config(0L) {};
+ ~RandRScreenPrivate()
+ {
+ if (config)
+ XRRFreeScreenConfigInfo(config);
+ }
+
+ XRRScreenConfiguration* config;
+};
+
+RandRScreen::RandRScreen(int screenIndex)
+ : d(new RandRScreenPrivate())
+ , m_screen(screenIndex)
+ , m_shownDialog(NULL)
+{
+ loadSettings();
+ setOriginal();
+}
+
+RandRScreen::~RandRScreen()
+{
+ delete d;
+}
+
+void RandRScreen::loadSettings()
+{
+ if (d->config)
+ XRRFreeScreenConfigInfo(d->config);
+
+ d->config = XRRGetScreenInfo(qt_xdisplay(), RootWindow(qt_xdisplay(), m_screen));
+ Q_ASSERT(d->config);
+
+ Rotation rotation;
+ m_currentSize = m_proposedSize = XRRConfigCurrentConfiguration(d->config, &rotation);
+ m_currentRotation = m_proposedRotation = rotation;
+
+ m_pixelSizes.clear();
+ m_mmSizes.clear();
+ int numSizes;
+ XRRScreenSize* sizes = XRRSizes(qt_xdisplay(), m_screen, &numSizes);
+ for (int i = 0; i < numSizes; i++) {
+ m_pixelSizes.append(QSize(sizes[i].width, sizes[i].height));
+ m_mmSizes.append(QSize(sizes[i].mwidth, sizes[i].mheight));
+ }
+
+ m_rotations = XRRRotations(qt_xdisplay(), m_screen, &rotation);
+
+ m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex(m_currentSize, XRRConfigCurrentRate(d->config));
+}
+
+void RandRScreen::setOriginal()
+{
+ m_originalSize = m_currentSize;
+ m_originalRotation = m_currentRotation;
+ m_originalRefreshRate = m_currentRefreshRate;
+}
+
+bool RandRScreen::applyProposed()
+{
+ //kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl;
+
+ Status status;
+
+ if (proposedRefreshRate() < 0)
+ status = XRRSetScreenConfig(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime);
+ else {
+ if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) {
+ m_proposedRefreshRate = 0;
+ }
+ status = XRRSetScreenConfigAndRate(qt_xdisplay(), d->config, DefaultRootWindow(qt_xdisplay()), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime);
+ }
+
+ //kdDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << endl;
+
+ if (status == RRSetConfigSuccess) {
+ m_currentSize = m_proposedSize;
+ m_currentRotation = m_proposedRotation;
+ m_currentRefreshRate = m_proposedRefreshRate;
+ return true;
+ }
+
+ return false;
+}
+
+bool RandRScreen::applyProposedAndConfirm()
+{
+ if (proposedChanged()) {
+ setOriginal();
+
+ if (applyProposed()) {
+ if (!confirm()) {
+ proposeOriginal();
+ applyProposed();
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool RandRScreen::confirm()
+{
+ // uncomment the line below and edit out the KTimerDialog stuff to get
+ // a version which works on today's kdelibs (no accept dialog is presented)
+
+ // FIXME remember to put the dialog on the right screen
+
+ KTimerDialog acceptDialog ( 15000, KTimerDialog::CountDown,
+ KApplication::kApplication()->mainWidget(),
+ "mainKTimerDialog",
+ true,
+ i18n("Confirm Display Setting Change"),
+ KTimerDialog::Ok|KTimerDialog::Cancel,
+ KTimerDialog::Cancel);
+
+ acceptDialog.setButtonOK(KGuiItem(i18n("&Accept Configuration"), "button_ok"));
+ acceptDialog.setButtonCancel(KGuiItem(i18n("&Return to Previous Configuration"), "button_cancel"));
+
+ KActiveLabel *label = new KActiveLabel(i18n("Your screen orientation, size and refresh rate "
+ "have been changed to the requested settings. Please indicate whether you wish to "
+ "keep this configuration. In 15 seconds the display will revert to your previous "
+ "settings."), &acceptDialog, "userSpecifiedLabel");
+
+ acceptDialog.setMainWidget(label);
+
+ KDialog::centerOnScreen(&acceptDialog, m_screen);
+
+ m_shownDialog = &acceptDialog;
+ connect( m_shownDialog, SIGNAL( destroyed()), this, SLOT( shownDialogDestroyed()));
+ connect( kapp->desktop(), SIGNAL( resized(int)), this, SLOT( desktopResized()));
+
+ return acceptDialog.exec();
+}
+
+void RandRScreen::shownDialogDestroyed()
+{
+ m_shownDialog = NULL;
+ disconnect( kapp->desktop(), SIGNAL( resized(int)), this, SLOT( desktopResized()));
+}
+
+void RandRScreen::desktopResized()
+{
+ if( m_shownDialog != NULL )
+ KDialog::centerOnScreen(m_shownDialog, m_screen);
+}
+
+QString RandRScreen::changedMessage() const
+{
+ if (currentRefreshRate() == -1)
+ return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3")
+ .arg(currentPixelWidth())
+ .arg(currentPixelHeight())
+ .arg(currentRotationDescription());
+ else
+ return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3\nRefresh rate: %4")
+ .arg(currentPixelWidth())
+ .arg(currentPixelHeight())
+ .arg(currentRotationDescription())
+ .arg(currentRefreshRateDescription());
+}
+
+bool RandRScreen::changedFromOriginal() const
+{
+ return m_currentSize != m_originalSize || m_currentRotation != m_originalRotation || m_currentRefreshRate != m_originalRefreshRate;
+}
+
+void RandRScreen::proposeOriginal()
+{
+ m_proposedSize = m_originalSize;
+ m_proposedRotation = m_originalRotation;
+ m_proposedRefreshRate = m_originalRefreshRate;
+}
+
+bool RandRScreen::proposedChanged() const
+{
+ return m_currentSize != m_proposedSize || m_currentRotation != m_proposedRotation || m_currentRefreshRate != m_proposedRefreshRate;
+}
+
+QString RandRScreen::rotationName(int rotation, bool pastTense, bool capitalised)
+{
+ if (!pastTense)
+ switch (rotation) {
+ case RR_Rotate_0:
+ return i18n("Normal");
+ case RR_Rotate_90:
+ return i18n("Left (90 degrees)");
+ case RR_Rotate_180:
+ return i18n("Upside-down (180 degrees)");
+ case RR_Rotate_270:
+ return i18n("Right (270 degrees)");
+ case RR_Reflect_X:
+ return i18n("Mirror horizontally");
+ case RR_Reflect_Y:
+ return i18n("Mirror vertically");
+ default:
+ return i18n("Unknown orientation");
+ }
+
+ switch (rotation) {
+ case RR_Rotate_0:
+ return i18n("Normal");
+ case RR_Rotate_90:
+ return i18n("Rotated 90 degrees counterclockwise");
+ case RR_Rotate_180:
+ return i18n("Rotated 180 degrees counterclockwise");
+ case RR_Rotate_270:
+ return i18n("Rotated 270 degrees counterclockwise");
+ default:
+ if (rotation & RR_Reflect_X)
+ if (rotation & RR_Reflect_Y)
+ if (capitalised)
+ return i18n("Mirrored horizontally and vertically");
+ else
+ return i18n("mirrored horizontally and vertically");
+ else
+ if (capitalised)
+ return i18n("Mirrored horizontally");
+ else
+ return i18n("mirrored horizontally");
+ else if (rotation & RR_Reflect_Y)
+ if (capitalised)
+ return i18n("Mirrored vertically");
+ else
+ return i18n("mirrored vertically");
+ else
+ if (capitalised)
+ return i18n("Unknown orientation");
+ else
+ return i18n("unknown orientation");
+ }
+}
+
+QPixmap RandRScreen::rotationIcon(int rotation) const
+{
+ // Adjust icons for current screen orientation
+ if (!(m_currentRotation & RR_Rotate_0) && rotation & (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)) {
+ int currentAngle = m_currentRotation & (RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ switch (currentAngle) {
+ case RR_Rotate_90:
+ rotation <<= 3;
+ break;
+ case RR_Rotate_180:
+ rotation <<= 2;
+ break;
+ case RR_Rotate_270:
+ rotation <<= 1;
+ break;
+ }
+
+ // Fix overflow
+ if (rotation > RR_Rotate_270) {
+ rotation >>= 4;
+ }
+ }
+
+ switch (rotation) {
+ case RR_Rotate_0:
+ return SmallIcon("up");
+ case RR_Rotate_90:
+ return SmallIcon("back");
+ case RR_Rotate_180:
+ return SmallIcon("down");
+ case RR_Rotate_270:
+ return SmallIcon("forward");
+ case RR_Reflect_X:
+ case RR_Reflect_Y:
+ default:
+ return SmallIcon("stop");
+ }
+}
+
+QString RandRScreen::currentRotationDescription() const
+{
+ QString ret = rotationName(m_currentRotation & RotateMask);
+
+ if (m_currentRotation != m_currentRotation & RotateMask)
+ if (m_currentRotation & RR_Rotate_0)
+ ret = rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, true);
+ else
+ ret += ", " + rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, false);
+
+ return ret;
+}
+
+int RandRScreen::rotationIndexToDegree(int rotation) const
+{
+ switch (rotation & RotateMask) {
+ case RR_Rotate_90:
+ return 90;
+
+ case RR_Rotate_180:
+ return 180;
+
+ case RR_Rotate_270:
+ return 270;
+
+ default:
+ return 0;
+ }
+}
+
+int RandRScreen::rotationDegreeToIndex(int degree) const
+{
+ switch (degree) {
+ case 90:
+ return RR_Rotate_90;
+
+ case 180:
+ return RR_Rotate_180;
+
+ case 270:
+ return RR_Rotate_270;
+
+ default:
+ return RR_Rotate_0;
+ }
+}
+
+int RandRScreen::currentPixelWidth() const
+{
+ return m_pixelSizes[m_currentSize].width();
+}
+
+int RandRScreen::currentPixelHeight() const
+{
+ return m_pixelSizes[m_currentSize].height();
+}
+
+int RandRScreen::currentMMWidth() const
+{
+ return m_pixelSizes[m_currentSize].width();
+}
+
+int RandRScreen::currentMMHeight() const
+{
+ return m_pixelSizes[m_currentSize].height();
+}
+
+QStringList RandRScreen::refreshRates(int size) const
+{
+ int nrates;
+ short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
+
+ QStringList ret;
+ for (int i = 0; i < nrates; i++)
+ ret << refreshRateDirectDescription(rates[i]);
+
+ return ret;
+}
+
+QString RandRScreen::refreshRateDirectDescription(int rate) const
+{
+ return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(rate);
+}
+
+QString RandRScreen::refreshRateIndirectDescription(int size, int index) const
+{
+ return i18n("Refresh rate in Hertz (Hz)", "%1 Hz").arg(refreshRateIndexToHz(size, index));
+}
+
+QString RandRScreen::refreshRateDescription(int size, int index) const
+{
+ return refreshRates(size)[index];
+}
+
+bool RandRScreen::proposeRefreshRate(int index)
+{
+ if (index >= 0 && (int)refreshRates(proposedSize()).count() > index) {
+ m_proposedRefreshRate = index;
+ return true;
+ }
+
+ return false;
+}
+
+int RandRScreen::currentRefreshRate() const
+{
+ return m_currentRefreshRate;
+}
+
+QString RandRScreen::currentRefreshRateDescription() const
+{
+ return refreshRateIndirectDescription(m_currentSize, m_currentRefreshRate);
+}
+
+int RandRScreen::proposedRefreshRate() const
+{
+ return m_proposedRefreshRate;
+}
+
+int RandRScreen::refreshRateHzToIndex(int size, int hz) const
+{
+ int nrates;
+ short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
+
+ for (int i = 0; i < nrates; i++)
+ if (hz == rates[i])
+ return i;
+
+ if (nrates != 0)
+ // Wrong input Hz!
+ Q_ASSERT(false);
+
+ return -1;
+}
+
+int RandRScreen::refreshRateIndexToHz(int size, int index) const
+{
+ int nrates;
+ short* rates = XRRRates(qt_xdisplay(), m_screen, (SizeID)size, &nrates);
+
+ if (nrates == 0 || index < 0)
+ return 0;
+
+ // Wrong input Hz!
+ if(index >= nrates)
+ return 0;
+
+ return rates[index];
+}
+
+int RandRScreen::numSizes() const
+{
+ return m_pixelSizes.count();
+}
+
+const QSize& RandRScreen::pixelSize(int index) const
+{
+ return m_pixelSizes[index];
+}
+
+const QSize& RandRScreen::mmSize(int index) const
+{
+ return m_mmSizes[index];
+}
+
+int RandRScreen::sizeIndex(QSize pixelSize) const
+{
+ for (uint i = 0; i < m_pixelSizes.count(); i++)
+ if (m_pixelSizes[i] == pixelSize)
+ return i;
+
+ return -1;
+}
+
+int RandRScreen::rotations() const
+{
+ return m_rotations;
+}
+
+int RandRScreen::currentRotation() const
+{
+ return m_currentRotation;
+}
+
+int RandRScreen::currentSize() const
+{
+ return m_currentSize;
+}
+
+int RandRScreen::proposedRotation() const
+{
+ return m_proposedRotation;
+}
+
+void RandRScreen::proposeRotation(int newRotation)
+{
+ m_proposedRotation = newRotation & OrientationMask;
+}
+
+int RandRScreen::proposedSize() const
+{
+ return m_proposedSize;
+}
+
+bool RandRScreen::proposeSize(int newSize)
+{
+ if ((int)m_pixelSizes.count() > newSize) {
+ m_proposedSize = newSize;
+ return true;
+ }
+
+ return false;
+}
+
+void RandRScreen::load(KConfig& config)
+{
+ config.setGroup(QString("Screen%1").arg(m_screen));
+
+ if (proposeSize(sizeIndex(QSize(config.readNumEntry("width", currentPixelWidth()), config.readNumEntry("height", currentPixelHeight())))))
+ proposeRefreshRate(refreshRateHzToIndex(proposedSize(), config.readNumEntry("refresh", currentRefreshRate())));
+
+ proposeRotation(rotationDegreeToIndex(config.readNumEntry("rotation", 0)) + (config.readBoolEntry("reflectX") ? ReflectX : 0) + (config.readBoolEntry("reflectY") ? ReflectY : 0));
+}
+
+void RandRScreen::save(KConfig& config) const
+{
+ config.setGroup(QString("Screen%1").arg(m_screen));
+ config.writeEntry("width", currentPixelWidth());
+ config.writeEntry("height", currentPixelHeight());
+ config.writeEntry("refresh", refreshRateIndexToHz(currentSize(), currentRefreshRate()));
+ config.writeEntry("rotation", rotationIndexToDegree(currentRotation()));
+ config.writeEntry("reflectX", (bool)(currentRotation() & ReflectMask) == ReflectX);
+ config.writeEntry("reflectY", (bool)(currentRotation() & ReflectMask) == ReflectY);
+}
+
+RandRDisplay::RandRDisplay()
+ : m_valid(true)
+{
+ // Check extension
+ Status s = XRRQueryExtension(qt_xdisplay(), &m_eventBase, &m_errorBase);
+ if (!s) {
+ m_errorCode = QString("%1, base %1").arg(s).arg(m_errorBase);
+ m_valid = false;
+ return;
+ }
+
+ int major_version, minor_version;
+ XRRQueryVersion(qt_xdisplay(), &major_version, &minor_version);
+
+ m_version = QString("X Resize and Rotate extension version %1.%1").arg(major_version).arg(minor_version);
+
+ m_numScreens = ScreenCount(qt_xdisplay());
+
+ // This assumption is WRONG with Xinerama
+ // Q_ASSERT(QApplication::desktop()->numScreens() == ScreenCount(qt_xdisplay()));
+
+ m_screens.setAutoDelete(true);
+ for (int i = 0; i < m_numScreens; i++) {
+ m_screens.append(new RandRScreen(i));
+ }
+
+ setCurrentScreen(QApplication::desktop()->primaryScreen());
+}
+
+bool RandRDisplay::isValid() const
+{
+ return m_valid;
+}
+
+const QString& RandRDisplay::errorCode() const
+{
+ return m_errorCode;
+}
+
+int RandRDisplay::eventBase() const
+{
+ return m_eventBase;
+}
+
+int RandRDisplay::screenChangeNotifyEvent() const
+{
+ return m_eventBase + RRScreenChangeNotify;
+}
+
+int RandRDisplay::errorBase() const
+{
+ return m_errorBase;
+}
+
+const QString& RandRDisplay::version() const
+{
+ return m_version;
+}
+
+void RandRDisplay::setCurrentScreen(int index)
+{
+ m_currentScreenIndex = index;
+ m_currentScreen = m_screens.at(m_currentScreenIndex);
+ Q_ASSERT(m_currentScreen);
+}
+
+int RandRDisplay::screenIndexOfWidget(QWidget* widget)
+{
+ int ret = QApplication::desktop()->screenNumber(widget);
+ return ret != -1 ? ret : QApplication::desktop()->primaryScreen();
+}
+
+int RandRDisplay::currentScreenIndex() const
+{
+ return m_currentScreenIndex;
+}
+
+void RandRDisplay::refresh()
+{
+ for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
+ s->loadSettings();
+}
+
+int RandRDisplay::numScreens() const
+{
+ return m_numScreens;
+}
+
+RandRScreen* RandRDisplay::screen(int index)
+{
+ return m_screens.at(index);
+}
+
+RandRScreen* RandRDisplay::currentScreen()
+{
+ return m_currentScreen;
+}
+
+bool RandRDisplay::loadDisplay(KConfig& config, bool loadScreens)
+{
+ if (loadScreens)
+ for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
+ s->load(config);
+
+ return applyOnStartup(config);
+}
+
+bool RandRDisplay::applyOnStartup(KConfig& config)
+{
+ config.setGroup("Display");
+ return config.readBoolEntry("ApplyOnStartup", false);
+}
+
+bool RandRDisplay::syncTrayApp(KConfig& config)
+{
+ config.setGroup("Display");
+ return config.readBoolEntry("SyncTrayApp", false);
+}
+
+void RandRDisplay::saveDisplay(KConfig& config, bool applyOnStartup, bool syncTrayApp)
+{
+ Q_ASSERT(!config.isReadOnly());
+
+ config.setGroup("Display");
+ config.writeEntry("ApplyOnStartup", applyOnStartup);
+ config.writeEntry("SyncTrayApp", syncTrayApp);
+
+ for (RandRScreen* s = m_screens.first(); s; s = m_screens.next())
+ s->save(config);
+}
+
+void RandRDisplay::applyProposed(bool confirm)
+{
+ for (int screenIndex = 0; screenIndex < numScreens(); screenIndex++) {
+ if (screen(screenIndex)->proposedChanged()) {
+ if (confirm)
+ screen(screenIndex)->applyProposedAndConfirm();
+ else
+ screen(screenIndex)->applyProposed();
+ }
+ }
+}
+
+int RandRScreen::pixelCount( int index ) const
+{
+ QSize sz = pixelSize(index);
+ return sz.width() * sz.height();
+}
+
+#include "randr.moc"
diff --git a/kcontrol/randr/randr.desktop b/kcontrol/randr/randr.desktop
new file mode 100644
index 000000000..f67165d20
--- /dev/null
+++ b/kcontrol/randr/randr.desktop
@@ -0,0 +1,216 @@
+[Desktop Entry]
+Icon=randr
+Type=Application
+Exec=kcmshell randr
+X-KDE-Library=randr
+#X-KDE-Init=randr
+X-KDE-Test-Module=true
+
+Name=Size & Orientation
+Name[af]=Grootte & Ooriëntasie
+Name[ar]=القياس و الإتجاه
+Name[be]=Памеры і арыентацыя
+Name[bg]=Размер и ротация на екрана
+Name[bn]=আকৃতি এবং দিশা
+Name[br]=Ment ha reteradur
+Name[bs]=Veličina i orijentacija
+Name[ca]=Mida i orientació
+Name[cs]=Velikost a orientace
+Name[csb]=Miara ë pòłóżenié
+Name[cy]=Maint & Cyfeiriad
+Name[da]=Størrelse & Orientering
+Name[de]=Größe & Orientierung
+Name[el]=Μέγεθος & Προσανατολισμός
+Name[eo]=Grandeco kaj direkto
+Name[es]=Tamaño y orientación
+Name[et]=Suurus ja orientatsioon
+Name[eu]=Tamaina eta orientazioa
+Name[fa]=اندازه و جهت
+Name[fi]=Koko ja suunta
+Name[fr]=Taille et orientation
+Name[fy]=Grutte en oriïntaasje
+Name[ga]=Méid agus Treoshuíomh
+Name[gl]=Tamaño e Orientación
+Name[he]=גודל וכיוון
+Name[hi]=आकार व दिशा निर्धारण
+Name[hr]=Veličina i orijentacija
+Name[hu]=Képernyőfelbontás
+Name[is]=Stærð og snúningur
+Name[it]=Dimensione e orientazione
+Name[ja]=サイズと配置
+Name[ka]=ზომა და ორიენტაცია
+Name[kk]=Өлшем және бағыт
+Name[km]=ទំហំ & ទិស
+Name[ko]=해상도와 회전
+Name[lt]=Dydis ir orientacija
+Name[lv]=Izmērs un orientācija
+Name[mk]=Големина и ориентација
+Name[mn]=Хэмжээ & Чиглэл
+Name[ms]=Saiz & Orientasi
+Name[mt]=Daqs u Orjentazzjoni
+Name[nb]=Størrelse og retning
+Name[nds]=Grött & Utrichten
+Name[ne]=साइज र अभिमुखीकरण
+Name[nl]=Grootte en oriëntatie
+Name[nn]=Storleik og retning
+Name[pa]=ਆਕਾਰ ਅਤੇ ਸਥਿਤੀ
+Name[pl]=Rozmiar i orientacja
+Name[pt]=Tamanho e Orientação
+Name[pt_BR]=Tamanho & Orientação
+Name[ro]=Mărime și orientare
+Name[ru]=Размер и ориентация
+Name[rw]=Ingano & Icyerekezo
+Name[se]=Sturrodat ja joraheapmi
+Name[sk]=Veľkosť a orientácia
+Name[sl]=Velikost in orientacija
+Name[sr]=Величина и оријентација
+Name[sr@Latn]=Veličina i orijentacija
+Name[sv]=Storlek och orientering
+Name[ta]=அளவும் திசையும்
+Name[tg]=Андоза ва шиносоӣ
+Name[th]=ขนาดและการวางแนว
+Name[tr]=Konum ve Boyut
+Name[tt]=Ülçäm belän Yünälü
+Name[uk]=Розмір та орієнтація
+Name[uz]=Oʻlchami va joylashishi
+Name[uz@cyrillic]=Ўлчами ва жойлашиши
+Name[vi]=Cỡ & Hướng
+Name[wa]=Grandeu eyet oryintåcion
+Name[zh_CN]=大小和方向
+Name[zh_TW]=尺寸及定位
+
+Comment=Resize and Rotate your display
+Comment[af]=Hervergroot en Roteer jou skerm
+Comment[ar]=غيّر القياس و دوران شاشتك
+Comment[be]=Змяняе памеры і перагортвае ваш экран
+Comment[bg]=Настройване на размера и завъртането на екрана
+Comment[bn]=আপনার ডিসপ্লের আকৃতি এবং দিশা পরিবর্তন করুন
+Comment[br]=Adventañ ha treiñ ho skramm
+Comment[bs]=Podesite veličinu i rotirajte vaš ekran
+Comment[ca]=Amida i gira la vostra pantalla
+Comment[cs]=Změna velikosti a rotace obrazovky
+Comment[csb]=Zjinaka miarë ë pòłożenia ekranu
+Comment[cy]=Newid Maint a Cylchdroi eich dangosydd
+Comment[da]=Ændrer størrelse og roterer din visning
+Comment[de]=Die Größe und Ausrichtung der Anzeige ändern
+Comment[el]=Αλλαγή μεγέθους και Περιστροφή της οθόνης σας
+Comment[eo]=Grandigi kaj turni vian ekranblokon
+Comment[es]=Ajustar el tamaño y rotar la pantalla
+Comment[et]=Oma vaate suuruse muutmine ja pööramine
+Comment[eu]=Aldatu tamaina eta biratu zure pantaila
+Comment[fa]=تغییر اندازه و چرخش صفحه نمایش شما
+Comment[fi]=Resoluution muuttaminen ja ruudun kääntäminen
+Comment[fr]=Redimensionner et Tourner votre affichage
+Comment[fy]=Wizigje it skermgrutte en rotearje dizze
+Comment[gl]=Redimensionar e rotar a sua pantalla
+Comment[he]=שנה את גודלה של התצוגה שלך וסובב אותה
+Comment[hi]=अपने शक्ल-सूरत(डिस्प्ले) का आकार बदलें तथा घुमाएँ
+Comment[hr]=Promijena veličine i orijentacije zaslona
+Comment[hu]=A képernyő átméretezése, elforgatása
+Comment[is]=Breyta stærð skjásins og snúa honum
+Comment[it]=Ridimensiona e ruota il tuo display
+Comment[ja]=ディスプレイのリサイズと回転
+Comment[ka]=ეკრანის ზომის და ორიენტაციის შეცვლა
+Comment[kk]=Дисплейдің өлшемін және бағытын өзгерту
+Comment[km]=ប្ដូរ​ទំហំ និង​បង្វិល​ការ​បង្ហាញ​របស់​អ្នក
+Comment[ko]=디스플레이의 크기와 방향 조정
+Comment[lt]=Keisti ekrano dydį ir orientaciją
+Comment[lv]=Maina izmēru un rotē Jūsu ekrānu
+Comment[mk]=Сменете ја големината и ротацијата на вашиот екран
+Comment[mn]=Дэлгэцийнхээ хэмжээг өөрчилөх ба эргүүлэх
+Comment[ms]=Saiz Semula dan Putar paparan anda
+Comment[mt]=Ibdel id-daqs jew dawwar l-iskrin
+Comment[nb]=Endre størrelsen på og rotere skjermbildet
+Comment[nds]=Grött un Utrichten vun den Schirm ännern
+Comment[ne]=तपाईँको प्रदर्शन रिसाइज गर्नुहोस् र घुमाउनुहोस्
+Comment[nl]=Wijzig de schermgrootte en roteer deze
+Comment[nn]=Endra storleiken på og roter skjermbiletet
+Comment[pa]=ਆਪਣੀ ਝਲਕ ਨੂੰ ਮੁੜ-ਆਕਾਰ ਕਰੋ ਤੇ ਘੁੰਮਾਓ
+Comment[pl]=Zmiana rozmiaru i orientacji ekranu
+Comment[pt]=Dimensione e rode o seu ecrã
+Comment[pt_BR]=Redimensiona e Rotaciona a sua tela
+Comment[ro]=Redimensionează și rotește ecranul dumneavoastră
+Comment[ru]=Изменение размера и ориентации экрана
+Comment[rw]=Guhindura ingano no Kuzengurutsa iyerekana ryawe
+Comment[se]=Rievdat šearpma sturrodaga ja joraheami
+Comment[sk]=Zmení veľkosť a otočí váš displej
+Comment[sl]=Spremenite velikost in obrnite zaslon
+Comment[sr]=Промените величину и оријентацију вашег екрана
+Comment[sr@Latn]=Promenite veličinu i orijentaciju vašeg ekrana
+Comment[sv]=Storleksändring och rotation av skärmen
+Comment[ta]=தங்கள் காட்சியை அளவு மாற்று மற்றும் சுழற்று
+Comment[tg]=Андозаи намоиши худро дигаргун созед ва чаппа кунед
+Comment[th]=ปรับแต่งการแสดงผลของคุณ
+Comment[tr]=Ekranı boyutlandır ve çevir
+Comment[tt]=Kürägeñneñ Ülçäme belän Borılışı
+Comment[uk]=Зміна розміру та обертання дисплею
+Comment[uz]=Ekraning oʻlchamini oʻzgartirish va burish
+Comment[uz@cyrillic]=Экранинг ўлчамини ўзгартириш ва буриш
+Comment[vi]=Đổi cỡ và Quay màn hình của bạn
+Comment[wa]=Candjî l' grandeu eyet tourner li håynaedje
+Comment[zh_CN]=更改显示大小和旋转显示
+Comment[zh_TW]=調整大小及旋轉你的螢幕
+
+Keywords=resize,rotate,display,color,depth,size,horizontal,vertical
+Keywords[ar]=تغيير حجم، تدوير، لف، عرض، لون، عمق، حجم، أفقي، عمودي
+Keywords[be]=Змена памеру,Перагортванне,Дысплей,Экран,Колер,Глыбіня,Памер,Гарызантальны,Вертыкальны,resize,rotate,display,color,depth,size,horizontal,vertical
+Keywords[bg]=ротация, завъртане, екран, размер, промяна, resize, rotate, display, color, depth, size, horizontal, vertical
+Keywords[bs]=resize,rotate,display,color,depth,size,horizontal,vertical,veličina,rotacija,ekran,boja,dubina,uspravno,vodoravno
+Keywords[ca]=amida,gira,pantalla,color,profunditat,mida,horitzontal,vertical
+Keywords[cs]=velikost,rotace,obrazovka,barva,hloubka,horizontální,vertikální
+Keywords[csb]=zjinaka miarë,òbrócenié,pòłożenié,miara,ekran,farwa,farwë,głãbòkòsc farwów,wielëna farwów,knôdno,hòrizontalno
+Keywords[cy]=newid maint,cylchdroi,dangos,lliw,dyfnder,maint,llorweddol,fertigol
+Keywords[da]=ændr,rotér,visning,farve,dybde,størrelse,vandret,lodret
+Keywords[de]=Größe ändern,rotieren,anzeigen,Farbe,Tiefe,Größe,horizontal,vertikal,waagrecht,senkrecht
+Keywords[el]=αλλαγή μεγέθους,περιστροφή,οθόνη,χρώμα,βάθος,μέγεθος,οριζόντια,κατακόρυφα
+Keywords[en_GB]=resize,rotate,display,colour,depth,size,horizontal,vertical
+Keywords[eo]=grandigi,turni,direkto,ekrano,ekranbloko,grandeco,koloro,horizontala,vertikala
+Keywords[es]=redimensionar,rotar,mostrar,color,colores,tamaño,horizontal,vertical
+Keywords[et]=suuruse muutmine,pööramine,monitor,ekraan,värv,sügavus,suurus,horisontaalne,vertikaalne
+Keywords[eu]=tamaina aldatu,biratu,pantaila,kolorea,sakonera,tamaina,horizontala, bertikala
+Keywords[fa]=تغییر اندازه، چرخش، نمایش، رنگ، عمق، اندازه، افقی، عمودی
+Keywords[fi]=vaihda kokoa,käännä,näyttö,väri,syvyys,koko,vaakasuora,pystysuora
+Keywords[fr]=redimensionner,rotation,affichage,couleur,profondeur,taille, horizontal,vertical
+Keywords[fy]=grutte wizigje,rotearje,draaie,display,byldskerm,skerm,monitor,djipte,grutte,horizontaal,vertikaal
+Keywords[ga]=athraigh méid,rothlaigh,scáileán,dath,doimhneacht,méid,cothrománach,ingearach
+Keywords[gl]=redimensionar,rotar,pantalla,cor,resolución,tamaño,horizontal,vertical
+Keywords[he]=שנה גודל,סובב,תצוגה,צבע,עומק,גודל,אופקי,אנכי, resize,rotate,display,color,depth,size,horizontal,vertical
+Keywords[hi]=नया-आकार,घुमाएँ,प्रकटन,रंग,गहराई,आकार,आड़ा,खड़ा
+Keywords[hr]=resize,rotate,display,color,depth,size,horizontal,vertical,promjena,veličina,rotacija,zaslon,boja,dubina,vodoravno,uspravno
+Keywords[hu]=átméretezés,elforgatás,képernyő,szín,színmélység,vízszintes,függőleges
+Keywords[is]=resize,rotate,display,color,depth,size,horizontal,vertical,stækka,minnka,snúa
+Keywords[it]=ridimensiona,ruota,schermo,colori,profondità di colore,dimensione,orizzontale,verticale
+Keywords[ja]=リサイズ,回転,ディスプレイ,色,深度,サイズ,水平,垂直
+Keywords[km]=ប្ដូរ​ទំហំ,បង្វិល,បង្ហាញ,ពណ៌,ជម្រៅ,ទំហំ,ផ្ដេក,បញ្ឈរ
+Keywords[lt]=resize,rotate,display,color,depth,size,horizontal,vertical,keisti dydį,pasukti,sukti,ekranas,spalva,gylis,dydis,horizontalus,vertikalus
+Keywords[lv]=mainīt izmēru,rotēt,ekrāns,krāsa,dziļums,izmērs,horizontāls,vertikāls
+Keywords[mk]=resize,rotate,display,color,depth,size,horizontal,vertical,смени големина,ротира,прикажи,екран,боја,длабочина,големина,хоризонтално,вертикално
+Keywords[mn]=хэмжээ өөрчилөх,эргүүлэх,дэлгэц,өнгө,гүн,хэмжээ,хэвтээ,босоо
+Keywords[nb]=størrelse,rotere,skjerm,farge,dybde,vannrett,loddrett
+Keywords[nds]=Grött ännern,dreihen,display,Dorstellen,Klöör,Deep,Grött,waagrecht,pielliek
+Keywords[ne]=रिसाइज, घुमाउनुहोस्, प्रदर्शन, गहिराइ, साइज, तेर्सो, ठाडो
+Keywords[nl]=grootte wijzigen,roteren,draaien,display,beeldscherm,scherm,monitor,diepte,grootte,horizontaal,verticaal
+Keywords[nn]=storleik,rotera,skjerm,farge,djupn,vassrett,loddrett
+Keywords[pa]=ਮੁੜ-ਅਕਾਰ,ਘੁੰਮਾਉ,ਝਲਕ,ਰੰਗ,ਡੂੰਘਾਈ,ਅਕਾਰ,ਖਿਤਿਜੀ,ਲੰਬਕਾਰੀ
+Keywords[pl]=zmiana rozmiaru,obrót,orientacja,rozmiar,ekran,kolor,kolory,głębokość kolorów,liczba kolorów,pionowo,poziomo
+Keywords[pt]=redimensionar,rodar,ecrã,cor,profundidade,tamanho,horizontal,vertical
+Keywords[pt_BR]=redimensionar,rotacionar,display,cor,produndidade,tamanho,horizontal,vertical
+Keywords[ro]=redimensionare,rotire,ecran,monitor,culoare,adîncime,mărime,orizontal,vertical
+Keywords[ru]=resize,rotate,display,color,depth,size,horizontal,vertical,экран
+Keywords[rw]=guhindura ingano,kuzengurutsa,kwerekana,ibara,ubujyakuzimu,ingano,bitambitse,bihagaritse
+Keywords[se]=sturrodat,jorahit,šearbma,ivdni,čikŋodat,láskut,ceaggut
+Keywords[sk]=zmena veľkosti,rotácia,displej,farba,hĺbka,veľkosť,horizontálne,vertikálne
+Keywords[sl]=spremeni,velikost,zavrti,zaslon,barva,globina,navpičn,vodoravn
+Keywords[sr]=resize,rotate,display,color,depth,size,horizontal,vertical,промена,величина,ротација,екран,боја,дубина,водоравно,усправно
+Keywords[sr@Latn]=resize,rotate,display,color,depth,size,horizontal,vertical,promena,veličina,rotacija,ekran,boja,dubina,vodoravno,uspravno
+Keywords[sv]=ändra storlek,rotera,skärm,färg,djup,storlek,horisontell,vertikal
+Keywords[ta]=அளவுமாற்று, சுழற்று, காட்டு,வண்ணம், ஆழம்,அளவு,இடவலம்,மேலிருந்து கீழ்
+Keywords[th]=ปรับขนาด,หมุน,จอภาพ,สี,ความลึก,ขนาด,แนวราบ,แนวดิ่ง
+Keywords[tr]=boyutlandır,çevir,görünüm,renk,derinlik,boyut,dikey,yatay
+Keywords[uk]=зміна розміру,розмір,обертання,дисплей,колір,глибина,горизонтальний,вертикальний
+Keywords[uz]=oʻlchamini oʻzgartirish,burish,ekran,rang,chuqurlik,oʻlcham,gorizantal,vertikal
+Keywords[uz@cyrillic]=ўлчамини ўзгартириш,буриш,экран,ранг,чуқурлик,ўлчам,горизантал,вертикал
+Keywords[vi]=đổi cỡ,quay,hiển thị,màu,độ sâu,cỡ,ngang,dọc
+Keywords[wa]=candjî l' grandeu,tourner,håynaedje,coleur,parfondeu,grandeu,di coûtchî,d' astampé
+Keywords[zh_CN]=resize,rotate,display,color,depth,size,horizontal,vertical,更改大小,旋转,显示,颜色,深度,大小,垂直,水平
+Keywords[zh_TW]=resize,rotate,display,color,depth,size,horizontal,vertical,調整大小,旋轉,螢幕,顏色,深度,尺寸,垂直,水平
diff --git a/kcontrol/randr/randr.h b/kcontrol/randr/randr.h
new file mode 100644
index 000000000..c7eb240cf
--- /dev/null
+++ b/kcontrol/randr/randr.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2002,2003 Hamish Rodda <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __RANDR_H__
+#define __RANDR_H__
+
+#include <qobject.h>
+#include <qstringlist.h>
+#include <qptrlist.h>
+
+#include <kcmodule.h>
+#include <kconfig.h>
+
+class KTimerDialog;
+class RandRScreenPrivate;
+
+class RandRScreen : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum orientations {
+ Rotate0 = 0x1,
+ Rotate90 = 0x2,
+ Rotate180 = 0x4,
+ Rotate270 = 0x8,
+ RotateMask = 15,
+ RotationCount = 4,
+ ReflectX = 0x10,
+ ReflectY = 0x20,
+ ReflectMask = 48,
+ OrientationMask = 63,
+ OrientationCount = 6
+ };
+
+ RandRScreen(int screenIndex);
+ ~RandRScreen();
+
+ void loadSettings();
+ void setOriginal();
+
+ bool applyProposed();
+
+ /**
+ * @returns false if the user did not confirm in time, or cancelled, or the change failed
+ */
+ bool applyProposedAndConfirm();
+
+public slots:
+ bool confirm();
+
+public:
+ QString changedMessage() const;
+
+ bool changedFromOriginal() const;
+ void proposeOriginal();
+
+ bool proposedChanged() const;
+
+ static QString rotationName(int rotation, bool pastTense = false, bool capitalised = true);
+ QPixmap rotationIcon(int rotation) const;
+ QString currentRotationDescription() const;
+
+ int rotationIndexToDegree(int rotation) const;
+ int rotationDegreeToIndex(int degree) const;
+
+ /**
+ * Refresh rate functions.
+ */
+ QStringList refreshRates(int size) const;
+
+ QString refreshRateDirectDescription(int rate) const;
+ QString refreshRateIndirectDescription(int size, int index) const;
+ QString refreshRateDescription(int size, int index) const;
+
+ int currentRefreshRate() const;
+ QString currentRefreshRateDescription() const;
+
+ // Refresh rate hz <==> index conversion
+ int refreshRateHzToIndex(int size, int hz) const;
+ int refreshRateIndexToHz(int size, int index) const;
+
+ /**
+ * Screen size functions.
+ */
+ int numSizes() const;
+ const QSize& pixelSize(int index) const;
+ const QSize& mmSize(int index) const;
+ int pixelCount(int index) const;
+
+ /**
+ * Retrieve the index of a screen size with a specified pixel size.
+ *
+ * @param pixelSize dimensions of the screen in pixels
+ * @returns the index of the requested screen size
+ */
+ int sizeIndex(QSize pixelSize) const;
+
+ int rotations() const;
+
+ /**
+ * Current setting functions.
+ */
+ int currentPixelWidth() const;
+ int currentPixelHeight() const;
+ int currentMMWidth() const;
+ int currentMMHeight() const;
+
+ int currentRotation() const;
+ int currentSize() const;
+
+ /**
+ * Proposed setting functions.
+ */
+ int proposedSize() const;
+ bool proposeSize(int newSize);
+
+ int proposedRotation() const;
+ void proposeRotation(int newRotation);
+
+ int proposedRefreshRate() const;
+ /**
+ * Propose a refresh rate.
+ * Please note that you must propose the target size first for this to work.
+ *
+ * @param index the index of the refresh rate (not a refresh rate in hz!)
+ * @returns true if successful, false otherwise.
+ */
+ bool proposeRefreshRate(int index);
+
+ /**
+ * Configuration functions.
+ */
+ void load(KConfig& config);
+ void save(KConfig& config) const;
+
+private:
+ RandRScreenPrivate* d;
+
+ int m_screen;
+
+ QValueList<QSize> m_pixelSizes;
+ QValueList<QSize> m_mmSizes;
+ int m_rotations;
+
+ int m_originalRotation;
+ int m_originalSize;
+ int m_originalRefreshRate;
+
+ int m_currentRotation;
+ int m_currentSize;
+ int m_currentRefreshRate;
+
+ int m_proposedRotation;
+ int m_proposedSize;
+ int m_proposedRefreshRate;
+
+ KTimerDialog* m_shownDialog;
+
+private slots:
+ void desktopResized();
+ void shownDialogDestroyed();
+};
+
+typedef QPtrList<RandRScreen> ScreenList;
+
+class RandRDisplay
+{
+public:
+ RandRDisplay();
+
+ bool isValid() const;
+ const QString& errorCode() const;
+ const QString& version() const;
+
+ int eventBase() const;
+ int screenChangeNotifyEvent() const;
+ int errorBase() const;
+
+ int screenIndexOfWidget(QWidget* widget);
+
+ int numScreens() const;
+ RandRScreen* screen(int index);
+
+ void setCurrentScreen(int index);
+ int currentScreenIndex() const;
+ RandRScreen* currentScreen();
+
+ void refresh();
+
+ /**
+ * Loads saved settings.
+ *
+ * @param config the KConfig object to load from
+ * @param loadScreens whether to call RandRScreen::load() for each screen
+ * @retuns true if the settings should be applied on KDE startup.
+ */
+ bool loadDisplay(KConfig& config, bool loadScreens = true);
+ void saveDisplay(KConfig& config, bool applyOnStartup, bool syncTrayApp);
+
+ static bool applyOnStartup(KConfig& config);
+ static bool syncTrayApp(KConfig& config);
+
+ void applyProposed(bool confirm = true);
+
+private:
+ int m_numScreens;
+ int m_currentScreenIndex;
+ RandRScreen* m_currentScreen;
+ ScreenList m_screens;
+
+ bool m_valid;
+ QString m_errorCode;
+ QString m_version;
+
+ int m_eventBase;
+ int m_errorBase;
+};
+
+#endif