not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / libs / kephal / configurations / backendconfigurations.cpp
blob39b12191026e6ba41c9c3cbc4a56a541ef94ec81
1 /*
2 * Copyright 2008 Aike J Sommer <dev@aikesommer.name>
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
6 * published by the Free Software Foundation; either version 2,
7 * or (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 Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "backendconfigurations.h"
22 #include "kephal/outputs.h"
23 #include "kephal/backend.h"
25 #include <QDebug>
28 namespace Kephal {
30 BackendConfigurations * BackendConfigurations::self() {
31 return BackendConfigurations::m_instance;
34 BackendConfigurations::BackendConfigurations(QObject * parent)
35 : Configurations(parent)/*,
36 m_status(new StatusMessage(this))*/
38 BackendConfigurations::m_instance = this;
41 BackendConfigurations::~BackendConfigurations()
43 BackendConfigurations::m_instance = 0;
46 BackendConfigurations * BackendConfigurations::m_instance = 0;
48 BackendConfiguration * BackendConfigurations::activeBackendConfiguration() {
49 return (BackendConfiguration *) activeConfiguration();
54 BackendConfiguration::BackendConfiguration(QObject * parent)
55 : Configuration(parent)
59 QMap<int, QRect> BackendConfiguration::realLayout() {
60 QMap<Output *, int> outputScreens;
61 foreach (Output * output, Outputs::self()->outputs()) {
62 int screen = Configurations::self()->screen(output);
63 outputScreens.insert(output, screen);
65 return realLayout(outputScreens);
68 QMap<int, QRect> BackendConfiguration::realLayout(const QMap<Output *, int> & outputScreens) {
69 QMap<int, QPoint> simpleLayout = layout();
70 return realLayout(simpleLayout, outputScreens);
73 QMap<int, QRect> BackendConfiguration::realLayout(const QMap<int, QPoint> & sLayout, const QMap<Output *, int> & outputScreens) {
74 QMap<Output *, QSize> outputSizes;
75 foreach (Output * output, outputScreens.keys()) {
76 outputSizes.insert(output, output->isActivated() ? output->size() : output->preferredSize());
78 return realLayout(sLayout, outputScreens, outputSizes);
81 QMap<int, QRect> BackendConfiguration::realLayout(const QMap<int, QPoint> & sLayout, const QMap<Output *, int> & outputScreens, const QMap<Output *, QSize> & outputSizes) {
82 //qDebug() << "calculating real layout for:" << sLayout << outputScreens;
84 QMap<int, QRect> screens;
85 QMap<int, QPoint> simpleLayout = sLayout;
87 QMap<int, QSize> screenSizes;
88 foreach (int screen, simpleLayout.keys()) {
89 screenSizes.insert(screen, QSize());
92 foreach (Output * output, outputScreens.keys()) {
93 if (outputScreens[output] < 0) {
94 continue;
97 if (! screenSizes.contains(outputScreens[output])) {
98 INVALID_CONFIGURATION("outputs and configuration don't match");
99 return screens;
101 screenSizes[outputScreens[output]] = screenSizes[outputScreens[output]].expandedTo(outputSizes[output]);
104 int begin = simpleLayout.begin().key();
105 screens.insert(begin, QRect(QPoint(0, 0), screenSizes[begin]));
106 simpleToReal(simpleLayout, screenSizes, begin, screens);
107 Configurations::translateOrigin(screens);
109 for (QMap<int, QRect>::const_iterator i = screens.constBegin(); i != screens.constEnd(); ++i) {
110 for (QMap<int, QRect>::const_iterator j = (i + 1); j != screens.constEnd(); ++j) {
111 if (i.value().intersects(j.value())) {
112 INVALID_CONFIGURATION("overlapping screens");
113 screens.clear();
114 return screens;
119 return screens;
122 void BackendConfiguration::simpleToReal(QMap<int, QPoint> & simpleLayout, const QMap<int, QSize> & screenSizes, int index, QMap<int, QRect> & screens) {
123 QPoint pos = simpleLayout.take(index);
125 // to the right
126 QPoint nextPos(pos.x() + 1, pos.y());
127 int nextIndex = simpleLayout.key(nextPos, -1);
128 if (nextIndex >= 0) {
129 screens.insert(nextIndex, QRect(screens[index].topRight() + QPoint(1, 0), screenSizes[nextIndex]));
130 simpleToReal(simpleLayout, screenSizes, nextIndex, screens);
133 // to the left
134 nextPos = QPoint(pos.x() - 1, pos.y());
135 nextIndex = simpleLayout.key(nextPos, -1);
136 if (nextIndex >= 0) {
137 QSize screenSize = screenSizes[nextIndex];
138 screens.insert(nextIndex, QRect(screens[index].topLeft() - QPoint(screenSize.width(), 0), screenSize));
139 simpleToReal(simpleLayout, screenSizes, nextIndex, screens);
142 // to the bottom
143 nextPos = QPoint(pos.x(), pos.y() + 1);
144 nextIndex = simpleLayout.key(nextPos, -1);
145 if (nextIndex >= 0) {
146 screens.insert(nextIndex, QRect(screens[index].bottomLeft() + QPoint(0, 1), screenSizes[nextIndex]));
147 simpleToReal(simpleLayout, screenSizes, nextIndex, screens);
150 // to the top
151 nextPos = QPoint(pos.x(), pos.y() - 1);
152 nextIndex = simpleLayout.key(nextPos, -1);
153 if (nextIndex >= 0) {
154 QSize screenSize = screenSizes[nextIndex];
155 screens.insert(nextIndex, QRect(screens[index].topLeft() - QPoint(0, screenSize.height()), screenSize));
156 simpleToReal(simpleLayout, screenSizes, nextIndex, screens);
160 QMap<int, QPoint> BackendConfiguration::cloneLayout(int screen) {
161 QSet<QPoint> positions = clonePositions(screen);
162 QMap<int, QPoint> layout;
163 int i = 0;
164 foreach (const QPoint& p, positions) {
165 layout.insert(i, p);
166 ++i;
169 Configurations::translateOrigin(layout);
170 return layout;
173 QSet<QPoint> BackendConfiguration::clonePositions(int screen) {
174 QList<QSet<QPoint> > partitions = partition(screen);
175 if (partitions.size() == 1) {
176 return partitions[0];
178 return QSet<QPoint>();
181 QSet<QPoint> BackendConfiguration::positions() {
182 QSet<QPoint> result;
183 foreach (const QPoint& p, layout()) {
184 result << p;
186 return result;
189 QSet<QPoint> BackendConfiguration::possiblePositions(int screen) {
190 QList<QSet<QPoint> > partitions = partition(screen);
191 QSet<QPoint> result = border(partitions[0]);
192 foreach (QSet<QPoint> partition, partitions) {
193 result.intersect(border(partition));
195 return result;
198 QList<QSet<QPoint> > BackendConfiguration::partition(int screen) {
199 QHash<QPoint, QSet<QPoint> * > partitions;
200 QMap<int, QPoint> layout = this->layout();
201 bool exclude = layout.contains(screen);
202 QPoint excludePoint;
203 if (exclude) {
204 excludePoint = layout[screen];
206 foreach (const QPoint& p, layout) {
207 if (exclude && (p == excludePoint)) {
208 continue;
210 partitions.insert(p, new QSet<QPoint>());
211 partitions[p]->insert(p);
214 foreach (const QPoint& p, layout) {
215 if (exclude && (p == excludePoint)) {
216 continue;
218 QList<QPoint> connected;
219 if (partitions.contains(p + QPoint(1, 0))) {
220 connected.append(p + QPoint(1, 0));
222 if (partitions.contains(p + QPoint(0, 1))) {
223 connected.append(p + QPoint(0, 1));
225 foreach (const QPoint& c, connected) {
226 if (partitions[p] == partitions[c]) {
227 continue;
229 partitions[p]->unite(* (partitions[c]));
230 delete partitions[c];
231 partitions[c] = partitions[p];
235 QSet<QSet<QPoint> * > unique;
236 foreach (QSet<QPoint> * partition, partitions) {
237 unique.insert(partition);
240 QList<QSet<QPoint> > result;
241 foreach (QSet<QPoint> * partition, unique) {
242 result.append(* partition);
243 delete partition;
246 return result;
249 QSet<QPoint> BackendConfiguration::border(QSet<QPoint> screens) {
250 QSet<QPoint> result;
251 QList<QPoint> borders;
252 borders << QPoint(1, 0) << QPoint(0, 1) << QPoint(-1, 0) << QPoint(0, -1);
253 foreach (const QPoint& p, screens) {
254 foreach (const QPoint& border, borders) {
255 if (! screens.contains(p + border)) {
256 result.insert(p + border);
261 return result;
266 #ifndef NO_KDE
267 #include "backendconfigurations.moc"
268 #endif