add more spacing
[personal-kdebase.git] / workspace / libs / kephal / xrandr12 / randrscreen.cpp
blobf860eddaaa22cb6787599c8bb166dba6d982ff8c
1 /*
2 * Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "randrscreen.h"
20 #include "randrcrtc.h"
21 #include "randroutput.h"
22 #include "randrmode.h"
25 RandRScreen::RandRScreen(int screenIndex)
26 : m_resources(0L)
28 m_index = screenIndex;
29 m_rect = QRect(0, 0, XDisplayWidth(QX11Info::display(), m_index),
30 XDisplayHeight(QX11Info::display(), m_index));
32 m_connectedCount = 0;
33 m_activeCount = 0;
35 // select for randr input events
36 int mask = RRScreenChangeNotifyMask |
37 RRCrtcChangeNotifyMask |
38 RROutputChangeNotifyMask |
39 RROutputPropertyNotifyMask;
41 XRRSelectInput(QX11Info::display(), rootWindow(), 0);
42 XRRSelectInput(QX11Info::display(), rootWindow(), mask);
44 qDebug() << "RRInput mask is set!!";
46 loadSettings();
49 RandRScreen::~RandRScreen()
51 if (m_resources)
52 XRRFreeScreenResources(m_resources);
55 int RandRScreen::index() const
57 return m_index;
60 XRRScreenResources* RandRScreen::resources() const
62 return m_resources;
65 Window RandRScreen::rootWindow() const
67 return RootWindow(QX11Info::display(), m_index);
70 void RandRScreen::pollState()
72 XRRFreeScreenResources(XRRGetScreenResources(QX11Info::display(), rootWindow()));
75 void RandRScreen::reloadResources()
77 if (m_resources)
78 XRRFreeScreenResources(m_resources);
80 m_resources = XRRGetScreenResources(QX11Info::display(), rootWindow());
81 Q_ASSERT(m_resources);
84 void RandRScreen::loadSettings(bool notify)
86 bool changed = false;
87 int minW, minH, maxW, maxH;
89 Status status = XRRGetScreenSizeRange(QX11Info::display(), rootWindow(),
90 &minW, &minH, &maxW, &maxH);
91 //FIXME: we should check the status here
92 Q_UNUSED(status);
93 QSize minSize = QSize(minW, minH);
94 QSize maxSize = QSize(maxW, maxH);
96 if (minSize != m_minSize || maxSize != m_maxSize)
98 m_minSize = minSize;
99 m_maxSize = maxSize;
100 changed = true;
103 reloadResources();
105 RandR::timestamp = m_resources->timestamp;
107 // get all modes
108 changed |= loadModes();
110 //get all crtcs
111 RandRCrtc *c_none = new RandRCrtc(this, None);
112 m_crtcs[None] = c_none;
114 for (int i = 0; i < m_resources->ncrtc; ++i)
116 RRCrtc crtc = m_resources->crtcs[i];
117 if (m_crtcs.contains(crtc))
118 m_crtcs[crtc]->loadSettings(notify);
119 else
121 qDebug() << "RandRScreen::loadSettings - adding crtc: " << crtc;
122 RandRCrtc *c = new RandRCrtc(this, crtc);
123 c->loadSettings(notify);
124 connect(c, SIGNAL(crtcChanged(RRCrtc, int)), this, SIGNAL(configChanged()));
125 m_crtcs[crtc] = c;
126 changed = true;
130 //get all outputs
131 for (int i = 0; i < m_resources->noutput; ++i)
133 RROutput output = m_resources->outputs[i];
134 if (m_outputs.contains(output))
135 ;//m_outputs[m_resources->outputs[i]]->loadSettings(notify);
136 else
138 qDebug() << "RandRScreen::loadSettings - adding output: " << output;
139 RandROutput *o = new RandROutput(this, output);
140 connect(o, SIGNAL(outputChanged(RROutput, int)), this,
141 SLOT(slotOutputChanged(RROutput, int)));
142 m_outputs[output] = o;
143 if (o->isConnected())
144 m_connectedCount++;
145 if (o->isActive())
146 m_activeCount++;
148 changed = true;
152 if (notify && changed)
153 emit configChanged();
157 bool RandRScreen::loadModes()
159 bool changed = false;
160 for (int i = 0; i < m_resources->nmode; ++i)
162 XRRModeInfo mode = m_resources->modes[i];
163 if (!m_modes.contains(mode.id))
165 qDebug() << "RandRScreen::loadSettings - adding mode: " << mode.id << mode.width << "x" << mode.height;
166 m_modes[mode.id] = RandRMode(&mode);
167 changed = true;
171 return changed;
174 void RandRScreen::handleEvent(XRRScreenChangeNotifyEvent* event)
176 qDebug() << "RandRScreen::handleEvent";
178 m_rect.setWidth(event->width);
179 m_rect.setHeight(event->height);
181 reloadResources();
182 loadModes();
183 qDebug() << "Reloaded modes";
185 // foreach(RandROutput *output, m_outputs) {
186 // output->loadSettings(false);
187 // }
190 emit configChanged();
193 void RandRScreen::handleRandREvent(XRRNotifyEvent* event)
195 RandRCrtc *c;
196 RandROutput *o;
197 XRRCrtcChangeNotifyEvent *crtcEvent;
198 XRROutputChangeNotifyEvent *outputEvent;
199 XRROutputPropertyNotifyEvent *propertyEvent;
201 // forward events to crtcs and outputs
202 switch (event->subtype) {
203 case RRNotify_CrtcChange:
204 qDebug() << "RandRScreen::handleRandREvent - CrtcChange";
205 crtcEvent = (XRRCrtcChangeNotifyEvent*)event;
206 c = crtc(crtcEvent->crtc);
207 Q_ASSERT(c);
208 c->handleEvent(crtcEvent);
209 return;
211 case RRNotify_OutputChange:
212 qDebug() << "RandRScreen::handleRandREvent - OutputChange";
213 outputEvent = (XRROutputChangeNotifyEvent*)event;
214 o = output(outputEvent->output);
215 Q_ASSERT(o);
216 o->handleEvent(outputEvent);
217 return;
219 case RRNotify_OutputProperty:
220 qDebug() << "RandRScreen::handleRandREvent - OutputProperty";
221 propertyEvent = (XRROutputPropertyNotifyEvent*)event;
222 o = output(propertyEvent->output);
223 Q_ASSERT(o);
224 o->handlePropertyEvent(propertyEvent);
225 return;
227 default:
228 qDebug() << "RandRScreen::handleRandREvent - Other";
232 QSize RandRScreen::minSize() const
234 return m_minSize;
237 QSize RandRScreen::maxSize() const
239 return m_maxSize;
242 CrtcMap RandRScreen::crtcs() const
244 return m_crtcs;
247 RandRCrtc* RandRScreen::crtc(RRCrtc id) const
249 if (m_crtcs.contains(id))
250 return m_crtcs[id];
252 return 0;
255 OutputMap RandRScreen::outputs() const
257 return m_outputs;
260 RandROutput* RandRScreen::output(RROutput id) const
262 if (m_outputs.contains(id))
263 return m_outputs[id];
265 return 0;
268 ModeMap RandRScreen::modes() const
270 return m_modes;
273 RandRMode RandRScreen::mode(RRMode id) const
275 if (m_modes.contains(id))
276 return m_modes[id];
278 return RandRMode(0);
281 bool RandRScreen::adjustSize(const QRect &minimumSize)
283 //try to find a size in which all outputs fit
285 //start with a given minimum rect
286 QRect rect = QRect(0, 0, 0, 0).united(minimumSize);
288 foreach(RandROutput *output, m_outputs)
290 // outputs that are not active should not be taken into account
291 // when calculating the screen size
292 if (!output->isActive())
293 continue;
294 rect = rect.united(output->rect());
298 // check bounds
299 if (rect.width() < m_minSize.width())
300 rect.setWidth(m_minSize.width());
301 if (rect.height() < m_minSize.height())
302 rect.setHeight(m_minSize.height());
304 if (rect.width() > m_maxSize.width())
305 return false;
306 if (rect.height() > m_maxSize.height())
307 return false;
309 return setSize(rect.size());
312 bool RandRScreen::setSize(const QSize &s)
314 if (s == m_rect.size())
315 return true;
317 if (s.width() < m_minSize.width() ||
318 s.height() < m_minSize.height() ||
319 s.width() > m_maxSize.width() ||
320 s.height() > m_maxSize.height())
321 return false;
323 int widthMM, heightMM;
324 float dpi;
326 /* values taken from xrandr */
327 dpi = (25.4 * DisplayHeight(QX11Info::display(), m_index)) / DisplayHeightMM(QX11Info::display(), m_index);
328 widthMM = (int) ((25.4 * s.width()) / dpi);
329 heightMM = (int) ((25.4 * s.height()) / dpi);
331 XRRSetScreenSize(QX11Info::display(), rootWindow(), s.width(), s.height(), widthMM, heightMM);
332 m_rect.setSize(s);
334 return true;
337 int RandRScreen::connectedCount() const
339 return m_connectedCount;
342 int RandRScreen::activeCount() const
344 return m_activeCount;
347 QRect RandRScreen::rect() const
349 return m_rect;
352 void RandRScreen::slotOutputChanged(RROutput id, int changes)
354 Q_UNUSED(id);
355 Q_UNUSED(changes);
357 int connected = 0, active = 0;
358 foreach(RandROutput *output, m_outputs)
360 if (output->isConnected())
361 connected++;
362 if (output->isActive())
363 active++;
366 m_connectedCount = connected;
367 m_activeCount = active;