2 * Copyright (c) 2008 Harry Bock <hbock@providence.edu>
3 * Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
4 * Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 #include "randrdisplay.h"
26 #include "randrscreen.h"
29 RandRDisplay::RandRDisplay()
32 m_dpy
= QX11Info::display();
35 if(XRRQueryExtension(m_dpy
, &m_eventBase
, &m_errorBase
) == False
) {
40 int major_version
, minor_version
;
41 XRRQueryVersion(m_dpy
, &major_version
, &minor_version
);
43 // check if we have the new version of the XRandR extension
44 m_valid
= (major_version
> 1 || (major_version
== 1 && minor_version
>= 2));
49 qDebug() << "XRANDR error base: " << m_errorBase
;
50 m_numScreens
= ScreenCount(m_dpy
);
51 m_currentScreenIndex
= 0;
53 // set the timestamp to 0
56 // This assumption is WRONG with Xinerama
57 // Q_ASSERT(QApplication::desktop()->numScreens() == ScreenCount(QX11Info::display()));
59 for (int i
= 0; i
< m_numScreens
; i
++) {
60 m_screens
.append(new RandRScreen(i
));
63 setCurrentScreen(DefaultScreen(QX11Info::display()));
66 RandRDisplay::~RandRDisplay()
68 qDeleteAll(m_screens
);
71 bool RandRDisplay::isValid() const
76 const QString
& RandRDisplay::errorCode() const
81 int RandRDisplay::eventBase() const
86 int RandRDisplay::errorBase() const
91 const QString
& RandRDisplay::version() const
96 void RandRDisplay::setCurrentScreen(int index
)
98 Q_ASSERT(index
< ScreenCount(m_dpy
));
99 m_currentScreenIndex
= index
;
102 int RandRDisplay::screenIndexOfWidget(QWidget
* widget
)
104 // get info from Qt's X11 info directly; QDesktopWidget seems to use
105 // Xinerama by default, which doesn't work properly with randr.
106 // It will return more screens than exist for the display, causing
107 // a crash in the screen/currentScreen methods.
109 return widget
->x11Info().screen();
114 int RandRDisplay::currentScreenIndex() const
116 return m_currentScreenIndex
;
119 bool RandRDisplay::needsRefresh() const
121 Time time
, config_timestamp
;
122 time
= XRRTimes(m_dpy
, m_currentScreenIndex
, &config_timestamp
);
124 qDebug() << "Cache:" << RandR::timestamp
<< "Server:" << time
<< "Config:" << config_timestamp
;
125 return (RandR::timestamp
< time
);
128 void RandRDisplay::refresh()
130 for (int i
= 0; i
< m_screens
.count(); ++i
) {
131 RandRScreen
* s
= m_screens
.at(i
);
136 bool RandRDisplay::canHandle(const XEvent
*e
) const
138 if (e
->type
== m_eventBase
+ RRScreenChangeNotify
)
140 else if (e
->type
== m_eventBase
+ RRNotify
)
146 void RandRDisplay::handleEvent(XEvent
*e
)
148 if (e
->type
== m_eventBase
+ RRScreenChangeNotify
) {
149 XRRScreenChangeNotifyEvent
*event
= (XRRScreenChangeNotifyEvent
*)(e
);
150 qDebug() << "RandRDisplay::handleEvent - RRScreenChangeNotify win: " << event
->window
<< " root: " << event
->root
;
151 for (int i
=0; i
< m_screens
.count(); ++i
) {
152 RandRScreen
*screen
= m_screens
.at(i
);
153 if (screen
->rootWindow() == event
->root
)
154 screen
->handleEvent(event
);
158 else if (e
->type
== m_eventBase
+ RRNotify
) {
159 //forward the event to the right screen
160 XRRNotifyEvent
*event
= (XRRNotifyEvent
*)e
;
161 qDebug() << "RandRDisplay::handleEvent - RRNotify win: " << event
->window
;
162 for (int i
=0; i
< m_screens
.count(); ++i
) {
163 RandRScreen
*screen
= m_screens
.at(i
);
164 // TODO: removed the window check because randr seems to pass an incorrect window
165 // if ( screen->rootWindow() == event->window ) {
166 screen
->handleRandREvent(event
);
171 qDebug() << "RandRDisplay::handleEvent - Other";
175 int RandRDisplay::numScreens() const
177 Q_ASSERT(ScreenCount(QX11Info::display()) == m_numScreens
);
181 RandRScreen
* RandRDisplay::screen(int index
)
183 return m_screens
.at(index
);
186 RandRScreen
* RandRDisplay::currentScreen()
188 return m_screens
.at(m_currentScreenIndex
);