kcontrol: drop legacy configuration support in randr KCM

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-11-03 16:35:42 +02:00
parent 881a427576
commit 609a72aa84
38 changed files with 1771 additions and 3342 deletions

View file

@ -30,12 +30,3 @@ kde4_bool_to_01(X11_xf86misc_FOUND HAVE_XF86MISC) # kcontrol/keyboard
kde4_bool_to_01(X11_XSync_FOUND HAVE_XSYNC) # kwin
kde4_bool_to_01(X11_XRes_FOUND HAVE_XRES) # ksysguard
kde4_bool_to_01(X11_dpms_FOUND HAVE_DPMS) # kscreensaver
cmake_reset_check_state()
set(CMAKE_REQUIRED_INCLUDES ${X11_Xrandr_INCLUDE_PATH})
set(CMAKE_REQUIRED_LIBRARIES ${X11_Xrandr_LIB})
check_function_exists(XRRGetScreenSizeRange XRANDR_1_2_FOUND)
kde4_bool_to_01(XRANDR_1_2_FOUND HAS_RANDR_1_2)
check_function_exists(XRRGetScreenResourcesCurrent XRANDR_1_3_FOUND)
kde4_bool_to_01(XRANDR_1_3_FOUND HAS_RANDR_1_3)
cmake_reset_check_state()

View file

@ -1,12 +1,6 @@
/* Define if you have the XRandR extension */
#cmakedefine HAVE_XRANDR 1
/* Define if you have XRandR 1.2 */
#cmakedefine HAS_RANDR_1_2 1
/* Define if you have XRandR 1.3 */
#cmakedefine HAS_RANDR_1_3 1
/* Define if you have the XDamage extension */
#cmakedefine HAVE_XDAMAGE 1

View file

@ -1,61 +1,75 @@
if( XRANDR_1_2_FOUND )
add_subdirectory(module)
endif( XRANDR_1_2_FOUND )
add_subdirectory(module)
include_directories( ${X11_Xrandr_INCLUDE_PATH} )
include_directories(${X11_Xrandr_INCLUDE_PATH})
########### next target ###############
set(randrinternal_PART_SRCS
ktimerdialog.cpp
randr.cpp
randrdisplay.cpp
collapsiblewidget.cpp
legacyrandrscreen.cpp)
if( XRANDR_1_2_FOUND )
set(randrinternal_PART_SRCS ${randrinternal_PART_SRCS} layoutmanager.cpp
outputconfig.cpp outputgraphicsitem.cpp randrconfig.cpp randrcrtc.cpp
randrmode.cpp randroutput.cpp randrscreen.cpp)
endif( XRANDR_1_2_FOUND )
ktimerdialog.cpp
randr.cpp
randrdisplay.cpp
collapsiblewidget.cpp
layoutmanager.cpp
outputconfig.cpp
outputgraphicsitem.cpp
randrconfig.cpp
randrcrtc.cpp
randrmode.cpp
randroutput.cpp
randrscreen.cpp)
set(kcm_randr_PART_SRCS
krandrmodule.cpp
legacyrandrconfig.cpp
${randrinternal_PART_SRCS}
legacyrandrconfigbase.ui
randrconfigbase.ui
outputconfigbase.ui
${randrinternal_PART_SRCS}
krandrmodule.cpp
randrconfigbase.ui
outputconfigbase.ui
)
kde4_add_plugin(kcm_randr ${kcm_randr_PART_SRCS})
target_link_libraries(kcm_randr ${KDE4_KDEUI_LIBS} ${X11_Xrandr_LIB} ${X11_LIBRARIES})
install(TARGETS kcm_randr DESTINATION ${KDE4_PLUGIN_INSTALL_DIR})
target_link_libraries(kcm_randr
${KDE4_KDEUI_LIBS}
${X11_Xrandr_LIB}
${X11_LIBRARIES}
)
install(
TARGETS kcm_randr
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
)
########### next target ###############
set(krandrtray_SRCS
${randrinternal_PART_SRCS}
main.cpp
krandrtray.cpp
krandrapp.cpp
krandrpassivepopup.cpp
${randrinternal_PART_SRCS}
)
add_executable(krandrtray ${krandrtray_SRCS})
target_link_libraries(krandrtray ${KDE4_KCMUTILS_LIBS} ${X11_Xrandr_LIB} ${X11_LIBRARIES})
target_link_libraries(krandrtray
${KDE4_KCMUTILS_LIBS}
${X11_Xrandr_LIB}
${X11_LIBRARIES}
)
install(TARGETS krandrtray ${INSTALL_TARGETS_DEFAULT_ARGS})
install(
TARGETS krandrtray ${INSTALL_TARGETS_DEFAULT_ARGS}
)
########### next target ###############
install(PROGRAMS krandrstartup DESTINATION ${KDE4_BIN_INSTALL_DIR})
install(
FILES randr.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
)
install(FILES randr.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR})
install(PROGRAMS krandrtray.desktop DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR})
install(
PROGRAMS krandrtray.desktop
DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR}
)

View file

@ -52,18 +52,18 @@ ArrowButton::~ArrowButton()
void ArrowButton::paintEvent( QPaintEvent *event )
{
Q_UNUSED( event );
QPainter p( this );
QStyleOption opt;
int h = sizeHint().height();
opt.rect = QRect(0,( height()- h )/2, h, h);
opt.palette = palette();
opt.state = QStyle::State_Children;
if (isChecked())
opt.state |= QStyle::State_Open;
Q_UNUSED( event );
QPainter p( this );
QStyleOption opt;
int h = sizeHint().height();
opt.rect = QRect(0,( height()- h )/2, h, h);
opt.palette = palette();
opt.state = QStyle::State_Children;
if (isChecked())
opt.state |= QStyle::State_Open;
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, &p);
p.end();
style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, &p);
p.end();
}
@ -73,7 +73,7 @@ void ArrowButton::paintEvent( QPaintEvent *event )
class CollapsibleWidget::Private
{
public:
public:
QGridLayout *gridLayout;
QWidget *innerWidget;
ClickableLabel *label;
@ -85,7 +85,7 @@ class CollapsibleWidget::Private
class SettingsContainer::Private
{
public:
public:
QVBoxLayout *layout;
};
@ -94,186 +94,181 @@ class SettingsContainer::Private
*****************************************************************/
SettingsContainer::SettingsContainer(QWidget *parent)
: QScrollArea( parent ), d(new SettingsContainer::Private)
: QScrollArea( parent ), d(new SettingsContainer::Private)
{
QWidget *w = new QWidget;
QVBoxLayout *helperLay = new QVBoxLayout(w);
helperLay->setMargin(0);
d->layout = new QVBoxLayout;
helperLay->addLayout( d->layout );
helperLay->addStretch(1);
setWidget(w);
setWidgetResizable(true);
QWidget *w = new QWidget;
QVBoxLayout *helperLay = new QVBoxLayout(w);
helperLay->setMargin(0);
d->layout = new QVBoxLayout;
helperLay->addLayout( d->layout );
helperLay->addStretch(1);
setWidget(w);
setWidgetResizable(true);
}
SettingsContainer::~SettingsContainer()
{
delete d;
delete d;
}
CollapsibleWidget* SettingsContainer::insertWidget( QWidget *w, const QString& name )
{
if (w && w->layout()) {
QLayout *lay = w->layout();
lay->setMargin(2);
lay->setSpacing(2);
}
if (w && w->layout()) {
QLayout *lay = w->layout();
lay->setMargin(2);
lay->setSpacing(2);
}
CollapsibleWidget *cw = new CollapsibleWidget( name );
d->layout->addWidget( cw );
cw->setInnerWidget( w );
return cw;
CollapsibleWidget *cw = new CollapsibleWidget( name );
d->layout->addWidget( cw );
cw->setInnerWidget( w );
return cw;
}
CollapsibleWidget::CollapsibleWidget(QWidget *parent)
: QWidget(parent), d(new CollapsibleWidget::Private)
: QWidget(parent), d(new CollapsibleWidget::Private)
{
init();
}
CollapsibleWidget::CollapsibleWidget(const QString& caption, QWidget *parent)
: QWidget(parent), d(new CollapsibleWidget::Private)
: QWidget(parent), d(new CollapsibleWidget::Private)
{
init();
setCaption(caption);
init();
setCaption(caption);
}
void CollapsibleWidget::init()
{
d->expander = 0;
d->expanderLayout = 0;
d->timeline = new QTimeLine( 150, this );
d->timeline->setEasingCurve( QEasingCurve(QEasingCurve::InOutSine) );
connect( d->timeline, SIGNAL(valueChanged(qreal)),
this, SLOT(animateCollapse(qreal)) );
d->expander = 0;
d->expanderLayout = 0;
d->timeline = new QTimeLine( 150, this );
d->timeline->setEasingCurve( QEasingCurve(QEasingCurve::InOutSine) );
connect( d->timeline, SIGNAL(valueChanged(qreal)), this, SLOT(animateCollapse(qreal)) );
d->innerWidget = 0;
d->gridLayout = new QGridLayout( this );
d->gridLayout->setMargin(0);
d->innerWidget = 0;
d->gridLayout = new QGridLayout( this );
d->gridLayout->setMargin(0);
d->colButton = new ArrowButton;
d->colButton->setCheckable(true);
d->colButton = new ArrowButton;
d->colButton->setCheckable(true);
d->label = new ClickableLabel;
d->label->setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::Preferred);
d->label = new ClickableLabel;
d->label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
d->gridLayout->addWidget(d->colButton, 1, 1);
d->gridLayout->addWidget(d->label, 1, 2);
d->gridLayout->addWidget(d->colButton, 1, 1);
d->gridLayout->addWidget(d->label, 1, 2);
connect(d->label, SIGNAL(clicked()),
d->colButton, SLOT(click()));
connect(d->label, SIGNAL(clicked()), d->colButton, SLOT(click()));
connect(d->colButton, SIGNAL(toggled(bool)),
SLOT(setExpanded(bool)));
connect(d->colButton, SIGNAL(toggled(bool)), SLOT(setExpanded(bool)));
setExpanded(false);
setEnabled(false);
setExpanded(false);
setEnabled(false);
}
CollapsibleWidget::~CollapsibleWidget()
{
delete d;
delete d;
}
QWidget* CollapsibleWidget::innerWidget() const
{
return d->innerWidget;
return d->innerWidget;
}
#define SIMPLE
void CollapsibleWidget::setInnerWidget(QWidget *w)
{
if (!w) {
return;
}
if (!w) {
return;
}
d->innerWidget = w;
d->innerWidget = w;
#ifdef SIMPLE
if ( !isExpanded() ) {
d->innerWidget->hide();
}
d->gridLayout->addWidget( d->innerWidget, 2, 2 );
d->gridLayout->setRowStretch( 2, 1 );
if ( !isExpanded() ) {
d->innerWidget->hide();
}
d->gridLayout->addWidget( d->innerWidget, 2, 2 );
d->gridLayout->setRowStretch( 2, 1 );
#else
if ( !d->expander ) {
d->expander = new QWidget( this );
d->gridLayout->addWidget( d->expander, 2, 2 );
d->gridLayout->setRowStretch( 2, 1 );
d->expanderLayout = new QVBoxLayout( d->expander );
d->expanderLayout->setMargin( 0 );
d->expanderLayout->setSpacing( 0 );
d->expander->setFixedHeight( 0 );
}
if ( !d->expander ) {
d->expander = new QWidget( this );
d->gridLayout->addWidget( d->expander, 2, 2 );
d->gridLayout->setRowStretch( 2, 1 );
d->expanderLayout = new QVBoxLayout( d->expander );
d->expanderLayout->setMargin( 0 );
d->expanderLayout->setSpacing( 0 );
d->expander->setFixedHeight( 0 );
}
d->innerWidget->setParent( d->expander );
d->innerWidget->show();
d->expanderLayout->addWidget( d->innerWidget );
d->innerWidget->setParent( d->expander );
d->innerWidget->show();
d->expanderLayout->addWidget( d->innerWidget );
#endif
setEnabled( true );
setEnabled( true );
if ( isExpanded() ) {
setExpanded( true );
}
if ( isExpanded() ) {
setExpanded( true );
}
}
void CollapsibleWidget::setCaption(const QString& caption)
{
d->label->setText(QString("<b>%1</b>").arg(caption));
d->label->setText(QString("<b>%1</b>").arg(caption));
}
QString CollapsibleWidget::caption() const
{
return d->label->text();
return d->label->text();
}
void CollapsibleWidget::setExpanded(bool expanded)
{
if ( !d->innerWidget ) {
return;
}
if ( !d->innerWidget ) {
return;
}
#ifdef SIMPLE
if ( !expanded ) {
d->innerWidget->setVisible( false );
}
if ( !expanded ) {
d->innerWidget->setVisible( false );
}
#else
if ( expanded ) {
d->expander->setVisible( true );
}
d->innerWidget->setVisible( expanded );
if ( expanded ) {
d->expander->setVisible( true );
}
d->innerWidget->setVisible( expanded );
#endif
d->colButton->setChecked( expanded );
d->timeline->setDirection( expanded ? QTimeLine::Forward
: QTimeLine::Backward );
if (d->timeline->state() != QTimeLine::Running)
d->timeline->start();
d->colButton->setChecked( expanded );
d->timeline->setDirection( expanded ? QTimeLine::Forward : QTimeLine::Backward );
if (d->timeline->state() != QTimeLine::Running) {
d->timeline->start();
}
}
void CollapsibleWidget::animateCollapse( qreal showAmount )
{
int pixels = d->innerWidget->sizeHint().height() * showAmount;
d->gridLayout->setRowMinimumHeight( 2, pixels );
int pixels = d->innerWidget->sizeHint().height() * showAmount;
d->gridLayout->setRowMinimumHeight( 2, pixels );
#ifdef SIMPLE
d->gridLayout->setRowMinimumHeight( 2, pixels );
d->gridLayout->setRowMinimumHeight( 2, pixels );
if ( showAmount == 1 ) {
d->innerWidget->setVisible( true );
}
if ( showAmount == 1 ) {
d->innerWidget->setVisible( true );
}
#else
d->expander->setFixedHeight( pixels );
d->expander->setFixedHeight( pixels );
#endif
}
bool CollapsibleWidget::isExpanded() const
{
return d->colButton->isChecked();
return d->colButton->isChecked();
}
#include "moc_collapsiblewidget.cpp"

View file

@ -32,29 +32,27 @@
class ClickableLabel : public QLabel
{
Q_OBJECT
public:
Q_OBJECT
public:
ClickableLabel( QWidget* parent = 0 );
~ClickableLabel();
void mouseReleaseEvent( QMouseEvent *e );
signals:
signals:
void clicked();
};
class ArrowButton : public QAbstractButton
{
public:
public:
ArrowButton(QWidget *parent = 0);
~ArrowButton();
QSize sizeHint() const { return QSize(16, 16); }
protected:
protected:
void paintEvent( QPaintEvent* );
private:
};
/**
@ -64,7 +62,7 @@ class ArrowButton : public QAbstractButton
class Q_GUI_EXPORT CollapsibleWidget : public QWidget
{
Q_OBJECT
public:
public:
CollapsibleWidget(QWidget *parent = 0);
explicit CollapsibleWidget(const QString& caption, QWidget *parent = 0);
~CollapsibleWidget();
@ -75,23 +73,20 @@ class Q_GUI_EXPORT CollapsibleWidget : public QWidget
QWidget* innerWidget() const;
void setInnerWidget( QWidget *w);
public slots:
public slots:
void setExpanded(bool collapsed);
void setCaption(const QString& caption);
protected:
protected:
void init();
private slots:
private slots:
void animateCollapse(qreal);
private:
private:
Q_DISABLE_COPY( CollapsibleWidget )
class Private;
Private *d;
};
@ -104,20 +99,18 @@ class Q_GUI_EXPORT SettingsContainer : public QScrollArea
{
Q_ENUMS( CollapseState )
Q_OBJECT
public:
public:
enum CollapseState { Collapsed, Uncollapsed };
SettingsContainer( QWidget *parent = 0 );
~SettingsContainer();
CollapsibleWidget* insertWidget( QWidget* w, const QString& name );
private:
private:
Q_DISABLE_COPY( SettingsContainer )
class Private;
Private *d;
};
#endif // COLLAPSIBLEWIDGET_H

View file

@ -22,32 +22,27 @@
#include <config-X11.h>
#include "krandrapp.h"
#include "moc_krandrapp.cpp"
#include "krandrtray.h"
#ifdef HAS_RANDR_1_2
#include "randrscreen.h"
#endif
#include "legacyrandrscreen.h"
#include <X11/Xlib.h>
KRandRApp::KRandRApp()
{
m_display = new RandRDisplay();
m_tray = new KRandRSystemTray(m_display);
m_tray->setObjectName("RANDRTray");
m_display = new RandRDisplay();
m_tray = new KRandRSystemTray(m_display);
m_tray->setObjectName("RANDRTray");
// do not close when the last window is closed:
// the system tray is not considered a window, so when the confirm dialog is
// closed, the application exits
setQuitOnLastWindowClosed(false);
// do not close when the last window is closed:
// the system tray is not considered a window, so when the confirm dialog is
// closed, the application exits
setQuitOnLastWindowClosed(false);
}
bool KRandRApp::x11EventFilter(XEvent* e)
{
if (m_display->canHandle(e)) {
m_display->handleEvent(e);
}
if (m_display->canHandle(e))
m_display->handleEvent(e);
return KApplication::x11EventFilter(e);
return KApplication::x11EventFilter(e);
}

View file

@ -28,16 +28,15 @@ class RandRDisplay;
class KRandRApp : public KUniqueApplication
{
Q_OBJECT
Q_OBJECT
public:
KRandRApp();
KRandRApp();
virtual bool x11EventFilter(XEvent * e);
virtual bool x11EventFilter(XEvent * e);
private:
KRandRSystemTray *m_tray;
RandRDisplay *m_display;
KRandRSystemTray *m_tray;
RandRDisplay *m_display;
};
#endif
#endif // KRANDRAPP_H

View file

@ -18,8 +18,6 @@
*/
#include "krandrmodule.h"
#include "legacyrandrconfig.h"
#include "legacyrandrscreen.h"
#include "randrdisplay.h"
#include "randrconfig.h"
@ -42,7 +40,6 @@ extern "C"
{
KDE_EXPORT void kcminit_randr()
{
// TODO: drop legacy config support
KConfig config("krandrrc");
KConfigGroup group = config.group("Display");
const bool applyonstartup = group.readEntry("ApplyOnStartup", false);
@ -63,118 +60,84 @@ extern "C"
KRandRModule::KRandRModule(QWidget *parent, const QVariantList&)
: KCModule(KSSFactory::componentData(), parent)
{
m_display = new RandRDisplay();
if (!m_display->isValid())
{
QVBoxLayout *topLayout = new QVBoxLayout(this);
QLabel *label =
new QLabel(i18n("Your X server does not support resizing and "
"rotating the display. Please update to version 4.3 "
"or greater. You need the X Resize, Rotate, and Reflect "
"extension (RANDR) version 1.1 or greater to use this "
"feature."), this);
label->setWordWrap(true);
topLayout->addWidget(label);
kWarning() << "Error: " << m_display->errorCode() ;
return;
}
m_display = new RandRDisplay();
if (!m_display->isValid()) {
QVBoxLayout *topLayout = new QVBoxLayout(this);
QLabel *label = new QLabel(i18n("Your X server does not support resizing and "
"rotating the display. Please update to version 4.3 "
"or greater. You need the X Resize, Rotate, and Reflect "
"extension (RANDR) version 1.1 or greater to use this "
"feature."), this);
label->setWordWrap(true);
topLayout->addWidget(label);
kWarning() << "Error: " << m_display->errorCode() ;
return;
}
QVBoxLayout* topLayout = new QVBoxLayout(this);
topLayout->setMargin(0);
topLayout->setSpacing(KDialog::spacingHint());
QVBoxLayout* topLayout = new QVBoxLayout(this);
topLayout->setMargin(0);
topLayout->setSpacing(KDialog::spacingHint());
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
{
m_config = new RandRConfig(this, m_display);
connect(m_config, SIGNAL(changed(bool)), SIGNAL(changed(bool)));
topLayout->addWidget(m_config);
}
else
#endif
{
m_legacyConfig = new LegacyRandRConfig(this, m_display);
connect(m_legacyConfig, SIGNAL(changed(bool)), SIGNAL(changed(bool)));
topLayout->addWidget(m_legacyConfig);
}
m_config = new RandRConfig(this, m_display);
connect(m_config, SIGNAL(changed(bool)), SIGNAL(changed(bool)));
topLayout->addWidget(m_config);
//topLayout->addStretch(1);
// topLayout->addStretch(1);
setButtons(KCModule::Apply);
setButtons(KCModule::Apply);
kapp->installX11EventFilter( this );
kapp->installX11EventFilter( this );
}
KRandRModule::~KRandRModule(void)
{
delete m_display;
delete m_display;
}
void KRandRModule::defaults()
{
if (!m_display->isValid()) {
return;
}
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
m_config->defaults();
else
#endif
m_legacyConfig->defaults();
if (!m_display->isValid()) {
return;
}
m_config->defaults();
}
void KRandRModule::load()
{
kDebug() << "Loading KRandRModule...";
if (!m_display->isValid()) {
return;
}
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
m_config->load();
else
#endif
m_legacyConfig->load();
kDebug() << "Loading KRandRModule...";
emit changed(false);
if (!m_display->isValid()) {
return;
}
m_config->load();
emit changed(false);
}
void KRandRModule::save()
{
if (!m_display->isValid()) {
return;
}
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
m_config->save();
else
#endif
m_legacyConfig->save();
if (!m_display->isValid()) {
return;
}
m_config->save();
}
void KRandRModule::apply()
{
if (!m_display->isValid()) {
return;
}
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
m_config->apply();
else
#endif
m_legacyConfig->apply();
if (!m_display->isValid()) {
return;
}
m_config->apply();
}
bool KRandRModule::x11Event(XEvent* e)
{
if (m_display->canHandle(e)) {
m_display->handleEvent(e);
}
return QWidget::x11Event(e);
if (m_display->canHandle(e)) {
m_display->handleEvent(e);
}
return QWidget::x11Event(e);
}
#include "moc_krandrmodule.cpp"

View file

@ -26,30 +26,27 @@
#include <KCModule>
class RandRDisplay;
class LegacyRandRConfig;
class RandRConfig;
class KRandRModule : public KCModule
{
Q_OBJECT
Q_OBJECT
public:
KRandRModule(QWidget *parent, const QVariantList& _args);
~KRandRModule(void);
KRandRModule(QWidget *parent, const QVariantList& _args);
~KRandRModule(void);
virtual void load();
virtual void save();
virtual void defaults();
virtual bool x11Event(XEvent* );
virtual void load();
virtual void save();
virtual void defaults();
virtual bool x11Event(XEvent* );
protected:
void apply();
void update();
void apply();
void update();
private:
LegacyRandRConfig *m_legacyConfig;
RandRConfig *m_config;
RandRDisplay *m_display;
RandRConfig *m_config;
RandRDisplay *m_display;
};
#endif
#endif // KRANDRMODULE_H

View file

@ -31,14 +31,14 @@
KRandrPassivePopup::KRandrPassivePopup( QWidget *parent, Qt::WFlags f )
: KPassivePopup( parent, f )
{
{
update_timer.setSingleShot( true );
connect( &update_timer, SIGNAL(timeout()), SLOT(slotPositionSelf()));
}
}
KRandrPassivePopup* KRandrPassivePopup::message( const QString &caption, const QString &text,
const QPixmap &icon, QWidget *parent, int timeout )
{
{
KRandrPassivePopup *pop = new KRandrPassivePopup( parent );
pop->setAutoDelete( true );
pop->setView( caption, text, icon );
@ -46,78 +46,79 @@ KRandrPassivePopup* KRandrPassivePopup::message( const QString &caption, const Q
pop->show();
pop->startWatchingWidget( parent );
return pop;
}
}
void KRandrPassivePopup::startWatchingWidget( QWidget* widget_P )
{
static Atom wm_state = XInternAtom( QX11Info::display() , "WM_STATE", False );
Window win = widget_P->winId();
bool x11_events = false;
for(;;)
{
Window root, parent;
Window* children;
unsigned int nchildren;
XQueryTree( QX11Info::display(), 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( QX11Info::display(), win, &attrs );
XSelectInput( QX11Info::display(), 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( QX11Info::display(), 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 );
for(;;) {
Window root, parent;
Window* children;
unsigned int nchildren;
XQueryTree( QX11Info::display(), 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( QX11Info::display(), win, &attrs );
XSelectInput( QX11Info::display(), 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( QX11Info::display(), 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 )))
&& watched_widgets.contains( static_cast< QWidget* >( o ))) {
QTimer::singleShot( 0, this, SLOT(slotPositionSelf()));
return false;
}
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 );
return false;
}
return KPassivePopup::x11Event( e );
{
if( e->type == ConfigureNotify && watched_windows.contains( e->xconfigure.window ) ) {
if( !update_timer.isActive() ) {
update_timer.start( 10 );
}
return false;
}
return KPassivePopup::x11Event( e );
}
void KRandrPassivePopup::slotPositionSelf()
{
{
positionSelf();
}
}
#include "moc_krandrpassivepopup.cpp"

View file

@ -29,22 +29,25 @@
class KRandrPassivePopup
: public KPassivePopup
{
{
Q_OBJECT
public:
static KRandrPassivePopup *message( const QString &caption, const QString &text,
const QPixmap &icon, QWidget *parent, int timeout = -1 );
protected:
virtual bool eventFilter( QObject* o, QEvent* e );
virtual bool x11Event( XEvent* e );
private Q_SLOTS:
void slotPositionSelf();
private:
KRandrPassivePopup( QWidget *parent=0, Qt::WFlags f=0 );
void startWatchingWidget( QWidget* w );
QList< QWidget* > watched_widgets;
QList< Window > watched_windows;
QTimer update_timer;
};
public:
static KRandrPassivePopup *message( const QString &caption, const QString &text,
const QPixmap &icon, QWidget *parent, int timeout = -1 );
#endif
protected:
virtual bool eventFilter( QObject* o, QEvent* e );
virtual bool x11Event( XEvent* e );
private Q_SLOTS:
void slotPositionSelf();
private:
KRandrPassivePopup( QWidget *parent=0, Qt::WFlags f=0 );
void startWatchingWidget( QWidget* w );
QList< QWidget* > watched_widgets;
QList< Window > watched_windows;
QTimer update_timer;
};
#endif // __RANDRPASSIVEPOPUP_H__

View file

@ -1,54 +0,0 @@
#!/bin/sh
#
# A script that is called from startkde. Does early setup of a configuration
# saved by krandr.
if test "$krandrrc_display_applyonstartup" = "true"; then
if test -n "$krandrrc_display_startupcommands"; then
# new way of simply storing the commands
eval "$krandrrc_display_startupcommands"
else
# backwards compatibility
# 4 screens is hopefully enough
for scrn in 0 1 2 3; do
args=
width="\$krandrrc_screen${scrn}_width" ; eval "width=$width"
height="\$krandrrc_screen${scrn}_height" ; eval "height=$height"
if test -n "${width}" -a -n "${height}"; then
args="$args -s ${width}x${height}"
fi
refresh="\$krandrrc_screen${scrn}_refresh" ; eval "refresh=$refresh"
if test -n "${refresh}"; then
args="$args -r ${refresh}"
fi
rotation="\$krandrrc_screen${scrn}_rotation" ; eval "rotation=$rotation"
if test -n "${rotation}"; then
case "${rotation}" in
0)
args="$args -o 0"
;;
90)
args="$args -o 1"
;;
180)
args="$args -o 2"
;;
270)
args="$args -o 3"
;;
esac
fi
reflectx="\$krandrrc_screen${scrn}_reflectx" ; eval "reflectx=$reflectx"
if test "${refrectx}" = "true"; then
args="$args -x"
fi
reflecty="\$krandrrc_screen${scrn}_reflecty" ; eval "reflecty=$reflecty"
if test "${refrecty}" = "true"; then
args="$args -y"
fi
if test -n "$args"; then
xrandr $args
fi
done
fi
fi

View file

@ -22,12 +22,9 @@
#include "krandrtray.h"
#include "krandrpassivepopup.h"
#include "moc_krandrtray.cpp"
#include "legacyrandrscreen.h"
#ifdef HAS_RANDR_1_2
#include "randrscreen.h"
#include "randroutput.h"
#include "randrmode.h"
#endif
#include <QtGui/qevent.h>
#include <QVariant>
@ -45,575 +42,409 @@
#include <KWindowSystem>
KRandRSystemTray::KRandRSystemTray(RandRDisplay *dpy, QWidget* parent)
: KStatusNotifierItem(parent),
m_help(new KHelpMenu(parent, KGlobal::mainComponent().aboutData(), false, actionCollection())),
m_display(dpy)
: KStatusNotifierItem(parent),
m_help(new KHelpMenu(parent, KGlobal::mainComponent().aboutData(), false, actionCollection())),
m_display(dpy)
{
setIconByName("preferences-desktop-display-randr");
setCategory(Hardware);
setIconByName("preferences-desktop-display-randr");
setCategory(Hardware);
m_menu = new KMenu(associatedWidget());
setContextMenu(m_menu);
setStatus(Active);
m_menu = new KMenu(associatedWidget());
setContextMenu(m_menu);
setStatus(Active);
//TODO: probably we need an about to show signal
connect(m_menu, SIGNAL(aboutToShow()), this, SLOT(slotPrepareMenu()));
m_display->refresh();
updateToolTip();
//TODO: probably we need an about to show signal
connect(m_menu, SIGNAL(aboutToShow()), this, SLOT(slotPrepareMenu()));
m_display->refresh();
updateToolTip();
OutputMap outputs = m_display->currentScreen()->outputs();
foreach(RandROutput *output, outputs)
{
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(slotPrepareMenu()));
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(updateToolTip()));
}
OutputMap outputs = m_display->currentScreen()->outputs();
foreach(RandROutput *output, outputs) {
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(slotPrepareMenu()));
connect(output, SIGNAL(outputChanged(RROutput,int)), this, SLOT(updateToolTip()));
}
}
KRandRSystemTray::~KRandRSystemTray()
{
if (m_kcm) {
delete m_kcm.data();
}
if (m_kcm) {
delete m_kcm.data();
}
}
void KRandRSystemTray::activate(const QPoint &pos)
{
Q_UNUSED(pos)
slotPrefs();
Q_UNUSED(pos)
slotPrefs();
}
void KRandRSystemTray::slotPrepareMenu()
{
QAction *action;
QAction *action;
m_menu->clear();
m_menu->clear();
if (!m_display->isValid())
{
action = m_menu->addAction(i18n("Required X Extension Not Available"));
action->setEnabled(false);
if (!m_display->isValid()) {
action = m_menu->addAction(i18n("Required X Extension Not Available"));
action->setEnabled(false);
} else {
m_screenPopups.clear();
for (int s = 0; s < m_display->numScreens(); s++) {
m_display->setCurrentScreen(s);
if (s == QX11Info::appScreen()) {
/*lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1));
menu->setItemEnabled(lastIndex, false);*/
} else {
KMenu* subMenu = new KMenu(i18n("Screen %1", s+1), m_menu );
subMenu->setObjectName( QString("screen%1").arg(s+1) );
m_screenPopups.append(subMenu);
populateMenu(subMenu);
action = m_menu->addMenu(subMenu);
connect(subMenu, SIGNAL(activated(int)), SLOT(slotScreenActivated()));
}
}
}
else
{
m_screenPopups.clear();
for (int s = 0; s < m_display->numScreens(); s++)
{
m_display->setCurrentScreen(s);
if (s == QX11Info::appScreen())
{
/*lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1));
menu->setItemEnabled(lastIndex, false);*/
}
else
{
KMenu* subMenu = new KMenu(i18n("Screen %1", s+1), m_menu );
subMenu->setObjectName( QString("screen%1").arg(s+1) );
m_screenPopups.append(subMenu);
populateMenu(subMenu);
action = m_menu->addMenu(subMenu);
connect(subMenu, SIGNAL(activated(int)), SLOT(slotScreenActivated()));
}
}
m_display->setCurrentScreen(m_display->screenIndexOfWidget(m_menu));
if (m_display->needsRefresh()) {
kDebug() << "Configuration dirty, reloading settings...";
m_display->refresh();
updateToolTip();
}
m_display->setCurrentScreen(m_display->screenIndexOfWidget(m_menu));
if (m_display->needsRefresh()) {
kDebug() << "Configuration dirty, reloading settings...";
m_display->refresh();
updateToolTip();
}
populateMenu(m_menu);
}
populateMenu(m_menu);
}
m_menu->addSeparator();
m_menu->addSeparator();
KAction *actPrefs = actionCollection()->addAction( QString() );
actPrefs->setIcon( KIcon( "configure" ) );
actPrefs->setText( i18n( "Configure Display..." ) );
KAction *actPrefs = actionCollection()->addAction( QString() );
actPrefs->setIcon( KIcon( "configure" ) );
actPrefs->setText( i18n( "Configure Display..." ) );
connect( actPrefs, SIGNAL(triggered(bool)), SLOT(slotPrefs()) );
m_menu->addAction( actPrefs );
connect( actPrefs, SIGNAL(triggered(bool)), SLOT(slotPrefs()) );
m_menu->addAction( actPrefs );
m_menu->addMenu(/*SmallIcon("help-contents"),KStandardGuiItem::help().text(),*/ m_help->menu());
QAction *quitAction = actionCollection()->action(KStandardAction::name(KStandardAction::Quit));
m_menu->addAction( quitAction );
m_menu->addMenu(/*SmallIcon("help-contents"),KStandardGuiItem::help().text(),*/ m_help->menu());
QAction *quitAction = actionCollection()->action(KStandardAction::name(KStandardAction::Quit));
m_menu->addAction( quitAction );
}
void KRandRSystemTray::slotScreenActivated()
{
m_display->setCurrentScreen(m_screenPopups.indexOf(static_cast<KMenu*>(sender())));
m_display->setCurrentScreen(m_screenPopups.indexOf(static_cast<KMenu*>(sender())));
}
void KRandRSystemTray::updateToolTip()
{
const QString icon = "preferences-desktop-display-randr";
QString title = i18n("Display");
QString subTitle = i18n("Resize, rotate and configure screens.");
#ifdef HAS_RANDR_1_2
if (m_display->isValid())
{
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0)
return;
const QString icon = "preferences-desktop-display-randr";
QString title = i18n("Display");
QString subTitle = i18n("Resize, rotate and configure screens.");
if (m_display->isValid()) {
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0) {
return;
}
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
if (screen->outputsUnified() && screen->connectedCount() > 1)
{
SizeList sizes = screen->unifiedSizes();
if (!sizes.isEmpty())
{
const QSize currentSize = screen->rect().size();
subTitle = i18n("Resolution: %1 x %2",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0)
{
int rotation = RandR::Rotate0;
foreach (RandROutput *output, screen->outputs())
if (output->isActive())
{
rotation = output->rotation();
break;
}
if (screen->outputsUnified() && screen->connectedCount() > 1) {
SizeList sizes = screen->unifiedSizes();
if (!sizes.isEmpty()) {
const QSize currentSize = screen->rect().size();
subTitle = i18n("Resolution: %1 x %2",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0) {
int rotation = RandR::Rotate0;
foreach (RandROutput *output, screen->outputs()) {
if (output->isActive()) {
rotation = output->rotation();
break;
}
}
if (rotation != RandR::Rotate0)
subTitle += "<br>" + i18n("Rotation: %1", RandR::rotationName(1 << rotation));
}
}
}
else
{
QString details = "<table>";
bool first = true;
foreach(RandROutput *output, outputs)
{
if (output->isConnected())
{
if (!output->isActive()) {
details += "<tr><td>&nbsp;</td></tr>";
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ " (" + i18n("Disabled") + ") </th></tr>";
} else {
if (first)
{
first = false;
details += "<tr><td>&nbsp;</td></tr>";
}
else
{
details += "<tr><td>&nbsp;</td></tr>";
}
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ "</th></tr>";
if (rotation != RandR::Rotate0) {
subTitle += "<br>" + i18n("Rotation: %1", RandR::rotationName(1 << rotation));
}
}
}
} else {
QString details = "<table>";
bool first = true;
foreach(RandROutput *output, outputs) {
if (output->isConnected()) {
if (!output->isActive()) {
details += "<tr><td>&nbsp;</td></tr>";
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ " (" + i18n("Disabled") + ") </th></tr>";
} else {
if (first) {
first = false;
details += "<tr><td>&nbsp;</td></tr>";
} else {
details += "<tr><td>&nbsp;</td></tr>";
}
details += "<tr><th align=\"left\" colspan=\"2\">" + output->name()
+ "</th></tr>";
QSize currentSize = output->rect().size();
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270))
currentSize = QSize(currentSize.height(), currentSize.width());
QSize currentSize = output->rect().size();
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270)) {
currentSize = QSize(currentSize.height(), currentSize.width());
}
details += "<tr>" + i18n("<td align=\"right\">Resolution: </td><td>%1 x %2</td></tr>",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
RateList rates = output->refreshRates();
if (rates.count()) {
details += "<tr><td align=\"right\">" + i18n("Refresh: ") + "</td><td>"
+ ki18n("%1 Hz").subs(output->refreshRate(), 0, 'f', 1).toString()
+ "</td></tr>";
}
details += "<tr>" + i18n("<td align=\"right\">Resolution: </td><td>%1 x %2</td></tr>",
QString::number(currentSize.width()),
QString::number(currentSize.height()));
RateList rates = output->refreshRates();
if (rates.count())
{
details += "<tr><td align=\"right\">" + i18n("Refresh: ") + "</td><td>"
+ ki18n("%1 Hz").subs(output->refreshRate(), 0, 'f', 1).toString()
+ "</td></tr>";
}
int rotations = output->rotations();
if (rotations != RandR::Rotate0 && output->rotation() != RandR::Rotate0) {
details += "<tr><td align=\"right\">" + i18n("Rotation: ") + "</td><td>"
+ RandR::rotationName(1 << output->rotation())
+ "</td></tr>";
}
}
}
}
int rotations = output->rotations();
if (rotations != RandR::Rotate0 &&
output->rotation() != RandR::Rotate0)
{
details += "<tr><td align=\"right\">" + i18n("Rotation: ") + "</td><td>"
+ RandR::rotationName(1 << output->rotation())
+ "</td></tr>";
}
}
}
}
if (details != "<table>") {
subTitle = details + "</table>";
}
}
}
if (details != "<table>")
{
subTitle = details + "</table>";
}
}
}
#endif
setToolTip(icon, title, subTitle);
setToolTip(icon, title, subTitle);
}
void KRandRSystemTray::configChanged()
{
m_display->refresh();
updateToolTip();
static bool first = true;
m_display->refresh();
updateToolTip();
static bool first = true;
if (!first)
{
QString message;
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
// TODO: display config changed message
message = "Screen config changed";
else
#endif
message = m_display->currentLegacyScreen()->changedMessage();
if (!first) {
// TODO: display config changed message
QString message = "Screen config changed";
KRandrPassivePopup::message(
i18n("Screen configuration has changed"),
message, SmallIcon("view-fullscreen"),
associatedWidget());
}
KRandrPassivePopup::message(
i18n("Screen configuration has changed"),
message, SmallIcon("view-fullscreen"),
associatedWidget()
);
}
first = false;
first = false;
}
void KRandRSystemTray::populateMenu(KMenu* menu)
{
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
{
QAction *action;
QActionGroup *actionGroup;
QAction *action;
QActionGroup *actionGroup;
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0)
return;
OutputMap outputs = m_display->currentScreen()->outputs();
if (outputs.count() <= 0) {
return;
}
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
RandRScreen *screen = m_display->currentScreen();
Q_ASSERT(screen);
// if the outputs are unified, do not show output-specific size
// changing options in the tray.
if (screen->outputsUnified() && screen->connectedCount() > 1)
{
SizeList sizes = screen->unifiedSizes();
if (sizes.count())
{
// populate unified sizes
QSize currentSize;
currentSize = screen->rect().size();
// if the outputs are unified, do not show output-specific size
// changing options in the tray.
if (screen->outputsUnified() && screen->connectedCount() > 1) {
SizeList sizes = screen->unifiedSizes();
if (sizes.count()) {
// populate unified sizes
QSize currentSize;
currentSize = screen->rect().size();
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Screen Size"));
actionGroup = populateSizes(menu, sizes, currentSize);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotResizeUnified(QAction*)));
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Screen Size"));
actionGroup = populateSizes(menu, sizes, currentSize);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotResizeUnified(QAction*)));
// if the outputs are unified, we can rotate the screen on all outputs
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0)
{
menu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
int rotation = RandR::Rotate0;
foreach(RandROutput *output, screen->outputs())
if (output->isActive())
{
rotation = output->rotation();
break;
}
// if the outputs are unified, we can rotate the screen on all outputs
int rotations = screen->unifiedRotations();
if (rotations != RandR::Rotate0) {
menu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
int rotation = RandR::Rotate0;
foreach(RandROutput *output, screen->outputs()) {
if (output->isActive()) {
rotation = output->rotation();
break;
}
}
actionGroup = populateRotations(menu, rotations, rotation);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotRotateUnified(QAction*)));
}
}
}
else
{
if (screen->connectedCount() != 1)
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Outputs"));
actionGroup = populateRotations(menu, rotations, rotation);
connect(actionGroup, SIGNAL(triggered(QAction*)), screen, SLOT(slotRotateUnified(QAction*)));
}
}
} else {
if (screen->connectedCount() != 1) {
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Outputs"));
}
#ifdef HAS_RANDR_1_3
RandROutput *primary = screen->primaryOutput();
#endif //HAS_RANDR_1_3
RandROutput *primary = screen->primaryOutput();
foreach(RandROutput *output, outputs)
{
if (output->isConnected())
{
KMenu *outputMenu;
if (screen->connectedCount() == 1)
outputMenu = menu;
else
outputMenu = new KMenu(output->name());
outputMenu->setIcon(SmallIcon(output->icon()));
outputMenu->addTitle(SmallIcon("view-fullscreen"), i18n("%1 - Screen Size", output->name()));
foreach(RandROutput *output, outputs) {
if (output->isConnected()) {
KMenu *outputMenu;
if (screen->connectedCount() == 1) {
outputMenu = menu;
} else {
outputMenu = new KMenu(output->name());
}
outputMenu->setIcon(SmallIcon(output->icon()));
outputMenu->addTitle(SmallIcon("view-fullscreen"), i18n("%1 - Screen Size", output->name()));
QSize currentSize = output->rect().size();
QSize currentSize = output->rect().size();
// if the output is rotated 90 or 270, the returned rect is inverted
// so we need to invert the size before comparing
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270))
currentSize = QSize(currentSize.height(), currentSize.width());
// if the output is rotated 90 or 270, the returned rect is inverted
// so we need to invert the size before comparing
if (output->rotation() & (RandR::Rotate90 | RandR::Rotate270)) {
currentSize = QSize(currentSize.height(), currentSize.width());
}
actionGroup = populateSizes(outputMenu, output->sizes(), currentSize);
connect(actionGroup, SIGNAL(triggered(QAction*)), output, SLOT(slotChangeSize(QAction*)));
// if there is only one output active, do not show the disable option
// this prevents the user from doing wrong things ;)
kDebug() << "Active outputs: " << screen->activeCount();
if (screen->activeCount() != 1)
{
action = outputMenu->addAction(i18n("Disable"));
if (!output->crtc())
{
QFont font = action->font();
font.setBold(true);
action->setFont(font);
}
connect(action, SIGNAL(triggered(bool)), output, SLOT(slotDisable()));
}
actionGroup = populateSizes(outputMenu, output->sizes(), currentSize);
connect(actionGroup, SIGNAL(triggered(QAction*)), output, SLOT(slotChangeSize(QAction*)));
// if there is only one output active, do not show the disable option
// this prevents the user from doing wrong things ;)
kDebug() << "Active outputs: " << screen->activeCount();
if (screen->activeCount() != 1) {
action = outputMenu->addAction(i18n("Disable"));
if (!output->crtc()) {
QFont font = action->font();
font.setBold(true);
action->setFont(font);
}
connect(action, SIGNAL(triggered(bool)), output, SLOT(slotDisable()));
}
// Display the rotations
int rotations = output->rotations();
// Don't display the rotation options if there is no point (ie. none are supported)
// XFree86 4.3 does not include rotation support.
if (rotations != RandR::Rotate0)
{
outputMenu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
actionGroup = populateRotations(outputMenu, rotations, output->rotation());
connect(actionGroup, SIGNAL(triggered(QAction*)),
output, SLOT(slotChangeRotation(QAction*)));
}
// Display the rotations
int rotations = output->rotations();
// Don't display the rotation options if there is no point (ie. none are supported)
// XFree86 4.3 does not include rotation support.
if (rotations != RandR::Rotate0) {
outputMenu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
actionGroup = populateRotations(outputMenu, rotations, output->rotation());
connect(actionGroup, SIGNAL(triggered(QAction*)), output, SLOT(slotChangeRotation(QAction*)));
}
// refresh rate
RateList rates = output->refreshRates();
if (rates.count())
{
outputMenu->addTitle(SmallIcon("chronometer"), i18n("Refresh Rate"));
actionGroup = populateRates(outputMenu, rates, output->refreshRate());
connect(actionGroup, SIGNAL(triggered(QAction*)),
output, SLOT(slotChangeRefreshRate(QAction*)));
}
// refresh rate
RateList rates = output->refreshRates();
if (rates.count()) {
outputMenu->addTitle(SmallIcon("chronometer"), i18n("Refresh Rate"));
actionGroup = populateRates(outputMenu, rates, output->refreshRate());
connect(actionGroup, SIGNAL(triggered(QAction*)), output, SLOT(slotChangeRefreshRate(QAction*)));
}
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3 && screen->connectedCount() != 1)
{
outputMenu->addSeparator();
action = outputMenu->addAction(
i18nc("(checkbox) designate this output as the primary output", "Primary output"),
output,
SLOT(slotSetAsPrimary(bool)) );
action->setCheckable(true);
action->setChecked(primary == output);
}
#endif //HAS_RANDR_1_3
if (screen->connectedCount() != 1) {
outputMenu->addSeparator();
action = outputMenu->addAction(
i18nc("(checkbox) designate this output as the primary output", "Primary output"),
output,
SLOT(slotSetAsPrimary(bool))
);
action->setCheckable(true);
action->setChecked(primary == output);
}
if (screen->connectedCount() != 1)
menu->addMenu(outputMenu);
}
}
}
// if there is more than one output connected, give the option to unify the outputs
if (screen->connectedCount() != 1 && !screen->unifiedSizes().isEmpty())
{
menu->addSeparator();
action = menu->addAction( i18n("Unify Outputs"), screen, SLOT(slotUnifyOutputs(bool)) );
action->setCheckable(true);
action->setChecked(screen->outputsUnified());
}
}
else
#endif
populateLegacyMenu(menu);
}
void KRandRSystemTray::populateLegacyMenu(KMenu* menu)
{
menu->addTitle(SmallIcon("view-fullscreen"), i18n("Screen Size"));
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
// add sizes
QActionGroup *screenSizeGroup = populateSizes(menu, RandR::sortSizes(screen->pixelSizes()), screen->currentPixelSize());
connect(screenSizeGroup, SIGNAL(triggered(QAction*)), SLOT(slotResolutionChanged(QAction*)));
// Don't display the rotation options if there is no point (ie. none are supported)
// XFree86 4.3 does not include rotation support.
if (screen->rotations() != RandR::Rotate0)
{
menu->addTitle(SmallIcon("view-refresh"), i18n("Orientation"));
QActionGroup *rotationGroup = populateRotations(menu, screen->rotations(), screen->rotation());
connect(rotationGroup, SIGNAL(triggered(QAction*)), SLOT(slotOrientationChanged(QAction*)));
}
RateList rr = screen->refreshRates(screen->proposedSize());
if (rr.count())
{
menu->addTitle(SmallIcon("clock"), i18n("Refresh Rate"));
QActionGroup *rateGroup = populateRates(menu, rr, screen->refreshRate());
connect(rateGroup, SIGNAL(triggered(QAction*)), SLOT(slotRefreshRateChanged(QAction*)));
}
if (screen->connectedCount() != 1) {
menu->addMenu(outputMenu);
}
}
}
}
// if there is more than one output connected, give the option to unify the outputs
if (screen->connectedCount() != 1 && !screen->unifiedSizes().isEmpty()) {
menu->addSeparator();
action = menu->addAction( i18n("Unify Outputs"), screen, SLOT(slotUnifyOutputs(bool)) );
action->setCheckable(true);
action->setChecked(screen->outputsUnified());
}
}
QActionGroup *KRandRSystemTray::populateRotations(KMenu *menu, int rotations, int rotation)
{
QAction *action;
QActionGroup *rotateGroup = new QActionGroup(menu);
rotateGroup->setExclusive(true);
QAction *action;
QActionGroup *rotateGroup = new QActionGroup(menu);
rotateGroup->setExclusive(true);
for (int i = 0; i < 6; i++)
{
if ((1 << i) & rotations)
{
action = menu->addAction(QIcon(RandR::rotationIcon(1 << i, rotation)),
RandR::rotationName(1 << i));
action->setCheckable(true);
for (int i = 0; i < 6; i++) {
if ((1 << i) & rotations) {
action = menu->addAction(QIcon(RandR::rotationIcon(1 << i, rotation)), RandR::rotationName(1 << i));
action->setCheckable(true);
action->setData(1 << i);
if (rotation & (1 << i))
{
action->setChecked(true);
}
rotateGroup->addAction(action);
}
}
return rotateGroup;
action->setData(1 << i);
if (rotation & (1 << i)) {
action->setChecked(true);
}
rotateGroup->addAction(action);
}
}
return rotateGroup;
}
QActionGroup *KRandRSystemTray::populateSizes(KMenu *menu, const SizeList &sizes, const QSize &size)
{
QAction *action;
QActionGroup *sizeGroup = new QActionGroup(menu);
sizeGroup->setExclusive(true);
for (int i = 0; i < sizes.count(); ++i)
{
QSize s = sizes[i];
action = menu->addAction(QString("%1 x %2").arg(s.width()).arg(s.height()));
action->setCheckable(true);
action->setData(s);
if (s == size)
{
action->setChecked(true);
}
sizeGroup->addAction(action);
}
return sizeGroup;
QAction *action;
QActionGroup *sizeGroup = new QActionGroup(menu);
sizeGroup->setExclusive(true);
for (int i = 0; i < sizes.count(); ++i) {
QSize s = sizes[i];
action = menu->addAction(QString("%1 x %2").arg(s.width()).arg(s.height()));
action->setCheckable(true);
action->setData(s);
if (s == size) {
action->setChecked(true);
}
sizeGroup->addAction(action);
}
return sizeGroup;
}
QActionGroup *KRandRSystemTray::populateRates(KMenu *menu, const RateList &rates, float rate)
{
QAction *action;
QActionGroup *rateGroup = new QActionGroup(menu);
rateGroup->setExclusive(true);
QAction *action;
QActionGroup *rateGroup = new QActionGroup(menu);
rateGroup->setExclusive(true);
foreach(float r, rates)
{
action = menu->addAction(ki18n("%1 Hz").subs(r, 0, 'f', 1).toString());
action->setCheckable(true);
action->setData(r);
if (r == rate)
{
action->setChecked(true);
}
rateGroup->addAction(action);
}
return rateGroup;
}
void KRandRSystemTray::slotResolutionChanged(QAction *action)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
QSize s = action->data().toSize();
int index = 0;
const SizeList pixelSizes = screen->pixelSizes();
for (int i = 0; i < pixelSizes.count(); ++i)
if (pixelSizes[i] == s)
{
index = i;
break;
}
if (screen->size() == index)
return;
screen->proposeSize(index);
screen->proposeRefreshRate(-1);
if (screen->applyProposedAndConfirm())
{
KConfig config("krandrrc");
if (m_display->syncTrayApp(config))
screen->save(config);
}
}
void KRandRSystemTray::slotOrientationChanged(QAction *action)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
int propose = screen->rotation();
int rotate = action->data().toInt();
if (rotate & RandR::RotateMask)
propose &= RandR::ReflectMask;
propose ^= rotate;
if (screen->rotation() == propose)
return;
screen->proposeRotation(propose);
if (screen->applyProposedAndConfirm())
{
KConfig config("krandrrc");
if (m_display->syncTrayApp(config))
screen->save(config);
}
}
void KRandRSystemTray::slotRefreshRateChanged(QAction *action)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
int index = action->data().toInt();
if (screen->refreshRate() == index)
return;
screen->proposeRefreshRate(index);
if (screen->applyProposedAndConfirm())
{
KConfig config("krandrrc");
if (m_display->syncTrayApp(config))
screen->save(config);
}
foreach(float r, rates) {
action = menu->addAction(ki18n("%1 Hz").subs(r, 0, 'f', 1).toString());
action->setCheckable(true);
action->setData(r);
if (r == rate) {
action->setChecked(true);
}
rateGroup->addAction(action);
}
return rateGroup;
}
void KRandRSystemTray::slotPrefs()
{
if (!m_kcm)
{
KCMultiDialog *kcm = new KCMultiDialog( associatedWidget() );
kcm->setFaceType( KCMultiDialog::Plain );
kcm->setWindowTitle( i18n( "Configure Display" ) );
kcm->addModule( "display" );
kcm->setAttribute(Qt::WA_DeleteOnClose);
m_kcm = kcm;
} else if (KWindowSystem::activeWindow() == m_kcm.data()->winId()) {
m_kcm.data()->hide();
return;
}
if (!m_kcm) {
KCMultiDialog *kcm = new KCMultiDialog( associatedWidget() );
kcm->setFaceType( KCMultiDialog::Plain );
kcm->setWindowTitle( i18n( "Configure Display" ) );
kcm->addModule( "display" );
kcm->setAttribute(Qt::WA_DeleteOnClose);
m_kcm = kcm;
} else if (KWindowSystem::activeWindow() == m_kcm.data()->winId()) {
m_kcm.data()->hide();
return;
}
KWindowSystem::setOnDesktop(m_kcm.data()->winId(), KWindowSystem::currentDesktop());
m_kcm.data()->show();
m_kcm.data()->raise();
KWindowSystem::forceActiveWindow(m_kcm.data()->winId());
KWindowSystem::setOnDesktop(m_kcm.data()->winId(), KWindowSystem::currentDesktop());
m_kcm.data()->show();
m_kcm.data()->raise();
KWindowSystem::forceActiveWindow(m_kcm.data()->winId());
}
// vim:noet:sts=8:sw=8:

View file

@ -21,52 +21,47 @@
#include <QtGui/qevent.h>
#include <QtCore/qsharedpointer.h>
#include <QAction>
#include <QActionGroup>
#include <KStatusNotifierItem>
#include "randrdisplay.h"
#include <QAction>
#include <QActionGroup>
class KCMultiDialog;
class KHelpMenu;
class KMenu;
class KRandRSystemTray : public KStatusNotifierItem
{
Q_OBJECT
Q_OBJECT
public:
explicit KRandRSystemTray(RandRDisplay *dpy, QWidget* parent = 0);
~KRandRSystemTray();
explicit KRandRSystemTray(RandRDisplay *dpy, QWidget* parent = 0);
~KRandRSystemTray();
void configChanged();
void activate(const QPoint &pos);
void configChanged();
void activate(const QPoint &pos);
protected Q_SLOTS:
void slotScreenActivated();
void slotResolutionChanged(QAction *action);
void slotOrientationChanged(QAction *action);
void slotRefreshRateChanged(QAction *action);
void slotPrefs();
void slotScreenActivated();
void slotPrefs();
void slotPrepareMenu();
void updateToolTip();
void slotPrepareMenu();
void updateToolTip();
private:
void populateMenu(KMenu* menu);
void populateLegacyMenu(KMenu* menu);
void populateMenu(KMenu* menu);
// helper functions
QActionGroup *populateRotations(KMenu *menu, int rotations, int rotation);
QActionGroup *populateSizes(KMenu *menu, const SizeList &sizes, const QSize &size);
QActionGroup *populateRates(KMenu *menu, const RateList &rates, float rate);
// helper functions
QActionGroup *populateRotations(KMenu *menu, int rotations, int rotation);
QActionGroup *populateSizes(KMenu *menu, const SizeList &sizes, const QSize &size);
QActionGroup *populateRates(KMenu *menu, const RateList &rates, float rate);
KHelpMenu* m_help;
QList<KMenu*> m_screenPopups;
KMenu* m_menu;
RandRDisplay *m_display;
QWeakPointer<KCMultiDialog> m_kcm;
KHelpMenu* m_help;
QList<KMenu*> m_screenPopups;
KMenu* m_menu;
RandRDisplay *m_display;
QWeakPointer<KCMultiDialog> m_kcm;
};
#endif
#endif // KRANDRTRAY_H

View file

@ -64,10 +64,11 @@ KTimerDialog::KTimerDialog( int msec, TimerStyle style, QWidget *parent,
msecTotal = msecRemaining = msec;
updateInterval = 1000;
tStyle = style;
KWindowSystem::setIcons( winId(), DesktopIcon("preferences-desktop-display-randr"), SmallIcon("preferences-desktop-display-randr") );
KWindowSystem::setIcons( winId(), DesktopIcon("preferences-desktop-display-randr"), SmallIcon("preferences-desktop-display-randr") );
// default to canceling the dialog on timeout
if ( buttonMask & Cancel )
if ( buttonMask & Cancel ) {
buttonOnTimeout = Cancel;
}
connect( totalTimer, SIGNAL(timeout()), SLOT(slotInternalTimeout()) );
connect( updateTimer, SIGNAL(timeout()), SLOT(slotUpdateTime()) );
@ -124,8 +125,9 @@ void KTimerDialog::setMainWidget( QWidget *widget )
void KTimerDialog::setRefreshInterval( int msec )
{
updateInterval = msec;
if ( updateTimer->isActive() )
if ( updateTimer->isActive() ) {
updateTimer->start( updateInterval );
}
}
int KTimerDialog::timeoutButton() const

View file

@ -27,10 +27,11 @@
#include <kvbox.h>
#include <QTimer>
class KHBox;
#include <QProgressBar>
#include <QLabel>
class KHBox;
/**
* Provides a dialog that is only available for a specified amount
* of time, and reports the time remaining to the user.
@ -47,9 +48,8 @@ class KHBox;
*/
class KTimerDialog : public KDialog
{
Q_OBJECT
public:
Q_OBJECT
public:
/**
* @li @p CountDown - The timer counts downwards from the seconds given.
@ -122,19 +122,19 @@ class KTimerDialog : public KDialog
*/
void setMainWidget( QWidget *widget );
Q_SIGNALS:
Q_SIGNALS:
/**
* Signal which is emitted once the timer has timed out.
*/
void timerTimeout();
public Q_SLOTS:
public Q_SLOTS:
/**
* Execute the dialog modally - see @see QDialog .
*/
int exec();
private Q_SLOTS:
private Q_SLOTS:
/**
* Updates the dialog with the current progress levels.
*/
@ -145,7 +145,7 @@ class KTimerDialog : public KDialog
*/
void slotInternalTimeout();
private:
private:
/**
* Prepares the layout that manages the widgets of the dialog
*/
@ -167,7 +167,4 @@ class KTimerDialog : public KDialog
KTimerDialogPrivate *d;
};
#endif
#endif // _KTIMERDIALOG_H_

View file

@ -27,10 +27,10 @@
#include <math.h>
LayoutManager::LayoutManager(RandRScreen *screen, QGraphicsScene *scene)
: QObject(screen)
: QObject(screen)
{
m_screen = screen;
m_scene = scene;
m_screen = screen;
m_scene = scene;
}
LayoutManager::~LayoutManager()
@ -39,112 +39,101 @@ LayoutManager::~LayoutManager()
void LayoutManager::slotAdjustOutput(OutputGraphicsItem *output)
{
QPointF p = output->pos();
float nearest = m_scene->width() * m_scene->height();
OutputGraphicsItem *selected = NULL;
QPointF p = output->pos();
float nearest = m_scene->width() * m_scene->height();
OutputGraphicsItem *selected = NULL;
OutputGraphicsItem *mouseGrabber = dynamic_cast<OutputGraphicsItem*>(m_scene->mouseGrabberItem());
// find the nearest item
QList<QGraphicsItem *> itemList = m_scene->items();
OutputGraphicsItem *mouseGrabber = dynamic_cast<OutputGraphicsItem*>(m_scene->mouseGrabberItem());
// find the nearest item
QList<QGraphicsItem *> itemList = m_scene->items();
foreach(QGraphicsItem *current, itemList)
{
OutputGraphicsItem *cur = dynamic_cast<OutputGraphicsItem*>(current);
if (cur == output || cur == mouseGrabber)
continue;
foreach(QGraphicsItem *current, itemList) {
OutputGraphicsItem *cur = dynamic_cast<OutputGraphicsItem*>(current);
if (cur == output || cur == mouseGrabber) {
continue;
}
QPointF pos = cur->pos();
float distance = (p.x() - pos.x())*(p.x()-pos.x()) + (p.y() - pos.y())*(p.y() - pos.y());
if (distance <=nearest)
{
nearest = distance;
selected = cur;
}
}
QPointF pos = cur->pos();
float distance = (p.x() - pos.x())*(p.x()-pos.x()) + (p.y() - pos.y())*(p.y() - pos.y());
if (distance <=nearest) {
nearest = distance;
selected = cur;
}
}
if (selected)
{
// find in which side this
QRectF s = selected->boundingRect();
QRectF i = output->boundingRect();
if (selected) {
// find in which side this
QRectF s = selected->boundingRect();
QRectF i = output->boundingRect();
s.translate(selected->scenePos());
i.translate(output->scenePos());
s.translate(selected->scenePos());
i.translate(output->scenePos());
// calculate the distances
float top = fabsf(i.top() - s.bottom());
float bottom = fabsf(i.bottom() - s.top());
float left = fabsf(i.left() - s.right());
float right = fabsf(i.right() - s.left());
// calculate the distances
float top = fabsf(i.top() - s.bottom());
float bottom = fabsf(i.bottom() - s.top());
float left = fabsf(i.left() - s.right());
float right = fabsf(i.right() - s.left());
// choose top
if (top <= bottom && top <= left && top <= right)
{
output->setTop(selected);
selected->setBottom(output);
}
// choose bottom
else if (bottom < top && bottom <= left && bottom <= right)
{
output->setBottom(selected);
selected->setTop(output);
}
// choose left
else if (left < top && left < bottom && left <= right)
{
output->setLeft(selected);
selected->setRight(output);
}
// choose right
else
{
output->setRight(selected);
selected->setLeft(output);
}
}
// choose top
if (top <= bottom && top <= left && top <= right) {
output->setTop(selected);
selected->setBottom(output);
}
// choose bottom
else if (bottom < top && bottom <= left && bottom <= right) {
output->setBottom(selected);
selected->setTop(output);
}
// choose left
else if (left < top && left < bottom && left <= right) {
output->setLeft(selected);
selected->setRight(output);
}
// choose right
else {
output->setRight(selected);
selected->setLeft(output);
}
}
// now visit all the outputs on the screen to adjust their positions
// starting by the item selected to be the parent of the current item
QList<OutputGraphicsItem *> visitedList;
// now visit all the outputs on the screen to adjust their positions
// starting by the item selected to be the parent of the current item
QList<OutputGraphicsItem *> visitedList;
// FIXME: after adjusting the scene, we have to translate everything back to
// the 0,0 position so that everything is onscreen
output->setPos(0,0);
// call a recursive function to adjust the outputs
adjustScene(output, visitedList);
// FIXME: after adjusting the scene, we have to translate everything back to
// the 0,0 position so that everything is onscreen
output->setPos(0,0);
// call a recursive function to adjust the outputs
adjustScene(output, visitedList);
}
void LayoutManager::adjustScene(OutputGraphicsItem *current, QList<OutputGraphicsItem*> &visited)
{
visited.append(current);
visited.append(current);
OutputGraphicsItem *item;
item = current->left();
if (item && visited.indexOf(item) == -1)
{
item->setPos(current->x() - item->boundingRect().width(), current->y());
adjustScene(item, visited);
}
OutputGraphicsItem *item;
item = current->left();
if (item && visited.indexOf(item) == -1) {
item->setPos(current->x() - item->boundingRect().width(), current->y());
adjustScene(item, visited);
}
item = current->right();
if (item && visited.indexOf(item) == -1)
{
item->setPos(current->x() + current->boundingRect().width(), current->y());
adjustScene(item, visited);
}
item = current->right();
if (item && visited.indexOf(item) == -1) {
item->setPos(current->x() + current->boundingRect().width(), current->y());
adjustScene(item, visited);
}
item = current->top();
if (item && visited.indexOf(item) == -1)
{
item->setPos(current->x(), current->y() - item->boundingRect().height());
adjustScene(item, visited);
}
item = current->top();
if (item && visited.indexOf(item) == -1) {
item->setPos(current->x(), current->y() - item->boundingRect().height());
adjustScene(item, visited);
}
item = current->bottom();
if (item && visited.indexOf(item) == -1)
{
item->setPos(current->x(), current->y() + current->boundingRect().height());
adjustScene(item, visited);
}
item = current->bottom();
if (item && visited.indexOf(item) == -1) {
item->setPos(current->x(), current->y() + current->boundingRect().height());
adjustScene(item, visited);
}
}

View file

@ -20,29 +20,29 @@
#define __LAYOUTMANAGER_H__
#include <QObject>
#include <QGraphicsScene>
#include "randr.h"
class RandRScreen;
#include <QGraphicsScene>
class OutputGraphicsItem;
class LayoutManager : public QObject
{
Q_OBJECT
Q_OBJECT
public:
LayoutManager(RandRScreen *screen, QGraphicsScene *scene);
~LayoutManager();
LayoutManager(RandRScreen *screen, QGraphicsScene *scene);
~LayoutManager();
public slots:
void slotAdjustOutput(OutputGraphicsItem *output);
void slotAdjustOutput(OutputGraphicsItem *output);
protected:
void adjustScene(OutputGraphicsItem *current, QList<OutputGraphicsItem*> &visited);
void adjustScene(OutputGraphicsItem *current, QList<OutputGraphicsItem*> &visited);
private:
RandRScreen *m_screen;
QGraphicsScene *m_scene;
RandRScreen *m_screen;
QGraphicsScene *m_scene;
};
#endif
#endif // __LAYOUTMANAGER_H__

View file

@ -1,278 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002 Hamish Rodda <rodda@kde.org>
*
* 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 "legacyrandrconfig.h"
#include <QRadioButton>
#include "randrdisplay.h"
#include "legacyrandrscreen.h"
LegacyRandRConfig::LegacyRandRConfig(QWidget *parent, RandRDisplay *display)
: QWidget(parent), Ui::LegacyRandRConfigBase()
{
setupUi(this);
layout()->setMargin(0);
m_display = display;
Q_ASSERT(m_display);
if (!m_display->isValid())
return;
for (int s = 0; s < m_display->numScreens(); ++s)
screenCombo->addItem(i18n("Screen %1", s+1));
screenCombo->setCurrentIndex(m_display->currentScreenIndex());
if (m_display->numScreens() <= 1)
screenCombo->setEnabled(false);
new QGridLayout(rotationGroup);
// Create rotations
for (int i = 0; i < RandR::OrientationCount; i++)
addRotationButton(1 << i, i > RandR::RotationCount - 1);
connect(screenCombo, SIGNAL(activated(int)), SLOT(slotScreenChanged(int)));
connect(sizeCombo, SIGNAL(activated(int)), SLOT(slotSizeChanged(int)));
connect(rateCombo, SIGNAL(activated(int)), SLOT(slotRefreshChanged(int)));
connect(applyOnStartup, SIGNAL(clicked()), SLOT(setChanged()));
connect(syncTrayApp, SIGNAL(clicked()), SLOT(setChanged()));
load();
syncTrayApp->setEnabled(applyOnStartup->isChecked());
slotScreenChanged(m_display->currentScreenIndex());
}
LegacyRandRConfig::~LegacyRandRConfig()
{
}
void LegacyRandRConfig::load()
{
if (!m_display->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("krandrrc");
m_oldApply = m_display->loadDisplay(config, false);
m_oldSyncTrayApp = m_display->syncTrayApp(config);
applyOnStartup->setChecked(m_oldApply);
syncTrayApp->setChecked(m_oldSyncTrayApp);
setChanged();
}
void LegacyRandRConfig::save()
{
if (!m_display->isValid())
return;
apply();
m_oldApply = applyOnStartup->isChecked();
m_oldSyncTrayApp = syncTrayApp->isChecked();
KConfig config("krandrrc");
m_display->saveDisplay(config, m_oldSyncTrayApp);
if(m_oldApply)
m_display->saveStartup(config);
else
m_display->disableStartup(config);
setChanged();
}
void LegacyRandRConfig::defaults()
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
if (screen->changedFromOriginal()) {
screen->proposeOriginal();
screen->applyProposed();
} else {
screen->proposeOriginal();
}
update();
}
void LegacyRandRConfig::slotScreenChanged(int screenId)
{
m_display->setCurrentScreen(screenId);
// Clear resolutions
sizeCombo->clear();
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
// Add new resolutions
for (int i = 0; i < screen->numSizes(); i++) {
sizeCombo->addItem(QString("%1 x %2").arg(screen->pixelSize(i).width()).arg(screen->pixelSize(i).height()));
// Aspect ratio
/* , aspect ratio %5)*/
/*.arg((double)currentScreen()->size(i).mwidth / (double)currentScreen()->size(i).mheight))*/
}
// configure the possible rotations
for (int i = 0; i < RandR::OrientationCount; i++)
m_rotationGroup.button(1 << i)->setEnabled( (1 << i) & screen->rotations());
m_rotationGroup.button(screen->rotation())->setChecked(true);
populateRefreshRates();
update();
setChanged();
}
void LegacyRandRConfig::slotRotationChanged()
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
//FIXME: need to check this later
int id = m_rotationGroup.checkedId();
screen->proposeRotation(id);
setChanged();
}
void LegacyRandRConfig::slotSizeChanged(int index)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
int oldProposed = screen->proposedSize();
screen->proposeSize(index);
if (screen->proposedSize() != oldProposed) {
screen->proposeRefreshRate(0);
populateRefreshRates();
// Item with index zero is already selected
}
setChanged();
}
void LegacyRandRConfig::slotRefreshChanged(int index)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
screen->proposeRefreshRate(index);
setChanged();
}
void LegacyRandRConfig::setChanged()
{
bool isChanged = (m_oldApply != applyOnStartup->isChecked()) || (m_oldSyncTrayApp != syncTrayApp->isChecked());
syncTrayApp->setEnabled(applyOnStartup->isChecked());
if (!isChanged)
for (int screenIndex = 0; screenIndex < m_display->numScreens(); screenIndex++) {
if (m_display->legacyScreen(screenIndex)->proposedChanged()) {
isChanged = true;
break;
}
}
if (isChanged != m_changed) {
m_changed = isChanged;
emit changed(m_changed);
}
}
void LegacyRandRConfig::apply()
{
if (m_changed) {
m_display->applyProposed();
update();
}
}
void LegacyRandRConfig::update()
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
sizeCombo->blockSignals(true);
sizeCombo->setCurrentIndex(screen->proposedSize());
sizeCombo->blockSignals(false);
m_rotationGroup.blockSignals(true);
m_rotationGroup.button(screen->proposedRotation())->setChecked(true);
//m_rotationGroup.button(4)->setDown(screen->proposedRotation() & RandR::ReflectX);
//m_rotationGroup.button(5)->setDown(screen->proposedRotation() & RandR::ReflectY);
m_rotationGroup.blockSignals(false);
rateCombo->blockSignals(true);
rateCombo->setCurrentIndex(screen->proposedRefreshRate());
rateCombo->blockSignals(false);
}
void LegacyRandRConfig::addRotationButton(int thisRotation, bool checkbox)
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
if (!checkbox) {
QRadioButton* thisButton = new QRadioButton(RandR::rotationName(thisRotation), rotationGroup);
m_rotationGroup.addButton( thisButton, thisRotation );
thisButton->setEnabled(thisRotation & screen->rotations());
connect(thisButton, SIGNAL(clicked()), SLOT(slotRotationChanged()));
rotationGroup->layout()->addWidget(thisButton);
} else {
QCheckBox* thisButton = new QCheckBox(RandR::rotationName(thisRotation), rotationGroup);
m_rotationGroup.addButton( thisButton, thisRotation );
thisButton->setEnabled(thisRotation & screen->rotations());
connect(thisButton, SIGNAL(clicked()), SLOT(slotRotationChanged()));
rotationGroup->layout()->addWidget(thisButton);
}
}
void LegacyRandRConfig::populateRefreshRates()
{
LegacyRandRScreen *screen = m_display->currentLegacyScreen();
Q_ASSERT(screen);
rateCombo->clear();
RateList rr = screen->refreshRates(screen->proposedSize());
rateCombo->setEnabled(rr.count());
foreach(float rate, rr)
{
rateCombo->addItem(ki18n("%1 Hz").subs(rate, 0, 'f', 1).toString(), rate);
}
}
#include "moc_legacyrandrconfig.cpp"

View file

@ -1,65 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002 Hamish Rodda <rodda@kde.org>
*
* 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 __LEGACYRANDRCONFIG_H__
#define __LEGACYRANDRCONFIG_H__
#include <QButtonGroup>
#include <QWidget>
#include "ui_legacyrandrconfigbase.h"
class RandRDisplay;
class LegacyRandRConfig : public QWidget, public Ui::LegacyRandRConfigBase
{
Q_OBJECT
public:
LegacyRandRConfig(QWidget *parent, RandRDisplay *display);
virtual ~LegacyRandRConfig();
void load();
void save();
void defaults();
void apply();
void update();
protected Q_SLOTS:
void slotScreenChanged(int screen);
void slotRotationChanged();
void slotSizeChanged(int index);
void slotRefreshChanged(int index);
void setChanged();
signals:
void changed(bool c);
protected:
void addRotationButton(int thisRotation, bool checkbox);
void populateRefreshRates();
private:
RandRDisplay *m_display;
bool m_oldApply;
bool m_oldSyncTrayApp;
bool m_changed;
QButtonGroup m_rotationGroup;
};
#endif

View file

@ -1,145 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LegacyRandRConfigBase</class>
<widget class="QWidget" name="LegacyRandRConfigBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>469</width>
<height>292</height>
</rect>
</property>
<property name="windowTitle">
<string>Screen Resize and Rotate Settings</string>
</property>
<property name="whatsThis">
<string>If this option is enabled, options set by the system tray applet will be saved and loaded when KDE starts instead of being temporary.</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="screenLabel">
<property name="text">
<string>Settings for screen:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>screenCombo</cstring>
</property>
</widget>
</item>
<item>
<widget class="KComboBox" name="screenCombo">
<property name="whatsThis">
<string>The screen whose settings you would like to change can be selected using this drop-down list.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="sizeLabel">
<property name="text">
<string>Screen size:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>sizeCombo</cstring>
</property>
</widget>
</item>
<item>
<widget class="KComboBox" name="sizeCombo">
<property name="whatsThis">
<string>The size, otherwise known as the resolution, of your screen can be selected from this drop-down list.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="rateLabel">
<property name="text">
<string>Refresh rate:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="KComboBox" name="rateCombo">
<property name="whatsThis">
<string>The refresh rate of your screen can be selected from this drop-down list.</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="rotationGroup">
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="whatsThis">
<string>The options in this section allow you to change the rotation of your screen.</string>
</property>
<property name="title">
<string>Orientation (degrees counterclockwise)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="applyOnStartup">
<property name="whatsThis">
<string>If this option is enabled the size and orientation settings will be used when KDE starts.</string>
</property>
<property name="text">
<string>Apply settings on KDE startup</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="syncTrayApp">
<property name="text">
<string>Allow tray application to change startup settings</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
</customwidgets>
<connections/>
</ui>

View file

@ -1,422 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
*
* 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>
#include <QPixmap>
#include "ktimerdialog.h"
#include <kdebug.h>
#include <klocale.h>
#include <kglobal.h>
#include <kapplication.h>
#include <kiconloader.h>
#include <QtGui/QLabel>
#include <QDesktopWidget>
#include <QtGui/qx11info_x11.h>
#include "legacyrandrscreen.h"
LegacyRandRScreen::LegacyRandRScreen(int screenIndex)
: m_config(0L)
, m_screen(screenIndex)
{
loadSettings();
setOriginal();
}
LegacyRandRScreen::~LegacyRandRScreen()
{
if (m_config)
XRRFreeScreenConfigInfo(m_config);
}
void LegacyRandRScreen::loadSettings()
{
if (m_config)
XRRFreeScreenConfigInfo(m_config);
m_config = XRRGetScreenInfo(QX11Info::display(), rootWindow());
Q_ASSERT(m_config);
Rotation rotation;
m_currentSize = m_proposedSize = XRRConfigCurrentConfiguration(m_config, &rotation);
m_currentRotation = m_proposedRotation = rotation;
m_pixelSizes.clear();
m_mmSizes.clear();
int numSizes;
XRRScreenSize* sizes = XRRSizes(QX11Info::display(), 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(QX11Info::display(), m_screen, &rotation);
m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex(m_currentSize, XRRConfigCurrentRate(m_config));
}
void LegacyRandRScreen::setOriginal()
{
m_originalSize = m_currentSize;
m_originalRotation = m_currentRotation;
m_originalRefreshRate = m_currentRefreshRate;
}
bool LegacyRandRScreen::applyProposed()
{
//kDebug() << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate());
Status status;
if (proposedRefreshRate() < 0)
status = XRRSetScreenConfig(QX11Info::display(), m_config, rootWindow(), (SizeID)proposedSize(), (Rotation)proposedRotation(), CurrentTime);
else {
if( refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) <= 0 ) {
m_proposedRefreshRate = 0;
}
status = XRRSetScreenConfigAndRate(QX11Info::display(), m_config, rootWindow(), (SizeID)proposedSize(), (Rotation)proposedRotation(), refreshRateIndexToHz(proposedSize(), proposedRefreshRate()), CurrentTime);
}
//kDebug() << "New size: " << WidthOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen)) << ", " << HeightOfScreen(ScreenOfDisplay(QPaintDevice::x11AppDisplay(), screen));
if (status == RRSetConfigSuccess) {
m_currentSize = m_proposedSize;
m_currentRotation = m_proposedRotation;
m_currentRefreshRate = m_proposedRefreshRate;
return true;
}
return false;
}
bool LegacyRandRScreen::applyProposedAndConfirm()
{
if (proposedChanged()) {
setOriginal();
if (applyProposed()) {
if (!RandR::confirm()) {
proposeOriginal();
applyProposed();
return false;
}
} else {
return false;
}
}
return true;
}
Window LegacyRandRScreen::rootWindow() const
{
return RootWindow(QX11Info::display(), m_screen);
}
QString LegacyRandRScreen::changedMessage() const
{
if (refreshRate() == -1)
return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3",
currentPixelSize().width(),
currentPixelSize().height(),
currentRotationDescription());
else
return i18n("New configuration:\nResolution: %1 x %2\nOrientation: %3\nRefresh rate: %4",
currentPixelSize().width(),
currentPixelSize().height(),
currentRotationDescription(),
currentRefreshRateDescription());
}
bool LegacyRandRScreen::changedFromOriginal() const
{
return m_currentSize != m_originalSize || m_currentRotation != m_originalRotation || m_currentRefreshRate != m_originalRefreshRate;
}
void LegacyRandRScreen::proposeOriginal()
{
m_proposedSize = m_originalSize;
m_proposedRotation = m_originalRotation;
m_proposedRefreshRate = m_originalRefreshRate;
}
bool LegacyRandRScreen::proposedChanged() const
{
return m_currentSize != m_proposedSize || m_currentRotation != m_proposedRotation || m_currentRefreshRate != m_proposedRefreshRate;
}
QString LegacyRandRScreen::currentRotationDescription() const
{
QString ret = RandR::rotationName(m_currentRotation & RandR::RotateMask);
if (m_currentRotation != (m_currentRotation & RandR::RotateMask)) {
if (m_currentRotation & RR_Rotate_0)
ret = RandR::rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, true);
else
ret += ", " + RandR::rotationName(m_currentRotation & (RR_Reflect_X + RR_Reflect_X), true, false);
}
return ret;
}
int LegacyRandRScreen::rotationIndexToDegree(int rotation) const
{
switch (rotation & RandR::RotateMask) {
case RR_Rotate_90:
return 90;
case RR_Rotate_180:
return 180;
case RR_Rotate_270:
return 270;
default:
return 0;
}
}
int LegacyRandRScreen::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;
}
}
const QSize& LegacyRandRScreen::currentPixelSize() const
{
return m_pixelSizes[m_currentSize];
}
RateList LegacyRandRScreen::refreshRates(int size) const
{
int nrates;
short* rrates = XRRRates(QX11Info::display(), m_screen, (SizeID)size, &nrates);
RateList rateList;
for (int i = 0; i < nrates; i++)
rateList.append(rrates[i]);
return rateList;
}
QString LegacyRandRScreen::refreshRateDirectDescription(int rate) const
{
return i18nc("Refresh rate in Hertz (Hz)", "%1 Hz", rate);
}
QString LegacyRandRScreen::refreshRateIndirectDescription(int size, int index) const
{
return i18nc("Refresh rate in Hertz (Hz)", "%1 Hz", refreshRateIndexToHz(size, index));
}
QString LegacyRandRScreen::refreshRateDescription(int size, int index) const
{
return ki18n("%1 Hz").subs(refreshRates(size)[index], 0, 'f', 1).toString();
}
bool LegacyRandRScreen::proposeRefreshRate(int index)
{
if (index >= 0 && (int)refreshRates(proposedSize()).count() > index) {
m_proposedRefreshRate = index;
return true;
}
return false;
}
int LegacyRandRScreen::refreshRate() const
{
return m_currentRefreshRate;
}
QString LegacyRandRScreen::currentRefreshRateDescription() const
{
return refreshRateIndirectDescription(m_currentSize, m_currentRefreshRate);
}
int LegacyRandRScreen::proposedRefreshRate() const
{
return m_proposedRefreshRate;
}
int LegacyRandRScreen::refreshRateHzToIndex(int size, int hz) const
{
int nrates;
short* rates = XRRRates(QX11Info::display(), 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 LegacyRandRScreen::refreshRateIndexToHz(int size, int index) const
{
int nrates;
short* rates = XRRRates(QX11Info::display(), m_screen, (SizeID)size, &nrates);
if (nrates == 0 || index < 0)
return 0;
// Wrong input Hz!
if(index >= nrates)
return 0;
return rates[index];
}
int LegacyRandRScreen::numSizes() const
{
return m_pixelSizes.count();
}
const QSize& LegacyRandRScreen::pixelSize(int index) const
{
return m_pixelSizes[index];
}
const QSize& LegacyRandRScreen::mmSize(int index) const
{
return m_mmSizes[index];
}
int LegacyRandRScreen::sizeIndex(const QSize &pixelSize) const
{
for (int i = 0; i < m_pixelSizes.count(); i++)
if (m_pixelSizes[i] == pixelSize)
return i;
return -1;
}
int LegacyRandRScreen::rotations() const
{
return m_rotations;
}
int LegacyRandRScreen::rotation() const
{
return m_currentRotation;
}
int LegacyRandRScreen::size() const
{
return m_currentSize;
}
int LegacyRandRScreen::proposedRotation() const
{
return m_proposedRotation;
}
void LegacyRandRScreen::proposeRotation(int newRotation)
{
m_proposedRotation = newRotation & RandR::OrientationMask;
}
int LegacyRandRScreen::proposedSize() const
{
return m_proposedSize;
}
bool LegacyRandRScreen::proposeSize(int newSize)
{
if ((int)m_pixelSizes.count() > newSize) {
m_proposedSize = newSize;
return true;
}
return false;
}
void LegacyRandRScreen::load(KConfig& config)
{
KConfigGroup group = config.group(QString("Screen%1").arg(m_screen));
if (proposeSize(sizeIndex(group.readEntry("size", currentPixelSize()))))
proposeRefreshRate(refreshRateHzToIndex(proposedSize(), group.readEntry("refresh", refreshRate())));
proposeRotation(rotationDegreeToIndex( group.readEntry("rotation", 0)) +
(group.readEntry("reflectX", false) ? RandR::ReflectX : 0) +
(group.readEntry("reflectY",false) ? RandR::ReflectY : 0));
}
void LegacyRandRScreen::save(KConfig& config) const
{
KConfigGroup group = config.group(QString("Screen%1").arg(m_screen));
group.writeEntry("size", currentPixelSize());
group.writeEntry("refresh", refreshRateIndexToHz(size(), refreshRate()));
group.writeEntry("rotation", rotationIndexToDegree(rotation()));
group.writeEntry("reflectX", (bool)(rotation() & RandR::ReflectMask) == RandR::ReflectX);
group.writeEntry("reflectY", (bool)(rotation() & RandR::ReflectMask) == RandR::ReflectY);
}
QStringList LegacyRandRScreen::startupCommands() const
{
QString command = QString("xrandr -s %1x%2 -r %3 ").arg( currentPixelSize().width(),
currentPixelSize().height(), refreshRateIndexToHz(size(), refreshRate()));
switch( rotation()) {
case RR_Rotate_90:
command += " -o 1 ";
break;
case RR_Rotate_180:
command += " -o 2 ";
break;
case RR_Rotate_270:
command += " -o 3 ";
break;
}
if((rotation() & RandR::ReflectMask) == RandR::ReflectX)
command += " -x ";
if((bool)(rotation() & RandR::ReflectMask) == RandR::ReflectY)
command += " -y ";
return QStringList() << command;
}
int LegacyRandRScreen::pixelCount( int index ) const
{
QSize sz = pixelSize(index);
return sz.width() * sz.height();
}
SizeList LegacyRandRScreen::pixelSizes() const
{
return m_pixelSizes;
}
#include "moc_legacyrandrscreen.cpp"

View file

@ -1,157 +0,0 @@
/*
* Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
*
* 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 __LEGACYRANDRSCREEN_H__
#define __LEGACYRANDRSCREEN_H__
#include <QObject>
#include <QPixmap>
#include <kcmodule.h>
#include <kconfig.h>
#include "randr.h"
class KTimerDialog;
class LegacyRandRScreen : public QObject
{
Q_OBJECT
public:
LegacyRandRScreen(int screenIndex);
~LegacyRandRScreen();
void loadSettings();
void setOriginal();
bool applyProposed();
/**
* @returns false if the user did not confirm in time, or canceled, or the change failed
*/
bool applyProposedAndConfirm();
Window rootWindow() const;
public:
QString changedMessage() const;
bool changedFromOriginal() const;
void proposeOriginal();
bool proposedChanged() const;
QString currentRotationDescription() const;
int rotationIndexToDegree(int rotation) const;
int rotationDegreeToIndex(int degree) const;
/**
* Refresh rate functions.
*/
RateList refreshRates(int size) const;
QString refreshRateDirectDescription(int rate) const;
QString refreshRateIndirectDescription(int size, int index) const;
QString refreshRateDescription(int size, int index) const;
int refreshRate() 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;
SizeList pixelSizes() 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(const QSize &pixelSize) const;
int rotations() const;
/**
* Current setting functions.
*/
const QSize& currentPixelSize() const;
int rotation() const;
int size() 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;
QStringList startupCommands() const;
private:
XRRScreenConfiguration* m_config;
int m_screen;
SizeList m_pixelSizes;
SizeList 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;
};
#endif

View file

@ -28,24 +28,25 @@
#include "krandrapp.h"
static const char krandrtrayVersion[] = "0.5";
int main(int argc, char **argv)
{
KAboutData aboutData("display-randr", "krandr", ki18n("Resize and Rotate"), krandrtrayVersion,
ki18n("X Resize and Rotate System Tray App"), KAboutData::License_GPL,
ki18n("(c) 2007 Gustavo Pichorim Boiko, 2002-2003 Hamish Rodda"), ki18n(0L));
aboutData.addAuthor(ki18n("Gustavo Pichorim Boiko"),ki18n("Maintainer"), "gustavo.boiko@kdemail.net");
aboutData.addAuthor(ki18n("Hamish Rodda"),ki18n("Original Author"), "rodda@kde.org");
aboutData.addCredit(ki18n("Lubos Lunak"),ki18n("Many fixes"), "l.lunak@suse.cz");
aboutData.addCredit(ki18n("Harry Bock"),ki18n("Many fixes, multi-head support"), "hbock@providence.edu");
aboutData.setProgramIconName("preferences-desktop-display-randr");
KAboutData aboutData("display-randr", "krandr", ki18n("Resize and Rotate"), krandrtrayVersion,
ki18n("X Resize and Rotate System Tray App"), KAboutData::License_GPL,
ki18n("(c) 2007 Gustavo Pichorim Boiko, 2002-2003 Hamish Rodda"), ki18n(0L));
aboutData.addAuthor(ki18n("Gustavo Pichorim Boiko"),ki18n("Maintainer"), "gustavo.boiko@kdemail.net");
aboutData.addAuthor(ki18n("Hamish Rodda"),ki18n("Original Author"), "rodda@kde.org");
aboutData.addCredit(ki18n("Lubos Lunak"),ki18n("Many fixes"), "l.lunak@suse.cz");
aboutData.addCredit(ki18n("Harry Bock"),ki18n("Many fixes, multi-head support"), "hbock@providence.edu");
aboutData.setProgramIconName("preferences-desktop-display-randr");
KCmdLineArgs::init(argc,argv,&aboutData);
KCmdLineArgs::init(argc,argv,&aboutData);
KCmdLineOptions options;
options.add("login", ki18n("Application is being auto-started at KDE session start"), 0L);
KCmdLineArgs::addCmdLineOptions(options);
KCmdLineArgs::addStdCmdLineOptions();
KCmdLineOptions options;
options.add("login", ki18n("Application is being auto-started at KDE session start"), 0L);
KCmdLineArgs::addCmdLineOptions(options);
KCmdLineArgs::addStdCmdLineOptions();
KRandRApp app;
return app.exec();
KRandRApp app;
return app.exec();
}

View file

@ -1,4 +1,7 @@
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/.. )
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_BINARY_DIR}/..
)
########### next target ###############
@ -10,16 +13,26 @@ set(kded_randrmonitor_PART_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/../randrcrtc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../randrmode.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../randr.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../legacyrandrscreen.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../ktimerdialog.cpp
)
)
kde4_add_plugin(kded_randrmonitor ${kded_randrmonitor_PART_SRCS})
target_link_libraries(kded_randrmonitor ${KDE4_KDEUI_LIBS} ${X11_Xrandr_LIB} ${X11_LIBRARIES} ${KDE4_SOLID_LIBS})
target_link_libraries(kded_randrmonitor
${KDE4_KDEUI_LIBS}
${KDE4_SOLID_LIBS}
${X11_Xrandr_LIB}
${X11_LIBRARIES}
)
install(TARGETS kded_randrmonitor DESTINATION ${KDE4_PLUGIN_INSTALL_DIR} )
install(
TARGETS kded_randrmonitor
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
)
########### install files ###############
install( FILES randrmonitor.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR}/kded )
install(
FILES randrmonitor.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}/kded
)

View file

@ -34,69 +34,67 @@ typedef QList<OutputConfig*> OutputConfigList;
class OutputConfig : public QWidget, public Ui::OutputConfigBase
{
Q_OBJECT
Q_OBJECT
public:
OutputConfig(QWidget *parent, RandROutput *output, OutputConfigList preceding, bool unified);
~OutputConfig();
/** Enumeration describing two related outputs (i.e. VGA LeftOf TMDS) */
enum Relation {
Absolute = -1,
SameAs = 0,
LeftOf = 1,
RightOf,
Over,
Under
};
// NOTE: I'd love to have used Above and Below but Xlib already defines them
// and that confuses GCC.
OutputConfig(QWidget *parent, RandROutput *output, OutputConfigList preceding, bool unified);
~OutputConfig();
/** Enumeration describing two related outputs (i.e. VGA LeftOf TMDS) */
enum Relation {
Absolute = -1,
SameAs = 0,
LeftOf = 1,
RightOf,
Over,
Under
};
// NOTE: I'd love to have used Above and Below but Xlib already defines them
// and that confuses GCC.
bool isActive() const;
QPoint position(void) const;
QSize resolution(void) const;
QRect rect() const;
float refreshRate(void) const;
int rotation(void) const;
static QString positionName(Relation position);
RandROutput *output(void) const;
bool isActive() const;
QPoint position(void) const;
QSize resolution(void) const;
QRect rect() const;
float refreshRate(void) const;
int rotation(void) const;
static QString positionName(Relation position);
RandROutput *output(void) const;
bool hasPendingChanges( const QPoint& normalizePos ) const;
void setUnifyOutput(bool unified);
bool hasPendingChanges( const QPoint& normalizePos ) const;
void setUnifyOutput(bool unified);
public slots:
void load();
void updateSizeList(void);
void load();
void updateSizeList(void);
protected slots:
void setConfigDirty(void);
void updatePositionList(void);
void updatePositionListDelayed(void);
void updateRotationList(void);
void updateRateList(void);
void updateRateList(int resolutionIndex);
void positionComboChanged(int item);
void outputChanged(RROutput output, int changed);
void setConfigDirty(void);
void updatePositionList(void);
void updatePositionListDelayed(void);
void updateRotationList(void);
void updateRateList(void);
void updateRateList(int resolutionIndex);
void positionComboChanged(int item);
void outputChanged(RROutput output, int changed);
signals:
void updateView();
void optionChanged();
void connectedChanged(bool);
void updateView();
void optionChanged();
void connectedChanged(bool);
private:
static bool isRelativeTo( QRect rect, QRect to, Relation rel );
bool m_changed;
bool m_unified;
QPoint m_pos;
QTimer updatePositionListTimer;
RandROutput *m_output;
// List of configs shown before this one. Relative positions may be given only
// relative to these in order to avoid cycles.
OutputConfigList precedingOutputConfigs;
static bool isRelativeTo( QRect rect, QRect to, Relation rel );
bool m_changed;
bool m_unified;
QPoint m_pos;
QTimer updatePositionListTimer;
RandROutput *m_output;
// List of configs shown before this one. Relative positions may be given only
// relative to these in order to avoid cycles.
OutputConfigList precedingOutputConfigs;
};
#endif
#endif // __OUTPUTCONFIG_H__

View file

@ -28,47 +28,44 @@ class OutputConfig;
class OutputGraphicsItem : public QObject, public QGraphicsRectItem
{
Q_OBJECT
Q_OBJECT
public:
OutputGraphicsItem(OutputConfig *config);
~OutputGraphicsItem();
OutputGraphicsItem(OutputConfig *config);
~OutputGraphicsItem();
void configUpdated(); // updates from OutputConfig
void configUpdated(); // updates from OutputConfig
OutputGraphicsItem *left() const;
OutputGraphicsItem *right() const;
OutputGraphicsItem *top() const;
OutputGraphicsItem *bottom() const;
OutputGraphicsItem *left() const;
OutputGraphicsItem *right() const;
OutputGraphicsItem *top() const;
OutputGraphicsItem *bottom() const;
void setLeft(OutputGraphicsItem *output);
void setRight(OutputGraphicsItem *output);
void setTop(OutputGraphicsItem *output);
void setBottom(OutputGraphicsItem *output);
void setLeft(OutputGraphicsItem *output);
void setRight(OutputGraphicsItem *output);
void setTop(OutputGraphicsItem *output);
void setBottom(OutputGraphicsItem *output);
bool isConnected();
bool isPrimary() const;
void setPrimary(bool);
bool isConnected();
bool isPrimary() const;
void setPrimary(bool);
protected:
void disconnect();
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void disconnect();
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
signals:
void itemChanged(OutputGraphicsItem *item);
void itemChanged(OutputGraphicsItem *item);
private:
void calculateSetRect( OutputConfig* config );
OutputGraphicsItem *m_left;
OutputGraphicsItem *m_right;
OutputGraphicsItem *m_top;
OutputGraphicsItem *m_bottom;
OutputConfig *m_config;
QGraphicsTextItem *m_text;
void calculateSetRect( OutputConfig* config );
OutputGraphicsItem *m_left;
OutputGraphicsItem *m_right;
OutputGraphicsItem *m_top;
OutputGraphicsItem *m_bottom;
OutputConfig *m_config;
QGraphicsTextItem *m_text;
};
#endif
#endif // OUTPUTGRAPHICSITEM_H

View file

@ -20,8 +20,6 @@
#include "randr.h"
#include <KIconLoader>
bool RandR::has_1_2 = false;
bool RandR::has_1_3 = false;
Time RandR::timestamp = 0;
QString RandR::rotationName(int rotation, bool pastTense, bool capitalised)

View file

@ -39,7 +39,6 @@ extern "C"
#include <fixx11h.h>
#ifdef HAS_RANDR_1_2
class RandRScreen;
class RandRCrtc;
class RandROutput;
@ -55,53 +54,46 @@ typedef QList<RandRScreen*> ScreenList;
typedef QList<RROutput> OutputList;
typedef QList<RRCrtc> CrtcList;
typedef QList<RRMode> ModeList;
#endif
typedef QList<float> RateList;
typedef QList<QSize> SizeList;
class LegacyRandRScreen;
typedef QList<LegacyRandRScreen*> LegacyScreenList;
class RandR
{
public:
static bool has_1_2;
static bool has_1_3;
static Time timestamp;
static const int OrientationCount = 6;
static const int RotationCount = 4;
enum Orientations {
Rotate0 = RR_Rotate_0,
Rotate90 = RR_Rotate_90,
Rotate180 = RR_Rotate_180,
Rotate270 = RR_Rotate_270,
RotateMask = (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270),
ReflectX = RR_Reflect_X,
ReflectY = RR_Reflect_Y,
ReflectMask = (RR_Reflect_X | RR_Reflect_Y),
OrientationMask = (RotateMask | ReflectMask)
};
enum Changes
{
ChangeCrtc = 0x01,
ChangeOutputs = 0x02,
ChangeMode = 0x04,
ChangeRotation = 0x08,
ChangeConnection = 0x10,
ChangeRect = 0x20,
ChangeRate = 0x40
};
static Time timestamp;
static const int OrientationCount = 6;
static const int RotationCount = 4;
enum Orientations {
Rotate0 = RR_Rotate_0,
Rotate90 = RR_Rotate_90,
Rotate180 = RR_Rotate_180,
Rotate270 = RR_Rotate_270,
RotateMask = (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270),
ReflectX = RR_Reflect_X,
ReflectY = RR_Reflect_Y,
ReflectMask = (RR_Reflect_X | RR_Reflect_Y),
OrientationMask = (RotateMask | ReflectMask)
};
enum Changes {
ChangeCrtc = 0x01,
ChangeOutputs = 0x02,
ChangeMode = 0x04,
ChangeRotation = 0x08,
ChangeConnection = 0x10,
ChangeRect = 0x20,
ChangeRate = 0x40
};
static QString rotationName(int rotation, bool pastTense = false, bool capitalised = true);
static QPixmap rotationIcon(int rotation, int currentRotation);
static QString rotationName(int rotation, bool pastTense = false, bool capitalised = true);
static QPixmap rotationIcon(int rotation, int currentRotation);
static bool confirm(const QRect &rect = QRect());
static bool confirm(const QRect &rect = QRect());
static SizeList sortSizes(const SizeList &sizes);
static SizeList sortSizes(const SizeList &sizes);
};
#endif

View file

@ -36,174 +36,145 @@
QT_BEGIN_NAMESPACE
uint qHash( const QPoint& p )
{
return p.x() * 10000 + p.y();
return p.x() * 10000 + p.y();
}
QT_END_NAMESPACE
RandRConfig::RandRConfig(QWidget *parent, RandRDisplay *display)
: QWidget(parent), Ui::RandRConfigBase()
: QWidget(parent), Ui::RandRConfigBase()
{
m_display = display;
Q_ASSERT(m_display);
if (!m_display->isValid()) {
// FIXME: this needs much better handling of this error...
return;
}
m_display = display;
Q_ASSERT(m_display);
if (!m_display->isValid()) {
// FIXME: this needs much better handling of this error...
return;
}
setupUi(this);
layout()->setMargin(0);
setupUi(this);
layout()->setMargin(0);
connect( identifyOutputsButton, SIGNAL(clicked()), SLOT(identifyOutputs()));
connect( &identifyTimer, SIGNAL(timeout()), SLOT(clearIndicators()));
connect( &compressUpdateViewTimer, SIGNAL(timeout()), SLOT(slotDelayedUpdateView()));
connect(unifyOutputs, SIGNAL(toggled(bool)), SLOT(unifiedOutputChanged(bool)));
connect( identifyOutputsButton, SIGNAL(clicked()), SLOT(identifyOutputs()));
connect( &identifyTimer, SIGNAL(timeout()), SLOT(clearIndicators()));
connect( &compressUpdateViewTimer, SIGNAL(timeout()), SLOT(slotDelayedUpdateView()));
connect(unifyOutputs, SIGNAL(toggled(bool)), SLOT(unifiedOutputChanged(bool)));
identifyTimer.setSingleShot( true );
compressUpdateViewTimer.setSingleShot( true );
identifyTimer.setSingleShot( true );
compressUpdateViewTimer.setSingleShot( true );
connect( saveAsDefaultButton, SIGNAL(clicked()), SLOT(saveStartup()));
QMenu* saveMenu = new QMenu(saveAsDefaultButton);
saveMenu->addAction(i18n("Save as Default"),this, SLOT(saveStartup()));
saveMenu->addAction(i18n("Reset"),this, SLOT(disableStartup()));
saveAsDefaultButton->setMenu(saveMenu);
connect( saveAsDefaultButton, SIGNAL(clicked()), SLOT(saveStartup()));
QMenu* saveMenu = new QMenu(saveAsDefaultButton);
saveMenu->addAction(i18n("Save as Default"),this, SLOT(saveStartup()));
saveMenu->addAction(i18n("Reset"),this, SLOT(disableStartup()));
saveAsDefaultButton->setMenu(saveMenu);
// create the container for the settings widget
QHBoxLayout *layout = new QHBoxLayout(outputList);
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
m_container = new SettingsContainer(outputList);
m_container->setSizePolicy(QSizePolicy::Minimum,
QSizePolicy::Minimum);
layout->addWidget(m_container);
// create the container for the settings widget
QHBoxLayout *layout = new QHBoxLayout(outputList);
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
m_container = new SettingsContainer(outputList);
m_container->setSizePolicy(QSizePolicy::Minimum,
QSizePolicy::Minimum);
layout->addWidget(m_container);
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3)
{
primaryDisplayBox->setVisible(true);
label->setVisible(true);
}
else
#endif //HAS_RANDR_1_3
{
primaryDisplayBox->setVisible(false);
label->setVisible(false);
}
primaryDisplayBox->setVisible(true);
label->setVisible(true);
KConfig config("krandrrc");
if (config.hasGroup("Screen_0") && config.group("Screen_0").readEntry("OutputsUnified", false)) {
unifyOutputs->setChecked(true);
}
// create the scene
m_scene = new QGraphicsScene(m_display->currentScreen()->rect(), screenView);
screenView->setScene(m_scene);
screenView->installEventFilter(this);
KConfig config("krandrrc");
if (config.hasGroup("Screen_0") && config.group("Screen_0").readEntry("OutputsUnified", false)) {
unifyOutputs->setChecked(true);
}
// create the scene
m_scene = new QGraphicsScene(m_display->currentScreen()->rect(), screenView);
screenView->setScene(m_scene);
screenView->installEventFilter(this);
m_layoutManager = new LayoutManager(m_display->currentScreen(), m_scene);
m_layoutManager = new LayoutManager(m_display->currentScreen(), m_scene);
}
RandRConfig::~RandRConfig()
{
clearIndicators();
clearIndicators();
}
void RandRConfig::load(void)
{
if (!m_display->isValid()) {
kDebug() << "Invalid display! Aborting config load.";
return;
}
if (!m_display->isValid()) {
kDebug() << "Invalid display! Aborting config load.";
return;
}
m_scene->clear();
qDeleteAll(m_outputList);
m_outputList.clear();
m_configs.clear(); // objects deleted above
OutputMap outputs = m_display->currentScreen()->outputs();
#ifdef HAS_RANDR_1_3
RandROutput *primary = m_display->currentScreen()->primaryOutput();
if (RandR::has_1_3)
{
// disconnect while we repopulate the combo box
disconnect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
disconnect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePrimaryDisplay()));
primaryDisplayBox->clear();
primaryDisplayBox->addItem(i18nc("No display selected", "None"));
}
#endif //HAS_RANDR_1_3
m_scene->clear();
qDeleteAll(m_outputList);
m_outputList.clear();
m_configs.clear(); // objects deleted above
OutputMap outputs = m_display->currentScreen()->outputs();
RandROutput *primary = m_display->currentScreen()->primaryOutput();
// disconnect while we repopulate the combo box
disconnect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
disconnect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePrimaryDisplay()));
primaryDisplayBox->clear();
primaryDisplayBox->addItem(i18nc("No display selected", "None"));
// FIXME: adjust it to run on a multi screen system
CollapsibleWidget *w;
OutputGraphicsItem *o;
OutputConfigList preceding;
foreach(RandROutput *output, outputs)
{
OutputConfig *config = new OutputConfig(this, output, preceding, unifyOutputs->isChecked());
m_configs.append( config );
preceding.append( config );
QString description = output->isConnected()
? i18n("%1 (Connected)", output->name())
: output->name();
w = m_container->insertWidget(config, description);
if(output->isConnected()) {
w->setExpanded(true);
kDebug() << "Output rect:" << output->rect();
}
connect(config, SIGNAL(connectedChanged(bool)), this, SLOT(outputConnectedChanged(bool)));
m_outputList.append(w);
o = new OutputGraphicsItem(config);
m_scene->addItem(o);
connect(o, SIGNAL(itemChanged(OutputGraphicsItem*)),
this, SLOT(slotAdjustOutput(OutputGraphicsItem*)));
// FIXME: adjust it to run on a multi screen system
CollapsibleWidget *w;
OutputGraphicsItem *o;
OutputConfigList preceding;
foreach(RandROutput *output, outputs) {
OutputConfig *config = new OutputConfig(this, output, preceding, unifyOutputs->isChecked());
m_configs.append( config );
preceding.append( config );
QString description = output->isConnected() ? i18n("%1 (Connected)", output->name()) : output->name();
w = m_container->insertWidget(config, description);
if (output->isConnected()) {
w->setExpanded(true);
kDebug() << "Output rect:" << output->rect();
}
connect(config, SIGNAL(connectedChanged(bool)), this, SLOT(outputConnectedChanged(bool)));
m_outputList.append(w);
o = new OutputGraphicsItem(config);
m_scene->addItem(o);
connect(o, SIGNAL(itemChanged(OutputGraphicsItem*)), this, SLOT(slotAdjustOutput(OutputGraphicsItem*)));
connect(config, SIGNAL(updateView()), this, SLOT(slotUpdateView()));
connect(config, SIGNAL(optionChanged()), this, SIGNAL(changed()));
connect(config, SIGNAL(updateView()), this, SLOT(slotUpdateView()));
connect(config, SIGNAL(optionChanged()), this, SIGNAL(changed()));
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3 && output->isConnected())
{
primaryDisplayBox->addItem(output->name(), QVariant::fromValue(output->id()));
if (primary == output)
{
primaryDisplayBox->setCurrentIndex(primaryDisplayBox->count()-1);
}
}
#endif //HAS_RANDR_1_3
}
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3)
{
connect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
connect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePrimaryDisplay()));
}
#endif //HAS_RANDR_1_3
slotUpdateView();
if (output->isConnected()) {
primaryDisplayBox->addItem(output->name(), QVariant::fromValue(output->id()));
if (primary == output) {
primaryDisplayBox->setCurrentIndex(primaryDisplayBox->count()-1);
}
}
}
connect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SIGNAL(changed()));
connect(primaryDisplayBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updatePrimaryDisplay()));
slotUpdateView();
}
void RandRConfig::outputConnectedChanged(bool connected)
{
OutputConfig *config = static_cast <OutputConfig *> (sender());
int index = m_configs.indexOf(config);
QString description = connected
? i18n("%1 (Connected)", config->output()->name())
: config->output()->name();
m_outputList.at(index)->setCaption(description);
OutputConfig *config = static_cast <OutputConfig *> (sender());
int index = m_configs.indexOf(config);
QString description = connected ? i18n("%1 (Connected)", config->output()->name()) : config->output()->name();
m_outputList.at(index)->setCaption(description);
}
void RandRConfig::save()
{
if (!m_display->isValid())
return;
if (!m_display->isValid()) {
return;
}
KConfig config("krandrrc");
if (config.hasGroup("Screen_0")) {
config.group("Screen_0").writeEntry("OutputsUnified", unifyOutputs->isChecked());
config.sync();
}
apply();
KConfig config("krandrrc");
if (config.hasGroup("Screen_0")) {
config.group("Screen_0").writeEntry("OutputsUnified", unifyOutputs->isChecked());
config.sync();
}
apply();
}
void RandRConfig::defaults()
@ -213,242 +184,227 @@ void RandRConfig::defaults()
void RandRConfig::apply()
{
kDebug() << "Applying settings...";
kDebug() << "Applying settings...";
// normalize positions so that the coordinate system starts at (0,0)
QPoint normalizePos;
bool first = true;
foreach(CollapsibleWidget *w, m_outputList) {
OutputConfig *config = static_cast<OutputConfig *>(w->innerWidget());
if( config->isActive()) {
QPoint pos = config->position();
if( first ) {
normalizePos = pos;
first = false;
} else {
if( pos.x() < normalizePos.x())
normalizePos.setX( pos.x());
if( pos.y() < normalizePos.y())
normalizePos.setY( pos.y());
}
}
}
normalizePos = -normalizePos;
kDebug() << "Normalizing positions by" << normalizePos;
// normalize positions so that the coordinate system starts at (0,0)
QPoint normalizePos;
bool first = true;
foreach(CollapsibleWidget *w, m_outputList) {
OutputConfig *config = static_cast<OutputConfig *>(w->innerWidget());
if ( config->isActive()) {
QPoint pos = config->position();
if( first ) {
normalizePos = pos;
first = false;
} else {
if( pos.x() < normalizePos.x()) {
normalizePos.setX( pos.x());
}
if( pos.y() < normalizePos.y()) {
normalizePos.setY( pos.y());
}
}
}
}
normalizePos = -normalizePos;
kDebug() << "Normalizing positions by" << normalizePos;
foreach(CollapsibleWidget *w, m_outputList) {
OutputConfig *config = static_cast<OutputConfig *>(w->innerWidget());
RandROutput *output = config->output();
if(!output->isConnected())
continue;
QSize res = config->resolution();
if(!res.isNull()) {
if(!config->hasPendingChanges( normalizePos )) {
kDebug() << "Ignoring identical config for" << output->name();
continue;
}
QRect configuredRect(config->position(), res);
kDebug() << "Output config for" << output->name() << ":\n"
" rect =" << configuredRect
<< ", rot =" << config->rotation()
<< ", rate =" << config->refreshRate();
// Break the connection with the previous CRTC for changed outputs, since
// otherwise the code could try to use the same CRTC for two different outputs.
// This is probably rather hackish and may not always work, but I don't see
// a better way with this codebase, definitely not with the time I have now.
output->disconnectFromCrtc();
foreach(CollapsibleWidget *w, m_outputList) {
OutputConfig *config = static_cast<OutputConfig *>(w->innerWidget());
RandROutput *output = config->output();
if (!output->isConnected()) {
continue;
}
QSize res = config->resolution();
if (!res.isNull()) {
if (!config->hasPendingChanges( normalizePos )) {
kDebug() << "Ignoring identical config for" << output->name();
continue;
}
QRect configuredRect(config->position(), res);
kDebug() << "Output config for" << output->name() << ":\n"
" rect =" << configuredRect
<< ", rot =" << config->rotation()
<< ", rate =" << config->refreshRate();
// Break the connection with the previous CRTC for changed outputs, since
// otherwise the code could try to use the same CRTC for two different outputs.
// This is probably rather hackish and may not always work, but I don't see
// a better way with this codebase, definitely not with the time I have now.
output->disconnectFromCrtc();
output->proposeRect(configuredRect.translated( normalizePos ));
output->proposeRotation(config->rotation());
output->proposeRefreshRate(config->refreshRate());
} else { // user wants to disable this output
kDebug() << "Disabling" << output->name();
output->slotDisable();
}
}
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3)
{
int primaryOutputIndex = primaryDisplayBox->currentIndex();
RandRScreen *screen = m_display->currentScreen();
if (primaryOutputIndex > 0)
{
QVariant output = primaryDisplayBox->itemData(primaryOutputIndex);
screen->proposePrimaryOutput(screen->output(output.value<RROutput>()));
}
else
{
screen->proposePrimaryOutput(0);
}
}
#endif //HAS_RANDR_1_3
m_display->applyProposed();
update();
output->proposeRect(configuredRect.translated( normalizePos ));
output->proposeRotation(config->rotation());
output->proposeRefreshRate(config->refreshRate());
} else { // user wants to disable this output
kDebug() << "Disabling" << output->name();
output->slotDisable();
}
}
int primaryOutputIndex = primaryDisplayBox->currentIndex();
RandRScreen *screen = m_display->currentScreen();
if (primaryOutputIndex > 0) {
QVariant output = primaryDisplayBox->itemData(primaryOutputIndex);
screen->proposePrimaryOutput(screen->output(output.value<RROutput>()));
} else {
screen->proposePrimaryOutput(0);
}
m_display->applyProposed();
update();
}
void RandRConfig::updatePrimaryDisplay()
{
QString primary=primaryDisplayBox->currentText();
foreach( QGraphicsItem* item, m_scene->items()) {
OutputGraphicsItem* itemo = dynamic_cast< OutputGraphicsItem* >( item );
if(itemo && (itemo->objectName()==primary)!=itemo->isPrimary()) {
itemo->setPrimary(itemo->objectName()==primary);
}
}
QString primary=primaryDisplayBox->currentText();
foreach( QGraphicsItem* item, m_scene->items()) {
OutputGraphicsItem* itemo = dynamic_cast< OutputGraphicsItem* >( item );
if (itemo && (itemo->objectName() == primary) != itemo->isPrimary()) {
itemo->setPrimary(itemo->objectName() == primary);
}
}
}
void RandRConfig::update()
{
// TODO: implement
emit changed(false);
// TODO: implement
emit changed(false);
}
void RandRConfig::saveStartup()
{
if (!m_display->isValid())
return;
KConfig config("krandrrc");
m_display->saveStartup(config);
#ifdef HAS_RANDR_1_3
if (RandR::has_1_3)
{
// Add setting the primary screen to the list of commands
KConfigGroup group = config.group("Display");
QStringList commands = group.readEntry("StartupCommands").split("\n");
int primaryOutputIndex = primaryDisplayBox->currentIndex();
if (primaryOutputIndex > 0)
{
QString primaryOutput = primaryDisplayBox->itemText(primaryOutputIndex);
commands += QString("xrandr --output %1 --primary")
.arg( KShell::quoteArg( primaryOutput ));
}
else
commands += "xrandr --noprimary";
group.writeEntry("StartupCommands",commands.join("\n"));
}
#endif //HAS_RANDR_1_3
KMessageBox::information( window(), i18n( "Configuration has been set as the desktop default." ));
if (!m_display->isValid()) {
return;
}
KConfig config("krandrrc");
m_display->saveStartup(config);
// Add setting the primary screen to the list of commands
KConfigGroup group = config.group("Display");
QStringList commands = group.readEntry("StartupCommands").split("\n");
int primaryOutputIndex = primaryDisplayBox->currentIndex();
if (primaryOutputIndex > 0) {
QString primaryOutput = primaryDisplayBox->itemText(primaryOutputIndex);
commands += QString("xrandr --output %1 --primary").arg( KShell::quoteArg( primaryOutput ));
} else {
commands += "xrandr --noprimary";
group.writeEntry("StartupCommands",commands.join("\n"));
}
KMessageBox::information( window(), i18n( "Configuration has been set as the desktop default." ));
}
void RandRConfig::disableStartup()
{
if (!m_display->isValid())
return;
KConfig config("krandrrc");
m_display->disableStartup(config);
KMessageBox::information( window(), i18n( "Default desktop setup has been reset." ));
if (!m_display->isValid()) {
return;
}
KConfig config("krandrrc");
m_display->disableStartup(config);
KMessageBox::information( window(), i18n( "Default desktop setup has been reset." ));
}
void RandRConfig::unifiedOutputChanged(bool checked)
{
Q_FOREACH(OutputConfig *config, m_configs) {
config->setUnifyOutput(checked);
config->updateSizeList();
}
emit changed(true);
Q_FOREACH(OutputConfig *config, m_configs) {
config->setUnifyOutput(checked);
config->updateSizeList();
}
emit changed(true);
}
bool RandRConfig::eventFilter(QObject *obj, QEvent *event)
{
if ( obj == screenView && event->type() == QEvent::Resize ) {
slotUpdateView();
return false;
} else {
return QWidget::eventFilter(obj, event);
}
if ( obj == screenView && event->type() == QEvent::Resize ) {
slotUpdateView();
return false;
}
return QWidget::eventFilter(obj, event);
}
void RandRConfig::slotAdjustOutput(OutputGraphicsItem *o)
{
Q_UNUSED(o);
kDebug() << "Output graphics item changed:";
// TODO: Implement
kDebug() << "Output graphics item changed:";
// TODO: Implement
}
void RandRConfig::slotUpdateView()
{
compressUpdateViewTimer.start( 0 );
compressUpdateViewTimer.start( 0 );
}
void RandRConfig::slotDelayedUpdateView()
{
QRect r;
bool first = true;
QRect r;
bool first = true;
// updates the graphics view so that all outputs fit inside of it
foreach(OutputConfig *config, m_configs)
{
if (first)
{
first = false;
r = config->rect();
}
else
r = r.united(config->rect());
}
// scale the total bounding rectangle for all outputs to fit
// 80% of the containing QGraphicsView
float scaleX = (float)screenView->width() / r.width();
float scaleY = (float)screenView->height() / r.height();
float scale = (scaleX < scaleY) ? scaleX : scaleY;
scale *= 0.80f;
screenView->resetMatrix();
screenView->scale(scale,scale);
screenView->ensureVisible(r);
screenView->setSceneRect(r);
// updates the graphics view so that all outputs fit inside of it
foreach(OutputConfig *config, m_configs) {
if (first) {
first = false;
r = config->rect();
} else {
r = r.united(config->rect());
}
}
// scale the total bounding rectangle for all outputs to fit
// 80% of the containing QGraphicsView
float scaleX = (float)screenView->width() / r.width();
float scaleY = (float)screenView->height() / r.height();
float scale = (scaleX < scaleY) ? scaleX : scaleY;
scale *= 0.80f;
screenView->resetMatrix();
screenView->scale(scale,scale);
screenView->ensureVisible(r);
screenView->setSceneRect(r);
foreach( QGraphicsItem* item, m_scene->items()) {
if( OutputGraphicsItem* itemo = dynamic_cast< OutputGraphicsItem* >( item ))
itemo->configUpdated();
}
updatePrimaryDisplay();
screenView->update();
foreach( QGraphicsItem* item, m_scene->items()) {
if( OutputGraphicsItem* itemo = dynamic_cast< OutputGraphicsItem* >( item )) {
itemo->configUpdated();
}
}
updatePrimaryDisplay();
screenView->update();
}
void RandRConfig::identifyOutputs()
{
identifyTimer.stop();
clearIndicators();
QHash< QPoint, QStringList > ids; // outputs at centers of screens (can be more in case of clone mode)
OutputMap outputs = m_display->currentScreen()->outputs();
foreach(RandROutput *output, outputs)
{
if( !output->isConnected() || output->rect().isEmpty())
continue;
ids[ output->rect().center() ].append( output->name());
}
for( QHash< QPoint, QStringList >::ConstIterator it = ids.constBegin();
it != ids.constEnd();
++it )
{
QLabel *si = new QLabel(it->join("\n"), NULL, Qt::X11BypassWindowManagerHint);
QFont fnt = KGlobalSettings::generalFont();
fnt.setPixelSize(100);
si->setFont(fnt);
si->setFrameStyle(QFrame::Panel);
si->setFrameShadow(QFrame::Plain);
si->setAlignment(Qt::AlignCenter);
QRect targetGeometry(QPoint(0,0), si->sizeHint());
targetGeometry.moveCenter(it.key());
si->setGeometry(targetGeometry);
si->show();
m_indicators.append( si );
}
identifyTimer.start( 1500 );
identifyTimer.stop();
clearIndicators();
QHash< QPoint, QStringList > ids; // outputs at centers of screens (can be more in case of clone mode)
OutputMap outputs = m_display->currentScreen()->outputs();
foreach(RandROutput *output, outputs) {
if( !output->isConnected() || output->rect().isEmpty()) {
continue;
}
ids[ output->rect().center() ].append( output->name());
}
for( QHash< QPoint, QStringList >::ConstIterator it = ids.constBegin(); it != ids.constEnd(); ++it ) {
QLabel *si = new QLabel(it->join("\n"), NULL, Qt::X11BypassWindowManagerHint);
QFont fnt = KGlobalSettings::generalFont();
fnt.setPixelSize(100);
si->setFont(fnt);
si->setFrameStyle(QFrame::Panel);
si->setFrameShadow(QFrame::Plain);
si->setAlignment(Qt::AlignCenter);
QRect targetGeometry(QPoint(0,0), si->sizeHint());
targetGeometry.moveCenter(it.key());
si->setGeometry(targetGeometry);
si->show();
m_indicators.append( si );
}
identifyTimer.start( 1500 );
}
void RandRConfig::clearIndicators()
{
qDeleteAll( m_indicators );
m_indicators.clear();
qDeleteAll( m_indicators );
m_indicators.clear();
}
#include "moc_randrconfig.cpp"

View file

@ -25,8 +25,8 @@
#include <QWidget>
#include <QTimer>
#include <QGraphicsScene>
class SettingsContainer;
class CollapsibleWidget;
class RandRDisplay;
@ -38,50 +38,49 @@ typedef QList<OutputConfig*> OutputConfigList;
class RandRConfig : public QWidget, public Ui::RandRConfigBase
{
Q_OBJECT
Q_OBJECT
public:
RandRConfig(QWidget *parent, RandRDisplay *display);
virtual ~RandRConfig();
RandRConfig(QWidget *parent, RandRDisplay *display);
virtual ~RandRConfig();
void load(void);
void save(void);
void defaults(void);
void load(void);
void save(void);
void defaults(void);
void apply();
void update();
void apply();
void update();
public slots:
void slotUpdateView();
void slotDelayedUpdateView();
void updatePrimaryDisplay();
void slotUpdateView();
void slotDelayedUpdateView();
void updatePrimaryDisplay();
protected slots:
void slotAdjustOutput(OutputGraphicsItem *o);
void identifyOutputs();
void clearIndicators();
void saveStartup();
void disableStartup();
void unifiedOutputChanged(bool checked);
void outputConnectedChanged(bool);
void slotAdjustOutput(OutputGraphicsItem *o);
void identifyOutputs();
void clearIndicators();
void saveStartup();
void disableStartup();
void unifiedOutputChanged(bool checked);
void outputConnectedChanged(bool);
signals:
void changed(bool change=true);
void changed(bool change=true);
protected:
virtual bool eventFilter(QObject *obj, QEvent *event);
virtual bool eventFilter(QObject *obj, QEvent *event);
private:
RandRDisplay *m_display;
SettingsContainer *m_container;
QList<CollapsibleWidget*> m_outputList;
QGraphicsScene *m_scene;
LayoutManager *m_layoutManager;
QList<QWidget*> m_indicators;
QTimer identifyTimer;
OutputConfigList m_configs;
QTimer compressUpdateViewTimer;
RandRDisplay *m_display;
SettingsContainer *m_container;
QList<CollapsibleWidget*> m_outputList;
QGraphicsScene *m_scene;
LayoutManager *m_layoutManager;
QList<QWidget*> m_indicators;
QTimer identifyTimer;
OutputConfigList m_configs;
QTimer compressUpdateViewTimer;
};
#endif
#endif // __RANDRCONFIG_H__

View file

@ -29,66 +29,66 @@
/** Class representing a CRT controller. */
class RandRCrtc : public QObject
{
Q_OBJECT
Q_OBJECT
public:
RandRCrtc(RandRScreen *parent, RRCrtc id);
~RandRCrtc();
RandRCrtc(RandRScreen *parent, RRCrtc id);
~RandRCrtc();
RRCrtc id() const;
int rotations() const;
int rotation() const;
RRCrtc id() const;
int rotations() const;
int rotation() const;
void loadSettings(bool notify = false);
void handleEvent(XRRCrtcChangeNotifyEvent *event);
void loadSettings(bool notify = false);
void handleEvent(XRRCrtcChangeNotifyEvent *event);
bool isValid(void) const;
RandRMode mode() const;
QRect rect() const;
float refreshRate() const;
bool isValid(void) const;
RandRMode mode() const;
QRect rect() const;
float refreshRate() const;
bool proposeSize(const QSize &s);
bool proposePosition(const QPoint &p);
bool proposeRotation(int rotation);
bool proposeRefreshRate(float rate);
// applying stuff
bool applyProposed();
void proposeOriginal();
void setOriginal();
bool proposedChanged();
bool proposeSize(const QSize &s);
bool proposePosition(const QPoint &p);
bool proposeRotation(int rotation);
bool proposeRefreshRate(float rate);
// applying stuff
bool applyProposed();
void proposeOriginal();
void setOriginal();
bool proposedChanged();
bool addOutput(RROutput output, const QSize &size = QSize());
bool removeOutput(RROutput output);
OutputList connectedOutputs() const;
bool addOutput(RROutput output, const QSize &size = QSize());
bool removeOutput(RROutput output);
OutputList connectedOutputs() const;
ModeList modes() const;
ModeList modes() const;
signals:
void crtcChanged(RRCrtc c, int changes);
void crtcChanged(RRCrtc c, int changes);
private:
RRCrtc m_id;
RRMode m_currentMode;
QRect m_currentRect;
float m_currentRate;
int m_currentRotation;
RRCrtc m_id;
RRMode m_currentMode;
QRect m_currentRect;
float m_currentRate;
int m_currentRotation;
QRect m_originalRect;
float m_originalRate;
int m_originalRotation;
QRect m_originalRect;
float m_originalRate;
int m_originalRotation;
QRect m_proposedRect;
float m_proposedRate;
int m_proposedRotation;
OutputList m_connectedOutputs;
OutputList m_possibleOutputs;
int m_rotations;
QRect m_proposedRect;
float m_proposedRate;
int m_proposedRotation;
OutputList m_connectedOutputs;
OutputList m_possibleOutputs;
int m_rotations;
RandRScreen *m_screen;
RandRScreen *m_screen;
};
#endif
#endif // __RANDRCRTC_H__

View file

@ -28,211 +28,147 @@
#include <QtGui/qx11info_x11.h>
#include "randrdisplay.h"
#ifdef HAS_RANDR_1_2
#include "randrscreen.h"
#endif
#include "legacyrandrscreen.h"
RandRDisplay::RandRDisplay()
: m_valid(true)
: m_valid(true)
{
m_dpy = QX11Info::display();
// Check extension
if(XRRQueryExtension(m_dpy, &m_eventBase, &m_errorBase) == False) {
m_valid = false;
return;
}
m_dpy = QX11Info::display();
// Check extension
if(XRRQueryExtension(m_dpy, &m_eventBase, &m_errorBase) == False) {
m_valid = false;
return;
}
int major_version, minor_version;
XRRQueryVersion(m_dpy, &major_version, &minor_version);
int major_version, minor_version;
XRRQueryVersion(m_dpy, &major_version, &minor_version);
m_version = i18n("X Resize and Rotate extension version %1.%2",
major_version,minor_version);
m_version = i18n("X Resize and Rotate extension version %1.%2", major_version, minor_version);
kDebug() << "Using XRANDR extension 1.3 or greater.";
kDebug() << "XRANDR error base: " << m_errorBase;
m_numScreens = ScreenCount(m_dpy);
m_currentScreenIndex = 0;
// check if we have the new version of the XRandR extension
RandR::has_1_2 = (major_version > 1 || (major_version == 1 && minor_version >= 2));
RandR::has_1_3 = (major_version > 1 || (major_version == 1 && minor_version >= 3));
if(RandR::has_1_3)
kDebug() << "Using XRANDR extension 1.3 or greater.";
else if(RandR::has_1_2)
kDebug() << "Using XRANDR extension 1.2.";
else kDebug() << "Using legacy XRANDR extension (1.1 or earlier).";
kDebug() << "XRANDR error base: " << m_errorBase;
m_numScreens = ScreenCount(m_dpy);
m_currentScreenIndex = 0;
// set the timestamp to 0
RandR::timestamp = 0;
// set the timestamp to 0
RandR::timestamp = 0;
// This assumption is WRONG with Xinerama
// Q_ASSERT(QApplication::desktop()->numScreens() == ScreenCount(QX11Info::display()));
// This assumption is WRONG with Xinerama
// Q_ASSERT(QApplication::desktop()->numScreens() == ScreenCount(QX11Info::display()));
for (int i = 0; i < m_numScreens; i++) {
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
m_screens.append(new RandRScreen(i));
else
#endif
m_legacyScreens.append(new LegacyRandRScreen(i));
}
#if 0
//#ifdef HAS_RANDR_1_2
// check if we have more than one output, if no, revert to the legacy behavior
if (RandR::has_1_2)
{
int count = 0;
foreach(RandRScreen *screen, m_screens)
count += screen->outputs().count();
if (count < 2)
{
RandR::has_1_2 = false;
for (int i = 0; i < m_numScreens; ++i)
{
delete m_screens[i];
m_legacyScreens.append(new LegacyRandRScreen(i));
}
m_screens.clear();
}
}
#endif
setCurrentScreen(DefaultScreen(QX11Info::display()));
for (int i = 0; i < m_numScreens; i++) {
m_screens.append(new RandRScreen(i));
}
setCurrentScreen(DefaultScreen(QX11Info::display()));
}
RandRDisplay::~RandRDisplay()
{
qDeleteAll(m_legacyScreens);
#ifdef HAS_RANDR_1_2
qDeleteAll(m_screens);
#endif
qDeleteAll(m_screens);
}
bool RandRDisplay::isValid() const
{
return m_valid;
return m_valid;
}
const QString& RandRDisplay::errorCode() const
{
return m_errorCode;
return m_errorCode;
}
int RandRDisplay::eventBase() const
{
return m_eventBase;
return m_eventBase;
}
int RandRDisplay::errorBase() const
{
return m_errorBase;
return m_errorBase;
}
const QString& RandRDisplay::version() const
{
return m_version;
return m_version;
}
void RandRDisplay::setCurrentScreen(int index)
{
Q_ASSERT(index < ScreenCount(m_dpy));
m_currentScreenIndex = index;
Q_ASSERT(index < ScreenCount(m_dpy));
m_currentScreenIndex = index;
}
int RandRDisplay::screenIndexOfWidget(QWidget* widget)
{
//int ret = QApplication::desktop()->screenNumber(widget);
//return ret != -1 ? ret : QApplication::desktop()->primaryScreen();
// get info from Qt's X11 info directly; QDesktopWidget seems to use
// Xinerama by default, which doesn't work properly with randr.
// It will return more screens than exist for the display, causing
// a crash in the screen/currentScreen methods.
if(widget)
return widget->x11Info().screen();
//int ret = QApplication::desktop()->screenNumber(widget);
//return ret != -1 ? ret : QApplication::desktop()->primaryScreen();
// get info from Qt's X11 info directly; QDesktopWidget seems to use
// Xinerama by default, which doesn't work properly with randr.
// It will return more screens than exist for the display, causing
// a crash in the screen/currentScreen methods.
if (widget) {
return widget->x11Info().screen();
}
return -1;
return -1;
}
int RandRDisplay::currentScreenIndex() const
{
return m_currentScreenIndex;
return m_currentScreenIndex;
}
bool RandRDisplay::needsRefresh() const
{
Time time, config_timestamp;
time = XRRTimes(m_dpy, m_currentScreenIndex, &config_timestamp);
kDebug() << "Cache:" << RandR::timestamp << "Server:" << time << "Config:" << config_timestamp;
return (RandR::timestamp < time);
Time time, config_timestamp;
time = XRRTimes(m_dpy, m_currentScreenIndex, &config_timestamp);
kDebug() << "Cache:" << RandR::timestamp << "Server:" << time << "Config:" << config_timestamp;
return (RandR::timestamp < time);
}
void RandRDisplay::refresh()
{
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2) {
for (int i = 0; i < m_screens.count(); ++i) {
RandRScreen* s = m_screens.at(i);
s->loadSettings();
}
}
else
#endif
{
for (int i = 0; i < m_legacyScreens.size(); ++i) {
LegacyRandRScreen* s = m_legacyScreens.at(i);
s->loadSettings();
}
}
for (int i = 0; i < m_screens.count(); ++i) {
RandRScreen* s = m_screens.at(i);
s->loadSettings();
}
}
bool RandRDisplay::canHandle(const XEvent *e) const
{
if (e->type == m_eventBase + RRScreenChangeNotify)
return true;
#ifdef HAS_RANDR_1_2
else if (e->type == m_eventBase + RRNotify)
return true;
#endif
return false;
if (e->type == m_eventBase + RRScreenChangeNotify) {
return true;
} else if (e->type == m_eventBase + RRNotify) {
return true;
}
return false;
}
void RandRDisplay::handleEvent(XEvent *e)
{
if (e->type == m_eventBase + RRScreenChangeNotify) {
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2) {
XRRScreenChangeNotifyEvent *event = (XRRScreenChangeNotifyEvent*)(e);
for (int i=0; i < m_screens.count(); ++i) {
RandRScreen *screen = m_screens.at(i);
if (screen->rootWindow() == event->root)
screen->handleEvent(event);
}
}
else
#endif
{
// handle the event
}
}
#ifdef HAS_RANDR_1_2
else if (e->type == m_eventBase + RRNotify) {
//forward the event to the right screen
XRRNotifyEvent *event = (XRRNotifyEvent*)e;
for (int i=0; i < m_screens.count(); ++i) {
RandRScreen *screen = m_screens.at(i);
if ( screen->rootWindow() == event->window ) {
screen->handleRandREvent(event);
}
}
}
#endif
if (e->type == m_eventBase + RRScreenChangeNotify) {
XRRScreenChangeNotifyEvent *event = (XRRScreenChangeNotifyEvent*)(e);
for (int i=0; i < m_screens.count(); ++i) {
RandRScreen *screen = m_screens.at(i);
if (screen->rootWindow() == event->root) {
screen->handleEvent(event);
}
}
} else if (e->type == m_eventBase + RRNotify) {
//forward the event to the right screen
XRRNotifyEvent *event = (XRRNotifyEvent*)e;
for (int i=0; i < m_screens.count(); ++i) {
RandRScreen *screen = m_screens.at(i);
if ( screen->rootWindow() == event->window ) {
screen->handleRandREvent(event);
}
}
}
}
int RandRDisplay::numScreens() const
@ -241,76 +177,24 @@ int RandRDisplay::numScreens() const
return m_numScreens;
}
LegacyRandRScreen* RandRDisplay::legacyScreen(int index)
{
return m_legacyScreens.at(index);
}
LegacyRandRScreen* RandRDisplay::currentLegacyScreen()
{
return m_legacyScreens.at(m_currentScreenIndex);
}
#ifdef HAS_RANDR_1_2
RandRScreen* RandRDisplay::screen(int index)
{
return m_screens.at(index);
return m_screens.at(index);
}
RandRScreen* RandRDisplay::currentScreen()
{
return m_screens.at(m_currentScreenIndex);
}
#endif
bool RandRDisplay::loadDisplay(KConfig& config, bool loadScreens)
{
if (loadScreens)
{
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
{
foreach(RandRScreen *s, m_screens)
s->load(config);
}
else
#endif
{
foreach(LegacyRandRScreen* s, m_legacyScreens)
s->load(config);
}
}
return applyOnStartup(config);
return m_screens.at(m_currentScreenIndex);
}
bool RandRDisplay::applyOnStartup(KConfig& config)
{
return config.group("Display").readEntry("ApplyOnStartup", false);
return config.group("Display").readEntry("ApplyOnStartup", false);
}
bool RandRDisplay::syncTrayApp(KConfig& config)
{
return config.group("Display").readEntry("SyncTrayApp", false);
}
void RandRDisplay::saveDisplay(KConfig& config, bool syncTrayApp)
{
KConfigGroup group = config.group("Display");
group.writeEntry("SyncTrayApp", syncTrayApp);
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
{
foreach(RandRScreen *s, m_screens)
s->save(config);
}
else
#endif
{
foreach(LegacyRandRScreen *s, m_legacyScreens)
s->save(config);
}
return config.group("Display").readEntry("SyncTrayApp", false);
}
// to be used during desktop startup, make all screens provide the shell commands
@ -318,51 +202,28 @@ void RandRDisplay::saveDisplay(KConfig& config, bool syncTrayApp)
// early during desktop startup
void RandRDisplay::saveStartup(KConfig& config)
{
KConfigGroup group = config.group("Display");
group.writeEntry("ApplyOnStartup", true);
QStringList commands;
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
{
foreach(RandRScreen *s, m_screens)
commands += s->startupCommands();
}
else
#endif
{
foreach(LegacyRandRScreen *s, m_legacyScreens)
commands += s->startupCommands();
}
group.writeEntry( "StartupCommands", commands.join( "\n" ));
KConfigGroup group = config.group("Display");
group.writeEntry("ApplyOnStartup", true);
QStringList commands;
foreach(RandRScreen *s, m_screens) {
commands += s->startupCommands();
}
group.writeEntry( "StartupCommands", commands.join( "\n" ));
}
void RandRDisplay::disableStartup(KConfig& config)
{
KConfigGroup group = config.group("Display");
group.writeEntry("ApplyOnStartup", false);
group.deleteEntry( "StartupCommands" );
KConfigGroup group = config.group("Display");
group.writeEntry("ApplyOnStartup", false);
group.deleteEntry( "StartupCommands" );
}
void RandRDisplay::applyProposed(bool confirm)
{
#ifdef HAS_RANDR_1_2
if (RandR::has_1_2)
foreach(RandRScreen *s, m_screens)
s->applyProposed(confirm);
else
#endif
{
foreach(LegacyRandRScreen *s, m_legacyScreens)
{
if (s->proposedChanged()) {
if (confirm)
s->applyProposedAndConfirm();
else
s->applyProposed();
}
}
}
foreach(RandRScreen *s, m_screens) {
s->applyProposed(confirm);
}
}
// vim:noet:sts=8:sw=8:

View file

@ -30,66 +30,56 @@
class RandRDisplay
{
public:
RandRDisplay();
~RandRDisplay();
RandRDisplay();
~RandRDisplay();
bool isValid() const;
const QString& errorCode() const;
const QString& version() const;
bool isValid() const;
const QString& errorCode() const;
const QString& version() const;
int eventBase() const;
int errorBase() const;
int eventBase() const;
int errorBase() const;
int screenIndexOfWidget(QWidget* widget);
int screenIndexOfWidget(QWidget* widget);
int numScreens() const;
LegacyRandRScreen* legacyScreen(int index);
LegacyRandRScreen* currentLegacyScreen();
#ifdef HAS_RANDR_1_2
RandRScreen* screen(int index);
RandRScreen* currentScreen();
#endif
void setCurrentScreen(int index);
int currentScreenIndex() const;
int numScreens() const;
RandRScreen* screen(int index);
RandRScreen* currentScreen();
void setCurrentScreen(int index);
int currentScreenIndex() const;
bool needsRefresh() const;
void refresh();
bool needsRefresh() const;
void refresh();
/**
* Loads saved settings.
*
* @param config the KConfig object to load from
* @param loadScreens whether to call LegacyRandRScreen::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 syncTrayApp);
void saveStartup(KConfig& config);
void disableStartup(KConfig& config);
/**
* Loads saved settings.
*
* @param config the KConfig object to load from
* @retuns true if the settings should be applied on KDE startup.
*/
void saveStartup(KConfig& config);
void disableStartup(KConfig& config);
static bool applyOnStartup(KConfig& config);
static bool syncTrayApp(KConfig& config);
static bool applyOnStartup(KConfig& config);
static bool syncTrayApp(KConfig& config);
void applyProposed(bool confirm = true);
void applyProposed(bool confirm = true);
bool canHandle(const XEvent *e) const;
void handleEvent(XEvent *e);
bool canHandle(const XEvent *e) const;
void handleEvent(XEvent *e);
private:
Display *m_dpy;
int m_numScreens;
int m_currentScreenIndex;
LegacyScreenList m_legacyScreens;
#ifdef HAS_RANDR_1_2
ScreenList m_screens;
#endif
Display *m_dpy;
int m_numScreens;
int m_currentScreenIndex;
ScreenList m_screens;
bool m_valid;
QString m_errorCode;
QString m_version;
bool m_valid;
QString m_errorCode;
QString m_version;
int m_eventBase;
int m_errorBase;
int m_eventBase;
int m_errorBase;
};
#endif
#endif // __RANDRDISPLAY_H__

View file

@ -21,25 +21,24 @@
#include "randr.h"
class RandRMode
{
public:
RandRMode(XRRModeInfo *info = 0);
~RandRMode();
RandRMode(XRRModeInfo *info = 0);
~RandRMode();
RRMode id() const;
QString name() const;
bool isValid() const;
QSize size() const;
float refreshRate() const;
RRMode id() const;
QString name() const;
bool isValid() const;
QSize size() const;
float refreshRate() const;
private:
bool m_valid;
QString m_name;
QSize m_size;
float m_rate;
RRMode m_id;
bool m_valid;
QString m_name;
QSize m_size;
float m_rate;
RRMode m_id;
};
#endif
#endif // __RANDRMODE_H__

View file

@ -23,11 +23,11 @@
#include <QObject>
#include <QString>
#include <QRect>
#include <QAction>
#include "randr.h"
#include "randrmode.h"
#include <QAction>
class KConfig;
/** Class representing an RROutput identifier. This class is used
@ -35,147 +35,151 @@ class KConfig;
* refresh rate of a DVI-I port, or the resolution of a VGA port). */
class RandROutput : public QObject
{
Q_OBJECT
Q_OBJECT
public:
RandROutput(RandRScreen *parent, RROutput id);
~RandROutput();
/** Returns the internal RANDR identifier for a particular output. */
RROutput id() const;
/** Return the screen that this output belongs to. */
RandRScreen *screen() const;
void loadSettings(bool notify = false);
/** Handle an event from RANDR signifying a change in this output's
* configuration. */
void handleEvent(XRROutputChangeNotifyEvent *event);
void handlePropertyEvent(XRROutputPropertyNotifyEvent *event);
RandROutput(RandRScreen *parent, RROutput id);
~RandROutput();
/** Returns the internal RANDR identifier for a particular output. */
RROutput id() const;
/** Return the screen that this output belongs to. */
RandRScreen *screen() const;
void loadSettings(bool notify = false);
/** Handle an event from RANDR signifying a change in this output's
* configuration. */
void handleEvent(XRROutputChangeNotifyEvent *event);
void handlePropertyEvent(XRROutputPropertyNotifyEvent *event);
/** The name of this output, as returned by the X device driver.
* Examples may be VGA, TMDS, DVI-I_2/digital, etc. Note:
* this is usually NOT the name returned in the EDID of your
* display. */
QString name() const;
/** The name of this output, as returned by the X device driver.
* Examples may be VGA, TMDS, DVI-I_2/digital, etc. Note:
* this is usually NOT the name returned in the EDID of your
* display. */
QString name() const;
/** Return the icon name according to the device type. */
QString icon() const;
/** Return the icon name according to the device type. */
QString icon() const;
/** List possible CRT controllers for this output. */
CrtcList possibleCrtcs() const;
/** Returns the current CRTC for this output. */
RandRCrtc *crtc() const;
/** List possible CRT controllers for this output. */
CrtcList possibleCrtcs() const;
/** Returns the current CRTC for this output. */
RandRCrtc *crtc() const;
void disconnectFromCrtc();
void disconnectFromCrtc();
/** Returns a list of all RRModes supported by this output. */
ModeList modes() const;
/** Returns a list of all RRModes supported by this output. */
ModeList modes() const;
/** Returns the current mode for this output. */
RandRMode mode() const;
/** Returns the current mode for this output. */
RandRMode mode() const;
/** Returns the preferred mode for this output,
* or an invalid mode if no preferred mode is known. */
RandRMode preferredMode() const;
/** The list of supported sizes */
SizeList sizes() const;
QRect rect() const;
/** Returns the preferred mode for this output,
* or an invalid mode if no preferred mode is known. */
RandRMode preferredMode() const;
/** The list of supported sizes */
SizeList sizes() const;
QRect rect() const;
/** The list of refresh rates for the given size.
* If no size is specified, it will use the current size */
RateList refreshRates(const QSize &s = QSize()) const;
/** The list of refresh rates for the given size.
* If no size is specified, it will use the current size */
RateList refreshRates(const QSize &s = QSize()) const;
/** The current refresh rate. */
float refreshRate() const;
/** The current refresh rate. */
float refreshRate() const;
/** Return all possible rotations for all CRTCs this output can be connected
* to. */
int rotations() const;
/** Return all possible rotations for all CRTCs this output can be connected
* to. */
int rotations() const;
/** Returns the curent rotation of the CRTC this output is currently
* connected to */
int rotation() const;
/** Returns the curent rotation of the CRTC this output is currently
* connected to */
int rotation() const;
/** Determines whether this output is connected to a display device.
* It is not necessarily active. */
bool isConnected() const;
/** Determines whether this output is currently driving a display
* device. */
bool isActive() const;
/** Determines whether this output is connected to a display device.
* It is not necessarily active. */
bool isConnected() const;
/** Determines whether this output is currently driving a display
* device. */
bool isActive() const;
bool applyProposed(int changes = 0xffffff, bool confirm = false);
void proposeOriginal();
bool applyProposed(int changes = 0xffffff, bool confirm = false);
void proposeOriginal();
// proposal functions
void proposeRefreshRate(float rate);
void proposeRect(const QRect &r);
void proposeRotation(int rotation);
// proposal functions
void proposeRefreshRate(float rate);
void proposeRect(const QRect &r);
void proposeRotation(int rotation);
void load(KConfig &config);
void save(KConfig &config);
QStringList startupCommands() const;
void load(KConfig &config);
void save(KConfig &config);
QStringList startupCommands() const;
public slots:
void slotChangeSize(QAction *action);
void slotChangeRotation(QAction *action);
void slotChangeRefreshRate(QAction *action);
void slotDisable();
void slotEnable();
void slotSetAsPrimary(bool primary);
void slotChangeSize(QAction *action);
void slotChangeRotation(QAction *action);
void slotChangeRefreshRate(QAction *action);
void slotDisable();
void slotEnable();
void slotSetAsPrimary(bool primary);
private slots:
void slotCrtcChanged(RRCrtc c, int changes);
void slotCrtcChanged(RRCrtc c, int changes);
signals:
/** This signal is emitted when any relevant change
* occurs in an output (mode, CRTC, resolution,
* connection, etc.) */
void outputChanged(RROutput o, int changes);
/** This signal is emitted when any relevant change
* occurs in an output (mode, CRTC, resolution,
* connection, etc.) */
void outputChanged(RROutput o, int changes);
protected:
/** Query Xrandr for information about this output, and set
* up this instance accordingly. */
void queryOutputInfo(void);
/** Find the first CRTC that is not controlling any
* display devices. */
RandRCrtc *findEmptyCrtc(void);
bool tryCrtc(RandRCrtc *crtc, int changes);
/** Query Xrandr for information about this output, and set
* up this instance accordingly.
*/
void queryOutputInfo(void);
/** Find the first CRTC that is not controlling any
* display devices.
*/
RandRCrtc *findEmptyCrtc(void);
bool tryCrtc(RandRCrtc *crtc, int changes);
/** Set the current CRT controller for this output.
* The CRTC should never be set directly; it should be added through
* this function to properly manage signals related to this output. */
bool setCrtc(RandRCrtc *crtc, bool applyNow = true);
private:
RROutput m_id;
QString m_name;
QString m_alias;
/** Set the current CRT controller for this output.
* The CRTC should never be set directly; it should be added through
* this function to properly manage signals related to this output.
*/
bool setCrtc(RandRCrtc *crtc, bool applyNow = true);
CrtcList m_possibleCrtcs;
private:
RROutput m_id;
QString m_name;
QString m_alias;
RandRScreen *m_screen;
RandRCrtc *m_crtc;
//proposed stuff (mostly to read from the configuration)
QRect m_proposedRect;
int m_proposedRotation;
float m_proposedRate;
CrtcList m_possibleCrtcs;
QRect m_originalRect;
int m_originalRotation;
float m_originalRate;
RandRScreen *m_screen;
RandRCrtc *m_crtc;
//proposed stuff (mostly to read from the configuration)
QRect m_proposedRect;
int m_proposedRotation;
float m_proposedRate;
ModeList m_modes;
RandRMode m_preferredMode;
QRect m_originalRect;
int m_originalRotation;
float m_originalRate;
int m_rotations;
bool m_connected;
ModeList m_modes;
RandRMode m_preferredMode;
int m_rotations;
bool m_connected;
};
#endif
#endif // __RANDROUTPUT_H__
// vim:noet:sts=8:sw=8:

View file

@ -30,52 +30,50 @@ RandRScreen::RandRScreen(int screenIndex)
m_proposedPrimaryOutput(0),
m_resources(0)
{
m_index = screenIndex;
m_rect = QRect(0, 0, XDisplayWidth(QX11Info::display(), m_index),
XDisplayHeight(QX11Info::display(), m_index));
m_index = screenIndex;
m_rect = QRect(0, 0, XDisplayWidth(QX11Info::display(), m_index), XDisplayHeight(QX11Info::display(), m_index));
m_connectedCount = 0;
m_activeCount = 0;
m_connectedCount = 0;
m_activeCount = 0;
loadSettings();
KConfig cfg("krandrrc");
load(cfg, true);
loadSettings();
KConfig cfg("krandrrc");
load(cfg, true);
m_originalPrimaryOutput = primaryOutput();
m_originalPrimaryOutput = primaryOutput();
// select for randr input events
int mask = RRScreenChangeNotifyMask |
RRCrtcChangeNotifyMask |
RROutputChangeNotifyMask |
RROutputPropertyNotifyMask;
XRRSelectInput(QX11Info::display(), rootWindow(), 0);
XRRSelectInput(QX11Info::display(), rootWindow(), mask);
// select for randr input events
int mask = RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask;
mask |= RROutputChangeNotifyMask | RROutputPropertyNotifyMask;
XRRSelectInput(QX11Info::display(), rootWindow(), 0);
XRRSelectInput(QX11Info::display(), rootWindow(), mask);
}
RandRScreen::~RandRScreen()
{
if (m_resources)
XRRFreeScreenResources(m_resources);
if (m_resources) {
XRRFreeScreenResources(m_resources);
}
//qDeleteAll(m_crtcs);
//qDeleteAll(m_outputs);
//qDeleteAll(m_modes);
//qDeleteAll(m_crtcs);
//qDeleteAll(m_outputs);
//qDeleteAll(m_modes);
}
int RandRScreen::index() const
{
return m_index;
return m_index;
}
XRRScreenResources* RandRScreen::resources() const
{
return m_resources;
return m_resources;
}
Window RandRScreen::rootWindow() const
{
return RootWindow(QX11Info::display(), m_index);
return RootWindow(QX11Info::display(), m_index);
}
void RandRScreen::loadSettings(bool notify)
@ -83,8 +81,7 @@ void RandRScreen::loadSettings(bool notify)
bool changed = false;
int minW, minH, maxW, maxH;
Status status = XRRGetScreenSizeRange(QX11Info::display(), rootWindow(),
&minW, &minH, &maxW, &maxH);
Status status = XRRGetScreenSizeRange(QX11Info::display(), rootWindow(), &minW, &minH, &maxW, &maxH);
//FIXME: we should check the status here
Q_UNUSED(status);
QSize minSize = QSize(minW, minH);
@ -164,258 +161,253 @@ void RandRScreen::loadSettings(bool notify)
void RandRScreen::handleEvent(XRRScreenChangeNotifyEvent* event)
{
m_rect.setWidth(event->width);
m_rect.setHeight(event->height);
m_rect.setWidth(event->width);
m_rect.setHeight(event->height);
emit configChanged();
emit configChanged();
}
void RandRScreen::handleRandREvent(XRRNotifyEvent* event)
{
RandRCrtc *c;
RandROutput *o;
XRRCrtcChangeNotifyEvent *crtcEvent;
XRROutputChangeNotifyEvent *outputEvent;
XRROutputPropertyNotifyEvent *propertyEvent;
RandRCrtc *c;
RandROutput *o;
XRRCrtcChangeNotifyEvent *crtcEvent;
XRROutputChangeNotifyEvent *outputEvent;
XRROutputPropertyNotifyEvent *propertyEvent;
// forward events to crtcs and outputs
switch (event->subtype) {
case RRNotify_CrtcChange:
crtcEvent = (XRRCrtcChangeNotifyEvent*)event;
c = crtc(crtcEvent->crtc);
Q_ASSERT(c);
c->handleEvent(crtcEvent);
return;
case RRNotify_OutputChange:
outputEvent = (XRROutputChangeNotifyEvent*)event;
o = output(outputEvent->output);
Q_ASSERT(o);
o->handleEvent(outputEvent);
return;
case RRNotify_OutputProperty:
propertyEvent = (XRROutputPropertyNotifyEvent*)event;
o = output(propertyEvent->output);
Q_ASSERT(o);
o->handlePropertyEvent(propertyEvent);
return;
}
// forward events to crtcs and outputs
switch (event->subtype) {
case RRNotify_CrtcChange: {
crtcEvent = (XRRCrtcChangeNotifyEvent*)event;
c = crtc(crtcEvent->crtc);
Q_ASSERT(c);
c->handleEvent(crtcEvent);
return;
}
case RRNotify_OutputChange: {
outputEvent = (XRROutputChangeNotifyEvent*)event;
o = output(outputEvent->output);
Q_ASSERT(o);
o->handleEvent(outputEvent);
return;
}
case RRNotify_OutputProperty: {
propertyEvent = (XRROutputPropertyNotifyEvent*)event;
o = output(propertyEvent->output);
Q_ASSERT(o);
o->handlePropertyEvent(propertyEvent);
return;
}
}
}
QSize RandRScreen::minSize() const
{
return m_minSize;
return m_minSize;
}
QSize RandRScreen::maxSize() const
{
return m_maxSize;
return m_maxSize;
}
CrtcMap RandRScreen::crtcs() const
{
return m_crtcs;
return m_crtcs;
}
RandRCrtc* RandRScreen::crtc(RRCrtc id) const
{
if (m_crtcs.contains(id))
return m_crtcs[id];
return 0;
if (m_crtcs.contains(id)) {
return m_crtcs[id];
}
return 0;
}
OutputMap RandRScreen::outputs() const
{
return m_outputs;
return m_outputs;
}
RandROutput* RandRScreen::output(RROutput id) const
{
if (m_outputs.contains(id))
return m_outputs[id];
return 0;
if (m_outputs.contains(id)) {
return m_outputs[id];
}
return 0;
}
#ifdef HAS_RANDR_1_3
void RandRScreen::setPrimaryOutput(RandROutput* output)
{
if (RandR::has_1_3)
{
RROutput id = None;
if (output)
id = output->id();
XRRSetOutputPrimary(QX11Info::display(), rootWindow(), id);
}
RROutput id = None;
if (output) {
id = output->id();
}
XRRSetOutputPrimary(QX11Info::display(), rootWindow(), id);
}
void RandRScreen::proposePrimaryOutput(RandROutput* output)
{
m_proposedPrimaryOutput = output;
m_proposedPrimaryOutput = output;
}
RandROutput* RandRScreen::primaryOutput()
{
if (RandR::has_1_3)
{
return output(XRRGetOutputPrimary(QX11Info::display(), rootWindow()));
}
return 0;
return output(XRRGetOutputPrimary(QX11Info::display(), rootWindow()));
}
#endif
ModeMap RandRScreen::modes() const
{
return m_modes;
return m_modes;
}
RandRMode RandRScreen::mode(RRMode id) const
{
if (m_modes.contains(id))
return m_modes[id];
if (m_modes.contains(id)) {
return m_modes[id];
}
return RandRMode(0);
return RandRMode(0);
}
bool RandRScreen::adjustSize(const QRect &minimumSize)
{
//try to find a size in which all outputs fit
//start with a given minimum rect
QRect rect = QRect(0, 0, 0, 0).united(minimumSize);
//try to find a size in which all outputs fit
//start with a given minimum rect
QRect rect = QRect(0, 0, 0, 0).united(minimumSize);
foreach(RandROutput *output, m_outputs)
{
// outputs that are not active should not be taken into account
// when calculating the screen size
if (!output->isActive())
continue;
rect = rect.united(output->rect());
}
foreach(RandROutput *output, m_outputs) {
// outputs that are not active should not be taken into account
// when calculating the screen size
if (!output->isActive()) {
continue;
}
rect = rect.united(output->rect());
}
// check bounds
if (rect.width() < m_minSize.width())
rect.setWidth(m_minSize.width());
if (rect.height() < m_minSize.height())
rect.setHeight(m_minSize.height());
// check bounds
if (rect.width() < m_minSize.width()) {
rect.setWidth(m_minSize.width());
}
if (rect.height() < m_minSize.height()) {
rect.setHeight(m_minSize.height());
}
if (rect.width() > m_maxSize.width()) {
return false;
}
if (rect.height() > m_maxSize.height()) {
return false;
}
if (rect.width() > m_maxSize.width())
return false;
if (rect.height() > m_maxSize.height())
return false;
return setSize(rect.size());
return setSize(rect.size());
}
bool RandRScreen::setSize(const QSize &s)
{
if (s == m_rect.size())
return true;
if (s == m_rect.size()) {
return true;
}
if (s.width() < m_minSize.width() ||
s.height() < m_minSize.height() ||
s.width() > m_maxSize.width() ||
s.height() > m_maxSize.height())
return false;
if (s.width() < m_minSize.width() ||
s.height() < m_minSize.height() ||
s.width() > m_maxSize.width() ||
s.height() > m_maxSize.height()) {
return false;
}
int widthMM, heightMM;
float dpi;
int widthMM, heightMM;
float dpi;
/* values taken from xrandr */
dpi = (25.4 * DisplayHeight(QX11Info::display(), m_index)) / DisplayHeightMM(QX11Info::display(), m_index);
widthMM = (int) ((25.4 * s.width()) / dpi);
heightMM = (int) ((25.4 * s.height()) / dpi);
/* values taken from xrandr */
dpi = (25.4 * DisplayHeight(QX11Info::display(), m_index)) / DisplayHeightMM(QX11Info::display(), m_index);
widthMM = (int) ((25.4 * s.width()) / dpi);
heightMM = (int) ((25.4 * s.height()) / dpi);
XRRSetScreenSize(QX11Info::display(), rootWindow(), s.width(), s.height(), widthMM, heightMM);
m_rect.setSize(s);
XRRSetScreenSize(QX11Info::display(), rootWindow(), s.width(), s.height(), widthMM, heightMM);
m_rect.setSize(s);
return true;
return true;
}
int RandRScreen::connectedCount() const
{
return m_connectedCount;
return m_connectedCount;
}
int RandRScreen::activeCount() const
{
return m_activeCount;
return m_activeCount;
}
bool RandRScreen::outputsUnified() const
{
return m_outputsUnified;
return m_outputsUnified;
}
void RandRScreen::setOutputsUnified(bool unified)
{
m_outputsUnified = unified;
// should this be called here?
slotUnifyOutputs(unified);
m_outputsUnified = unified;
// should this be called here?
slotUnifyOutputs(unified);
}
int RandRScreen::unifiedRotations() const
{
bool first = true;
int rotations = RandR::Rotate0;
bool first = true;
int rotations = RandR::Rotate0;
foreach(RandRCrtc *crtc, m_crtcs)
{
if (!crtc->connectedOutputs().count())
continue;
foreach(RandRCrtc *crtc, m_crtcs) {
if (!crtc->connectedOutputs().count()) {
continue;
}
if (first)
{
rotations = crtc->rotations();
first = false;
}
else
rotations &= crtc->rotations();
}
if (first) {
rotations = crtc->rotations();
first = false;
} else {
rotations &= crtc->rotations();
}
}
return rotations;
return rotations;
}
SizeList RandRScreen::unifiedSizes() const
{
SizeList sizeList;
bool first = true;
SizeList sizeList;
bool first = true;
foreach(RandROutput *output, m_outputs)
{
if (!output->isConnected())
continue;
foreach(RandROutput *output, m_outputs) {
if (!output->isConnected()) {
continue;
}
if (first)
{
// we start using the list from the first output
sizeList = output->sizes();
first = false;
}
else
{
SizeList outputSizes = output->sizes();
for (int i = sizeList.count() - 1; i >=0; --i)
{
// check if the current output has the i-th size of the sizeList
// if not, remove from the list
if (outputSizes.indexOf(sizeList[i]) == -1)
sizeList.removeAt(i);
}
}
}
if (first) {
// we start using the list from the first output
sizeList = output->sizes();
first = false;
} else {
SizeList outputSizes = output->sizes();
for (int i = sizeList.count() - 1; i >=0; --i) {
// check if the current output has the i-th size of the sizeList
// if not, remove from the list
if (outputSizes.indexOf(sizeList[i]) == -1) {
sizeList.removeAt(i);
}
}
}
}
return sizeList;
return sizeList;
}
QRect RandRScreen::rect() const
{
return m_rect;
return m_rect;
}
void RandRScreen::load(KConfig& config, bool skipOutputs)
@ -442,22 +434,22 @@ void RandRScreen::load(KConfig& config, bool skipOutputs)
void RandRScreen::save(KConfig &config)
{
KConfigGroup group = config.group("Screen_" + QString::number(m_index));
group.writeEntry("OutputsUnified", m_outputsUnified);
group.writeEntry("UnifiedRect", m_unifiedRect);
group.writeEntry("UnifiedRotation", m_unifiedRotation);
KConfigGroup group = config.group("Screen_" + QString::number(m_index));
group.writeEntry("OutputsUnified", m_outputsUnified);
group.writeEntry("UnifiedRect", m_unifiedRect);
group.writeEntry("UnifiedRotation", m_unifiedRotation);
foreach(RandROutput *output, m_outputs)
{
if (output->isConnected())
output->save(config);
}
foreach(RandROutput *output, m_outputs) {
if (output->isConnected()) {
output->save(config);
}
}
}
void RandRScreen::save()
{
KConfig cfg("krandrrc");
save(cfg);
KConfig cfg("krandrrc");
save(cfg);
}
QStringList RandRScreen::startupCommands() const
@ -530,12 +522,10 @@ bool RandRScreen::applyProposed(bool confirm)
break;
}
}*/
#ifdef HAS_RANDR_1_3
if (succeed)
{
setPrimaryOutput(m_proposedPrimaryOutput);
}
#endif //HAS_RANDR_1_3
kDebug() << "Changes have been applied to all outputs.";
@ -560,10 +550,8 @@ bool RandRScreen::applyProposed(bool confirm)
}
}
#ifdef HAS_RANDR_1_3
m_proposedPrimaryOutput = m_originalPrimaryOutput;
setPrimaryOutput(m_proposedPrimaryOutput);
#endif //HAS_RANDR_1_3
return false;
}

View file

@ -24,116 +24,111 @@
#include <QtGui/qx11info_x11.h>
#include <QObject>
#include <QMap>
#include <QSize>
#include <QAction>
class KConfig;
class RandRScreen : public QObject
{
Q_OBJECT
Q_OBJECT
public:
RandRScreen(int screenIndex);
~RandRScreen();
RandRScreen(int screenIndex);
~RandRScreen();
int index() const;
int index() const;
XRRScreenResources* resources() const;
Window rootWindow() const;
XRRScreenResources* resources() const;
Window rootWindow() const;
QSize minSize() const;
QSize maxSize() const;
QSize minSize() const;
QSize maxSize() const;
void loadSettings(bool notify = false);
void loadSettings(bool notify = false);
void handleEvent(XRRScreenChangeNotifyEvent* event);
void handleRandREvent(XRRNotifyEvent* event);
void handleEvent(XRRScreenChangeNotifyEvent* event);
void handleRandREvent(XRRNotifyEvent* event);
CrtcMap crtcs() const;
RandRCrtc *crtc(RRCrtc id) const;
OutputMap outputs() const;
RandROutput *output(RROutput id) const;
CrtcMap crtcs() const;
RandRCrtc *crtc(RRCrtc id) const;
OutputMap outputs() const;
RandROutput *output(RROutput id) const;
#ifdef HAS_RANDR_1_3
void setPrimaryOutput(RandROutput* output);
RandROutput* primaryOutput();
void setPrimaryOutput(RandROutput* output);
RandROutput* primaryOutput();
void proposePrimaryOutput(RandROutput* output);
#endif
void proposePrimaryOutput(RandROutput* output);
ModeMap modes() const;
RandRMode mode(RRMode id) const;
ModeMap modes() const;
RandRMode mode(RRMode id) const;
bool adjustSize(const QRect &minimumSize = QRect(0,0,0,0));
bool setSize(const QSize &s);
bool adjustSize(const QRect &minimumSize = QRect(0,0,0,0));
bool setSize(const QSize &s);
/**
* Return the number of connected outputs
*/
int connectedCount() const;
/**
* Return the number of connected outputs
*/
int connectedCount() const;
/**
* Return the number of active outputs
*/
int activeCount() const;
/**
* Return the number of active outputs
*/
int activeCount() const;
bool outputsUnified() const;
void setOutputsUnified(bool unified);
bool outputsUnified() const;
void setOutputsUnified(bool unified);
int unifiedRotations() const;
SizeList unifiedSizes() const;
int unifiedRotations() const;
SizeList unifiedSizes() const;
QRect rect() const;
QRect rect() const;
bool applyProposed(bool confirm);
bool applyProposed(bool confirm);
void load(KConfig &config, bool skipOutputs = false);
void save(KConfig &config);
QStringList startupCommands() const;
void load(KConfig &config, bool skipOutputs = false);
void save(KConfig &config);
QStringList startupCommands() const;
public slots:
void slotUnifyOutputs(bool unify);
void slotResizeUnified(QAction *action);
void slotRotateUnified(QAction *action);
void slotUnifyOutputs(bool unify);
void slotResizeUnified(QAction *action);
void slotRotateUnified(QAction *action);
void slotOutputChanged(RROutput id, int changes);
void slotOutputChanged(RROutput id, int changes);
void save();
void load();
void save();
void load();
signals:
void configChanged();
void configChanged();
protected slots:
void unifyOutputs();
void unifyOutputs();
private:
int m_index;
QSize m_minSize;
QSize m_maxSize;
QRect m_rect;
int m_index;
QSize m_minSize;
QSize m_maxSize;
QRect m_rect;
bool m_outputsUnified;
QRect m_unifiedRect;
int m_unifiedRotation;
bool m_outputsUnified;
QRect m_unifiedRect;
int m_unifiedRotation;
int m_connectedCount;
int m_activeCount;
int m_connectedCount;
int m_activeCount;
#ifdef HAS_RANDR_1_3
RandROutput* m_originalPrimaryOutput;
RandROutput* m_proposedPrimaryOutput;
#endif //HAS_RANDR_1_3
RandROutput* m_originalPrimaryOutput;
RandROutput* m_proposedPrimaryOutput;
XRRScreenResources* m_resources;
XRRScreenResources* m_resources;
CrtcMap m_crtcs;
OutputMap m_outputs;
ModeMap m_modes;
CrtcMap m_crtcs;
OutputMap m_outputs;
ModeMap m_modes;
};
#endif
#endif // __RANDRSCREEN_H__
// vim:noet:sts=8:sw=8: