2
* Copyright (C) 2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17
#include "mirdisplayconfigurationpolicy.h"
19
#include <mir/graphics/display_configuration_policy.h>
20
#include <mir/graphics/display_configuration.h>
21
#include <mir/geometry/point.h>
22
#include <mir/server.h>
27
namespace mg = mir::graphics;
29
#define ENV_GRID_UNIT_PX "GRID_UNIT_PX"
30
#define DEFAULT_GRID_UNIT_PX 8
33
class MirDisplayConfigurationPolicy : public mir::graphics::DisplayConfigurationPolicy
36
MirDisplayConfigurationPolicy(const std::shared_ptr<mir::graphics::DisplayConfigurationPolicy> &wrapped);
38
void apply_to(mir::graphics::DisplayConfiguration &conf) override;
41
const std::shared_ptr<mir::graphics::DisplayConfigurationPolicy> m_wrapped;
45
static float getenvFloat(const char* name, float defaultValue)
47
QByteArray stringValue = qgetenv(name);
49
float value = stringValue.toFloat(&ok);
50
return ok ? value : defaultValue;
53
MirDisplayConfigurationPolicy::MirDisplayConfigurationPolicy(
54
const std::shared_ptr<mir::graphics::DisplayConfigurationPolicy> &wrapped)
57
float gridUnit = DEFAULT_GRID_UNIT_PX;
58
if (qEnvironmentVariableIsSet(ENV_GRID_UNIT_PX)) {
59
gridUnit = getenvFloat(ENV_GRID_UNIT_PX, DEFAULT_GRID_UNIT_PX);
61
m_defaultScale = gridUnit / DEFAULT_GRID_UNIT_PX;
64
void MirDisplayConfigurationPolicy::apply_to(mg::DisplayConfiguration &conf)
66
int nextTopLeftPosition = 0;
68
m_wrapped->apply_to(conf);
70
//TODO: scan through saved configurations and select matching one to apply
72
// We want to apply a particular display config policy when connecting an external display
73
// to a phone/tablet. We don't have a reliable way to distinguish a phone/tablet display
74
// from a laptop display as yet.
76
// Best we can do currently is guess that LVDS panel implies a phone/tablet
77
bool phoneDetected = false;
80
[&](const mg::DisplayConfigurationOutput &output )
82
if (output.connected && output.used) {
85
if (output.type == mg::DisplayConfigurationOutputType::lvds) {
92
[&](mg::UserDisplayConfigurationOutput &output)
94
if (!output.connected || !output.used) {
98
output.top_left = mir::geometry::Point{nextTopLeftPosition, 0};
99
nextTopLeftPosition += output.modes[output.current_mode_index].size.width.as_int();
102
if (screenCount == 1 || output.type == mg::DisplayConfigurationOutputType::lvds) {
103
output.form_factor = mir_form_factor_phone;
104
output.scale = m_defaultScale;
105
} else { // screenCount > 1 && output.type != lvds
106
output.form_factor = mir_form_factor_monitor;
110
output.form_factor = mir_form_factor_monitor;
111
output.scale = m_defaultScale; // probably 1 on desktop anyway.
117
void qtmir::setDisplayConfigurationPolicy(mir::Server& server)
119
server.wrap_display_configuration_policy(
120
[](const std::shared_ptr<mg::DisplayConfigurationPolicy> &wrapped)
121
-> std::shared_ptr<mg::DisplayConfigurationPolicy>
123
return std::make_shared<MirDisplayConfigurationPolicy>(wrapped);