2
* Compiz Core: OutputDevices class
4
* Copyright (c) 2012 Canonical Ltd.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
* DEALINGS IN THE SOFTWARE.
25
#include <core/option.h>
26
#include "outputdevices.h"
27
#include "core_options.h"
34
OutputDevices::OutputDevices() :
36
overlappingOutputs (false),
42
OutputDevices::setGeometryOnDevice(unsigned int const nOutput,
44
const int width, const int height)
46
if (outputDevs.size() < nOutput + 1)
47
outputDevs.resize(nOutput + 1);
49
outputDevs[nOutput].setGeometry(x, y, width, height);
53
OutputDevices::adoptDevices(unsigned int nOutput, CompSize* screen)
55
/* make sure we have at least one output */
58
setGeometryOnDevice(nOutput, 0, 0, screen->width(), screen->height());
61
if (outputDevs.size() > nOutput)
62
outputDevs.resize(nOutput);
65
/* set name, width, height and update rect pointers in all regions */
66
for (unsigned int i = 0; i < nOutput; i++)
68
snprintf(str, 10, "Output %d", i);
69
outputDevs[i].setId(str, i);
71
overlappingOutputs = false;
72
setCurrentOutput (currentOutputDev);
73
for (unsigned int i = 0; i < nOutput - 1; i++)
74
for (unsigned int j = i + 1; j < nOutput; j++)
75
if (outputDevs[i].intersects(outputDevs[j]))
76
overlappingOutputs = true;
80
OutputDevices::setCurrentOutput (unsigned int outputNum)
82
if (outputNum >= outputDevs.size ())
85
currentOutputDev = outputNum;
89
OutputDevices::outputDeviceForGeometry (
90
const CompWindow::Geometry& gm,
92
CompSize* screen) const
94
int overlapAreas[outputDevs.size ()];
95
int highest, seen, highestScore;
100
if (outputDevs.size () == 1)
104
if (strategy == CoreOptions::OverlappingOutputsSmartMode)
106
int centerX, centerY;
108
/* for smart mode, calculate the overlap of the whole rectangle
109
with the output device rectangle */
110
geomRect.setWidth (gm.width () + 2 * gm.border ());
111
geomRect.setHeight (gm.height () + 2 * gm.border ());
113
x = gm.x () % screen->width ();
114
centerX = (x + (geomRect.width () / 2));
116
x += screen->width ();
117
else if (centerX > screen->width ())
118
x -= screen->width ();
121
y = gm.y () % screen->height ();
122
centerY = (y + (geomRect.height () / 2));
124
y += screen->height ();
125
else if (centerY > screen->height ())
126
y -= screen->height ();
131
/* for biggest/smallest modes, only use the window center to determine
132
the correct output device */
133
x = (gm.x () + (gm.width () / 2) + gm.border ()) % screen->width ();
135
x += screen->width ();
136
y = (gm.y () + (gm.height () / 2) + gm.border ()) % screen->height ();
138
y += screen->height ();
140
geomRect.setGeometry (x, y, 1, 1);
143
/* get amount of overlap on all output devices */
144
for (i = 0; i < outputDevs.size (); i++)
146
CompRect overlap = outputDevs[i] & geomRect;
147
overlapAreas[i] = overlap.area ();
150
/* find output with largest overlap */
151
for (i = 0, highest = 0, highestScore = 0;
152
i < outputDevs.size (); i++)
154
if (overlapAreas[i] > highestScore)
157
highestScore = overlapAreas[i];
161
/* look if the highest score is unique */
162
for (i = 0, seen = 0; i < outputDevs.size (); i++)
163
if (overlapAreas[i] == highestScore)
168
/* it's not unique, select one output of the matching ones and use the
169
user preferred strategy for that */
170
unsigned int currentSize, bestOutputSize;
174
(strategy != CoreOptions::OverlappingOutputsPreferSmallerOutput);
179
bestOutputSize = UINT_MAX;
181
for (i = 0, highest = 0; i < outputDevs.size (); i++)
182
if (overlapAreas[i] == highestScore)
186
currentSize = outputDevs[i].area ();
189
bestFit = (currentSize > bestOutputSize);
191
bestFit = (currentSize < bestOutputSize);
196
bestOutputSize = currentSize;
205
} // namespace compiz