Merge lp:~jonas-drange/ubuntu-system-settings/displayConfiguration into lp:ubuntu-system-settings

Proposed by Jonas G. Drange
Status: Work in progress
Proposed branch: lp:~jonas-drange/ubuntu-system-settings/displayConfiguration
Merge into: lp:ubuntu-system-settings
Diff against target: 1591 lines (+1288/-71)
20 files modified
debian/control (+2/-0)
plugins/brightness/CMakeLists.txt (+25/-2)
plugins/brightness/ExternalDisplay.qml (+195/-0)
plugins/brightness/PageComponent.qml (+101/-64)
plugins/brightness/PageResolution.qml (+65/-0)
plugins/brightness/PageRotation.qml (+96/-0)
plugins/brightness/brightness.cpp (+13/-1)
plugins/brightness/brightness.h (+7/-0)
plugins/brightness/brightness.settings (+1/-0)
plugins/brightness/display.cpp (+162/-0)
plugins/brightness/display.h (+119/-0)
plugins/brightness/displaymodel.cpp (+133/-0)
plugins/brightness/displaymodel.h (+69/-0)
plugins/brightness/displays.cpp (+75/-0)
plugins/brightness/displays.h (+51/-0)
plugins/brightness/mirdisplays.cpp (+85/-0)
plugins/brightness/mirdisplays.h (+50/-0)
plugins/brightness/plugin.cpp (+4/-1)
plugins/brightness/plugin/CMakeLists.txt (+2/-2)
plugins/brightness/plugin/brightness-plugin.cpp (+33/-1)
To merge this branch: bzr merge lp:~jonas-drange/ubuntu-system-settings/displayConfiguration
Reviewer Review Type Date Requested Status
Ubuntu Touch System Settings Pending
Review via email: mp+281306@code.launchpad.net
To post a comment you must log in.
1579. By Jonas G. Drange

cleanup in mirdisplays and 1.0->1.3

1580. By Jonas G. Drange

some doccing as well as cleanup of imports

1581. By Jonas G. Drange

add orientation and fix local/actual code

Unmerged revisions

1581. By Jonas G. Drange

add orientation and fix local/actual code

1580. By Jonas G. Drange

some doccing as well as cleanup of imports

1579. By Jonas G. Drange

cleanup in mirdisplays and 1.0->1.3

1578. By Jonas G. Drange

mirdisplays

1577. By Jonas G. Drange

add display config

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-11-10 15:24:27 +0000
3+++ debian/control 2016-01-03 21:35:16 +0000
4@@ -15,6 +15,7 @@
5 libclick-0.4-dev,
6 libglib2.0-dev (>= 2.37.92),
7 libicu-dev,
8+ libmirclient-dev,
9 libnm-glib-dev,
10 libpolkit-agent-1-dev,
11 libqmenumodel-dev,
12@@ -26,6 +27,7 @@
13 qml-module-ubuntu-connectivity (>= 0.5.5),
14 qt5-default,
15 qtbase5-dev,
16+ qtbase5-private-dev,
17 qtdeclarative5-dev,
18 libapt-pkg-dev,
19 # test-deps
20
21=== modified file 'plugins/brightness/CMakeLists.txt'
22--- plugins/brightness/CMakeLists.txt 2014-10-25 00:30:46 +0000
23+++ plugins/brightness/CMakeLists.txt 2016-01-03 21:35:16 +0000
24@@ -1,18 +1,41 @@
25 add_subdirectory(plugin)
26
27+pkg_search_module(MIR REQUIRED mirclient)
28+find_package(Qt5Gui)
29+include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS} ${MIR_INCLUDE_DIRS})
30+
31 set(QML_SOURCES
32 PageComponent.qml
33+ PageResolution.qml
34+ PageRotation.qml
35+ ExternalDisplay.qml
36 )
37
38+add_library(uss-displays SHARED
39+ display.h
40+ display.cpp
41+ displaymodel.h
42+ displaymodel.cpp
43+ mirdisplays.h
44+ mirdisplays.cpp
45+ displays.h
46+ displays.cpp)
47+qt5_use_modules(uss-displays Quick DBus)
48+set_target_properties(uss-displays PROPERTIES VERSION 0.0 SOVERSION 0.0)
49+target_link_libraries(uss-displays ${Qt5Gui_PRIVATE_LDFLAGS} ${MIR_LDFLAGS})
50+
51 add_library(UbuntuBrightnessPanel MODULE
52+ brightness.h
53+ brightness.cpp
54 plugin.h
55- brightness.h
56 plugin.cpp
57- brightness.cpp
58 ${QML_SOURCES})
59 qt5_use_modules(UbuntuBrightnessPanel Quick Qml DBus)
60
61+target_link_libraries(UbuntuBrightnessPanel uss-displays)
62+
63 set(PLUG_DIR ${PLUGIN_PRIVATE_MODULE_DIR}/Ubuntu/SystemSettings/Brightness)
64+install(TARGETS uss-displays DESTINATION ${PLUGIN_MODULE_DIR})
65 install(TARGETS UbuntuBrightnessPanel DESTINATION ${PLUG_DIR})
66 install(FILES qmldir DESTINATION ${PLUG_DIR})
67 install(FILES brightness.settings DESTINATION ${PLUGIN_MANIFEST_DIR})
68
69=== added file 'plugins/brightness/ExternalDisplay.qml'
70--- plugins/brightness/ExternalDisplay.qml 1970-01-01 00:00:00 +0000
71+++ plugins/brightness/ExternalDisplay.qml 2016-01-03 21:35:16 +0000
72@@ -0,0 +1,195 @@
73+/*
74+ * This file is part of system-settings
75+ *
76+ * Copyright (C) 2015 Canonical Ltd.
77+ *
78+ * This program is free software: you can redistribute it and/or modify it
79+ * under the terms of the GNU General Public License version 3, as published
80+ * by the Free Software Foundation.
81+ *
82+ * This program is distributed in the hope that it will be useful, but
83+ * WITHOUT ANY WARRANTY; without even the implied warranties of
84+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
85+ * PURPOSE. See the GNU General Public License for more details.
86+ *
87+ * You should have received a copy of the GNU General Public License along
88+ * with this program. If not, see <http://www.gnu.org/licenses/>.
89+ *
90+ * Authors:
91+ * Jonas G. Drange <jonas.drange@canonical.com>
92+ */
93+
94+import QtQuick 2.4
95+import SystemSettings 1.0
96+import Ubuntu.Components 1.3
97+import Ubuntu.Components.ListItems 1.3 as ListItems
98+import Ubuntu.Settings.Menus 0.1 as Menus
99+import Ubuntu.Settings.Components 0.1 as USC
100+import Ubuntu.SystemSettings.Brightness 1.0
101+
102+Column {
103+
104+ property var localOrientation
105+ property string localMode
106+ property var localEnabled
107+
108+ signal apply();
109+
110+ ListItems.Standard {
111+ text: i18n.tr("External display")
112+ enabled: model.connected
113+ onClicked: enabledCheck.trigger()
114+ control: CheckBox {
115+ id: enabledCheck
116+ property bool serverChecked: model.enabled
117+ onServerCheckedChanged: checked = serverChecked
118+ Component.onCompleted: checked = serverChecked
119+ onTriggered: {
120+ console.warn('disabling display');
121+ localEnabled = checked;
122+ }
123+ }
124+ }
125+
126+ ListItems.SingleValue {
127+ text: i18n.tr("Rotation")
128+ value: {
129+ console.warn('display orientation', model.orientation);
130+ switch (model.orientation) {
131+ case Display.Normal:
132+ return i18n.tr("None");
133+ break;
134+ case Display.PortraitMode:
135+ return i18n.tr("90° clockwise");
136+ break;
137+ case Display.LandscapeInvertedMode:
138+ return i18n.tr("180° clockwise");
139+ break;
140+ case Display.PortraitInvertedMode:
141+ return i18n.tr("270° clockwise");
142+ break;
143+ default:
144+ throw "Unable to determine orientation type.";
145+ }
146+ }
147+ visible: model.enabled
148+ progression: true
149+ onClicked: {
150+ var rotationPage = pageStack.push(
151+ Qt.resolvedUrl("PageRotation.qml"), {
152+ orientation: model.orientation
153+ }
154+ );
155+ rotationPage.orientationChanged.connect(
156+ function () {
157+ console.warn('locally setting orientation', rotationPage.orientation);
158+ localOrientation = rotationPage.orientation;
159+ }
160+ );
161+ }
162+ }
163+
164+ ListItems.SingleValue {
165+ text: i18n.tr("Resolution")
166+ value: model.mode
167+ visible: model.enabled
168+ progression: true
169+ onClicked: {
170+ var resPage = pageStack.push(
171+ Qt.resolvedUrl("PageResolution.qml"), {
172+ modes: availableModes,
173+ mode: mode
174+ }
175+ );
176+ resPage.modeChanged.connect(
177+ function (mode) {
178+ localMode = mode;
179+ }
180+ );
181+ }
182+ }
183+
184+ SettingsItemTitle {
185+ text: i18n.tr("Scale UI elements")
186+ visible: model.enabled && showAllUI
187+ showDivider: false
188+ }
189+
190+ Menus.SliderMenu {
191+ id: scaleSlider
192+ objectName: "scaleSlider"
193+ visible: model.enabled && showAllUI
194+ live: true
195+ minimumValue: 0.0
196+ maximumValue: 100.0
197+ value: localScale >= 0 ? localScale : model.scale
198+ onUpdated: localScale = value
199+ }
200+
201+ Column {
202+ anchors {
203+ left: parent.left;
204+ right: parent.right
205+ leftMargin: spacing
206+ rightMargin: spacing
207+ }
208+ visible: model.enabled
209+ spacing: units.gu(1)
210+
211+ Button {
212+ anchors { left: parent.left; right: parent.right }
213+ text: i18n.tr("Apply changes")
214+ enabled: localOrientation ||
215+ localMode ||
216+ (typeof localEnabled !== "undefined")
217+ onClicked: {
218+ if (localOrientation) {
219+ model.orientation = localOrientation;
220+ localOrientation = null;
221+ }
222+
223+ if (localMode) {
224+ model.mode = localMode;
225+ localMode = "";
226+ }
227+
228+ if (typeof localEnabled !== "undefined") {
229+ model.enabled = localEnabled;
230+ localEnabled = null;
231+ }
232+
233+ apply();
234+ }
235+ }
236+
237+ ListItems.ThinDivider { opacity: 0 }
238+
239+ Button {
240+ anchors { left: parent.left; right: parent.right }
241+ text: i18n.tr("Sound settings…")
242+ onClicked: {
243+ var sPlugin = pluginManager.getByName("sound")
244+ if (sPlugin) {
245+ var soundPage = sPlugin.pageComponent;
246+ if (soundPage)
247+ pageStack.push(soundPage);
248+ else
249+ console.warn(
250+ "Failed to get sound page " +
251+ "pageComponent"
252+ );
253+ } else {
254+ console.warn(
255+ "Failed to get sound plugin " +
256+ "instance"
257+ )
258+ }
259+ }
260+ }
261+
262+ Button {
263+ anchors { left: parent.left; right: parent.right }
264+ text: i18n.tr("External keyboard…")
265+ }
266+ }
267+}
268
269=== modified file 'plugins/brightness/PageComponent.qml'
270--- plugins/brightness/PageComponent.qml 2015-08-10 13:31:45 +0000
271+++ plugins/brightness/PageComponent.qml 2016-01-03 21:35:16 +0000
272@@ -38,70 +38,107 @@
273 id: brightnessPanel
274 }
275
276- Column {
277- anchors.left: parent.left
278- anchors.right: parent.right
279-
280- QDBusActionGroup {
281- id: indicatorPower
282- busType: 1
283- busName: "com.canonical.indicator.power"
284- objectPath: "/com/canonical/indicator/power"
285-
286- property variant brightness: action("brightness")
287-
288- Component.onCompleted: start()
289- }
290-
291- ListItem.Standard {
292- text: i18n.tr("Display brightness")
293- showDivider: false
294- }
295-
296- /* Use the SliderMenu component instead of the Slider to avoid binding
297- issues on valueChanged until LP: #1388094 is fixed.
298- */
299- Menus.SliderMenu {
300- id: brightnessSlider
301- objectName: "sliderMenu"
302- enabled: indicatorPower.brightness.state != null
303- live: true
304- minimumValue: 0.0
305- maximumValue: 100.0
306- minIcon: "image://theme/display-brightness-min"
307- maxIcon: "image://theme/display-brightness-max"
308-
309- property real serverValue: enabled ? indicatorPower.brightness.state * 100 : 0.0
310-
311- USC.ServerPropertySynchroniser {
312- userTarget: brightnessSlider
313- userProperty: "value"
314- serverTarget: brightnessSlider
315- serverProperty: "serverValue"
316- maximumWaitBufferInterval: 16
317-
318- onSyncTriggered: indicatorPower.brightness.updateState(value / 100.0)
319- }
320- }
321-
322- ListItem.Standard {
323- id: adjust
324- text: i18n.tr("Adjust automatically")
325- visible: brightnessPanel.powerdRunning &&
326- brightnessPanel.autoBrightnessAvailable
327- control: CheckBox {
328- id: autoAdjustCheck
329- property bool serverChecked: gsettings.autoBrightness
330- onServerCheckedChanged: checked = serverChecked
331- Component.onCompleted: checked = serverChecked
332- onTriggered: gsettings.autoBrightness = checked
333- }
334- showDivider: false
335- }
336- ListItem.Caption {
337- text: i18n.tr(
338- "Brightens and dims the display to suit the surroundings.")
339- visible: adjust.visible
340+ Flickable {
341+ anchors.fill: parent
342+ contentHeight: contentItem.childrenRect.height
343+ boundsBehavior: (contentHeight > root.height) ?
344+ Flickable.DragAndOvershootBounds :
345+ Flickable.StopAtBounds
346+ /* Set the direction to workaround
347+ https://bugreports.qt-project.org/browse/QTBUG-31905 otherwise the UI
348+ might end up in a situation where scrolling doesn't work */
349+ flickableDirection: Flickable.VerticalFlick
350+
351+ Column {
352+ anchors.left: parent.left
353+ anchors.right: parent.right
354+
355+ QDBusActionGroup {
356+ id: indicatorPower
357+ busType: 1
358+ busName: "com.canonical.indicator.power"
359+ objectPath: "/com/canonical/indicator/power"
360+
361+ property variant brightness: action("brightness")
362+
363+ Component.onCompleted: start()
364+ }
365+
366+ SettingsItemTitle {
367+ text: i18n.tr("Display brightness")
368+ showDivider: false
369+ }
370+
371+ /* Use the SliderMenu component instead of the Slider to avoid binding
372+ issues on valueChanged until LP: #1388094 is fixed.
373+ */
374+ Menus.SliderMenu {
375+ id: brightnessSlider
376+ objectName: "sliderMenu"
377+ enabled: indicatorPower.brightness.state != null
378+ live: true
379+ minimumValue: 0.0
380+ maximumValue: 100.0
381+ minIcon: "image://theme/display-brightness-min"
382+ maxIcon: "image://theme/display-brightness-max"
383+ showDivider: adjust.visible
384+ property real serverValue: enabled ? indicatorPower.brightness.state * 100 : 0.0
385+
386+ USC.ServerPropertySynchroniser {
387+ userTarget: brightnessSlider
388+ userProperty: "value"
389+ serverTarget: brightnessSlider
390+ serverProperty: "serverValue"
391+ maximumWaitBufferInterval: 16
392+
393+ onSyncTriggered: indicatorPower.brightness.updateState(value / 100.0)
394+ }
395+ }
396+
397+ ListItem.Standard {
398+ id: adjust
399+ text: i18n.tr("Adjust automatically")
400+ visible: brightnessPanel.powerdRunning &&
401+ brightnessPanel.autoBrightnessAvailable
402+ control: CheckBox {
403+ id: autoAdjustCheck
404+ property bool serverChecked: gsettings.autoBrightness
405+ onServerCheckedChanged: checked = serverChecked
406+ Component.onCompleted: checked = serverChecked
407+ onTriggered: gsettings.autoBrightness = checked
408+ }
409+ showDivider: false
410+ }
411+
412+ ListItem.Caption {
413+ text: i18n.tr(
414+ "Brightens and dims the display to suit the surroundings.")
415+ visible: adjust.visible
416+ }
417+
418+ ListItem.Divider {
419+ visible: brightnessPanel.displays.count > 0
420+ }
421+
422+ Repeater {
423+ id: rep
424+ model: brightnessPanel.displays
425+
426+ delegate: ExternalDisplay {
427+ Component.onCompleted: console.warn('model.mode', mode);
428+ onApply: {
429+ console.warn('apply event obseverd by pagecompo');
430+ brightnessPanel.configureDisplay();
431+ }
432+ anchors { left: parent.left; right: parent.right }
433+ }
434+ }
435+
436+ ListItem.Divider {
437+ anchors { left: parent.left; right: parent.right; }
438+ height: units.gu(10)
439+ opacity: 0
440+ }
441 }
442 }
443
444
445=== added file 'plugins/brightness/PageResolution.qml'
446--- plugins/brightness/PageResolution.qml 1970-01-01 00:00:00 +0000
447+++ plugins/brightness/PageResolution.qml 2016-01-03 21:35:16 +0000
448@@ -0,0 +1,65 @@
449+/*
450+ * This file is part of system-settings
451+ *
452+ * Copyright (C) 2015 Canonical Ltd.
453+ *
454+ * This program is free software: you can redistribute it and/or modify it
455+ * under the terms of the GNU General Public License version 3, as published
456+ * by the Free Software Foundation.
457+ *
458+ * This program is distributed in the hope that it will be useful, but
459+ * WITHOUT ANY WARRANTY; without even the implied warranties of
460+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
461+ * PURPOSE. See the GNU General Public License for more details.
462+ *
463+ * You should have received a copy of the GNU General Public License along
464+ * with this program. If not, see <http://www.gnu.org/licenses/>.
465+ *
466+ * Authors:
467+ * Jonas G. Drange <jonas.drange@canonical.com>
468+ */
469+
470+import QtQuick 2.0
471+import SystemSettings 1.0
472+import Ubuntu.Components 1.3
473+import Ubuntu.Components.ListItems 1.3 as ListItem
474+import Ubuntu.SystemSettings.Brightness 1.0
475+
476+ItemPage {
477+ id: root
478+ title: i18n.tr("Resolution")
479+ objectName: "modePage"
480+
481+ property var modes
482+ property string mode
483+
484+ Flickable {
485+ id: scrollWidget
486+ anchors.fill: parent
487+ contentHeight: contentItem.childrenRect.height
488+ boundsBehavior: (contentHeight > root.height) ?
489+ Flickable.DragAndOvershootBounds :
490+ Flickable.StopAtBounds
491+
492+ Column {
493+ anchors.left: parent.left
494+ anchors.right: parent.right
495+
496+ ListItem.ItemSelector {
497+ id: modeSelector
498+ objectName: "modeSelector"
499+ delegate: OptionSelectorDelegate {
500+ text: modelData
501+ }
502+ model: modes
503+ expanded: true
504+ highlightWhenPressed: false
505+ onDelegateClicked: mode = model[index]
506+ Component.onCompleted: {
507+ selectedIndex = modes.indexOf(mode)
508+ console.warn("slected", modes, mode, modes.indexOf(mode))
509+ }
510+ }
511+ }
512+ }
513+}
514
515=== added file 'plugins/brightness/PageRotation.qml'
516--- plugins/brightness/PageRotation.qml 1970-01-01 00:00:00 +0000
517+++ plugins/brightness/PageRotation.qml 2016-01-03 21:35:16 +0000
518@@ -0,0 +1,96 @@
519+/*
520+ * This file is part of system-settings
521+ *
522+ * Copyright (C) 2015 Canonical Ltd.
523+ *
524+ * This program is free software: you can redistribute it and/or modify it
525+ * under the terms of the GNU General Public License version 3, as published
526+ * by the Free Software Foundation.
527+ *
528+ * This program is distributed in the hope that it will be useful, but
529+ * WITHOUT ANY WARRANTY; without even the implied warranties of
530+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
531+ * PURPOSE. See the GNU General Public License for more details.
532+ *
533+ * You should have received a copy of the GNU General Public License along
534+ * with this program. If not, see <http://www.gnu.org/licenses/>.
535+ *
536+ * Authors:
537+ * Jonas G. Drange <jonas.drange@canonical.com>
538+ */
539+
540+import QtQuick 2.0
541+import SystemSettings 1.0
542+import Ubuntu.Components 1.3
543+import Ubuntu.Components.ListItems 1.3 as ListItem
544+import Ubuntu.SystemSettings.Brightness 1.0
545+
546+ItemPage {
547+ id: root
548+ title: i18n.tr("Resolution")
549+ objectName: "resolutionPage"
550+
551+ property var orientation
552+
553+ Flickable {
554+ id: scrollWidget
555+ anchors.fill: parent
556+ contentHeight: contentItem.childrenRect.height
557+ boundsBehavior: (contentHeight > root.height) ?
558+ Flickable.DragAndOvershootBounds :
559+ Flickable.StopAtBounds
560+
561+ Column {
562+ anchors.left: parent.left
563+ anchors.right: parent.right
564+
565+ ListItem.ItemSelector {
566+ id: orientationSelector
567+ objectName: "orientationSelector"
568+ model: [
569+ i18n.tr("None"),
570+ i18n.tr("90° clockwise"),
571+ i18n.tr("180° clockwise"),
572+ i18n.tr("270° clockwise")
573+ ]
574+ expanded: true
575+ highlightWhenPressed: false
576+ onDelegateClicked: {
577+ switch (index) {
578+ case 0:
579+ orientation = Display.Normal;
580+ break;
581+ case 1:
582+ orientation = Display.PortraitMode;
583+ break;
584+ case 2:
585+ orientation = Display.LandscapeInvertedMode;
586+ break;
587+ case 3:
588+ orientation = Display.PortraitInvertedMode;
589+ break;
590+ }
591+ }
592+ Component.onCompleted: {
593+ console.warn('orientation', orientation)
594+ switch (orientation) {
595+ case Display.Normal:
596+ selectedIndex = 0;
597+ break;
598+ case Display.PortraitMode:
599+ selectedIndex = 1;
600+ break;
601+ case Display.LandscapeInvertedMode:
602+ selectedIndex = 2;
603+ break;
604+ case Display.PortraitInvertedMode:
605+ selectedIndex = 3;
606+ break;
607+ default:
608+ throw "Unable to determine orientation type.";
609+ }
610+ }
611+ }
612+ }
613+ }
614+}
615
616=== modified file 'plugins/brightness/brightness.cpp'
617--- plugins/brightness/brightness.cpp 2014-12-08 21:41:24 +0000
618+++ plugins/brightness/brightness.cpp 2016-01-03 21:35:16 +0000
619@@ -20,10 +20,13 @@
620
621 #include "brightness.h"
622
623+//#include <qpa/qplatformnativeinterface.h>
624+
625 #include <QDBusArgument>
626 #include <QDBusReply>
627 #include <QDBusMetaType>
628 #include <QDebug>
629+#include <QGuiApplication>
630
631 // Returned data from getBrightnessParams
632 struct BrightnessParams {
633@@ -61,7 +64,8 @@
634 "com.canonical.powerd",
635 m_systemBusConnection),
636 m_powerdRunning(false),
637- m_autoBrightnessAvailable(false)
638+ m_autoBrightnessAvailable(false),
639+ m_displays(this)
640 {
641 qRegisterMetaType<BrightnessParams>();
642 m_powerdRunning = m_powerdIface.isValid();
643@@ -90,3 +94,11 @@
644 bool Brightness::getPowerdRunning() const {
645 return m_powerdRunning;
646 }
647+
648+QAbstractItemModel * Brightness::displays() {
649+ return m_displays.displays();
650+}
651+
652+void Brightness::configureDisplay() {
653+ m_displays.applyDisplayConfiguration();
654+}
655
656=== modified file 'plugins/brightness/brightness.h'
657--- plugins/brightness/brightness.h 2014-01-27 13:01:26 +0000
658+++ plugins/brightness/brightness.h 2016-01-03 21:35:16 +0000
659@@ -23,6 +23,7 @@
660
661 #include <QDBusInterface>
662 #include <QObject>
663+#include "displays.h"
664
665 class Brightness : public QObject
666 {
667@@ -33,11 +34,16 @@
668 Q_PROPERTY (bool autoBrightnessAvailable
669 READ getAutoBrightnessAvailable
670 CONSTANT)
671+ Q_PROPERTY (QAbstractItemModel * displays
672+ READ displays
673+ CONSTANT)
674
675 public:
676 explicit Brightness(QObject *parent = 0);
677 bool getPowerdRunning() const;
678 bool getAutoBrightnessAvailable() const;
679+ QAbstractItemModel * displays();
680+ Q_INVOKABLE void configureDisplay();
681
682 private:
683 QDBusConnection m_systemBusConnection;
684@@ -45,6 +51,7 @@
685 QDBusInterface m_powerdIface;
686 bool m_powerdRunning;
687 bool m_autoBrightnessAvailable;
688+ Displays m_displays;
689 };
690
691 #endif // BRIGHTNESS_H
692
693=== modified file 'plugins/brightness/brightness.settings'
694--- plugins/brightness/brightness.settings 2014-09-24 17:10:03 +0000
695+++ plugins/brightness/brightness.settings 2016-01-03 21:35:16 +0000
696@@ -14,5 +14,6 @@
697 ],
698 "has-dynamic-keywords": false,
699 "has-dynamic-visibility": true,
700+ "has-dynamic-name": true,
701 "page-component": "PageComponent.qml"
702 }
703
704=== added file 'plugins/brightness/display.cpp'
705--- plugins/brightness/display.cpp 1970-01-01 00:00:00 +0000
706+++ plugins/brightness/display.cpp 2016-01-03 21:35:16 +0000
707@@ -0,0 +1,162 @@
708+/*
709+ * Copyright (C) 2015 Canonical Ltd
710+ *
711+ * This program is free software: you can redistribute it and/or modify
712+ * it under the terms of the GNU General Public License version 3 as
713+ * published by the Free Software Foundation.
714+ *
715+ * This program is distributed in the hope that it will be useful,
716+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
717+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
718+ * GNU General Public License for more details.
719+ *
720+ * You should have received a copy of the GNU General Public License
721+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
722+ *
723+ * Authors:
724+ * Jonas G. Drange <jonas.drange@canonical.com>
725+ *
726+ */
727+
728+#include <QDebug>
729+
730+#include "display.h"
731+
732+Display::Display(MirDisplayOutput *output) {
733+ setDisplayOutput(output);
734+}
735+
736+void Display::updateModes() {
737+ qWarning() << "updateModes";
738+ for (unsigned int i = 0; i < m_mirOutput->num_modes; ++i) {
739+ MirDisplayMode mode = m_mirOutput->modes[i];
740+ m_availableModes << QString("%1x%2x%3").arg(
741+ QString::number(mode.vertical_resolution),
742+ QString::number(mode.horizontal_resolution),
743+ QString::number(mode.refresh_rate));
744+ qWarning() << "mode" << i << m_availableModes;
745+ if (i == m_mirOutput->current_mode) {
746+ m_currentMode = i;
747+ m_refreshRate = mode.refresh_rate;
748+ }
749+ }
750+}
751+
752+void Display::updateSizes() {
753+ qWarning() << "updateSizes";
754+ m_physicalSize = QSizeF(
755+ QSize(m_mirOutput->physical_width_mm,
756+ m_mirOutput->physical_height_mm)
757+ );
758+}
759+
760+void Display::updateOrientation() {
761+ qWarning() << "updateOrientation";
762+ m_orientation = m_mirOutput->orientation;
763+}
764+
765+int Display::id() const {
766+ return m_id;
767+}
768+bool Display::enabled() const {
769+ return m_enabled && m_powerMode == mir_power_mode_on;
770+}
771+
772+bool Display::connected() const {
773+ return m_connected;
774+}
775+
776+QString Display::mode() const {
777+ return m_availableModes.value(m_currentMode, QString());
778+}
779+
780+QStringList Display::availableModes() const {
781+ return m_availableModes;
782+}
783+
784+Display::Orientation Display::orientation() const {
785+ qWarning() << __PRETTY_FUNCTION__ << m_orientation;
786+ switch (m_orientation) {
787+ case mir_orientation_normal:
788+ return Display::Orientation::Normal;
789+ case mir_orientation_left:
790+ return Display::Orientation::PortraitMode;
791+ case mir_orientation_inverted:
792+ return Display::Orientation::LandscapeInvertedMode;
793+ case mir_orientation_right:
794+ return Display::Orientation::PortraitInvertedMode;
795+ default:
796+ return Display::Orientation::Normal;
797+ }
798+}
799+
800+MirDisplayOutput * Display::getDisplayOutput() const {
801+ return m_mirOutput;
802+}
803+
804+void Display::setEnabled(const bool &enabled) {
805+ m_mirOutput->used = enabled;
806+ if (enabled) {
807+ int index = m_availableModes.indexOf(mode());
808+ uint32_t i = (uint32_t)index;
809+ m_mirOutput->current_mode = i;
810+ m_mirOutput->power_mode = mir_power_mode_on;
811+ } else {
812+ m_mirOutput->current_mode = 0;
813+ m_mirOutput->power_mode = mir_power_mode_standby;
814+ }
815+ m_powerMode = m_mirOutput->power_mode;
816+}
817+
818+void Display::setMode(const QString &mode) {
819+ int index = m_availableModes.indexOf(mode);
820+ if (index >= 0) {
821+ uint32_t i = (uint32_t)index;
822+ m_mirOutput->current_mode = i;
823+ } else {
824+ qWarning() << __PRETTY_FUNCTION__ << "failed to set mode to" << mode;
825+ }
826+}
827+
828+void Display::setOrientation(const Orientation &orientation) {
829+ qWarning() << __PRETTY_FUNCTION__ << orientation;
830+ MirOrientation newOrientation;
831+ switch (orientation) {
832+ case Display::Orientation::Normal:
833+ newOrientation = mir_orientation_normal;
834+ break;
835+ case Display::Orientation::PortraitMode:
836+ newOrientation = mir_orientation_left;
837+ break;
838+ case Display::Orientation::LandscapeInvertedMode:
839+ newOrientation = mir_orientation_inverted;
840+ break;
841+ case Display::Orientation::PortraitInvertedMode:
842+ newOrientation = mir_orientation_right;
843+ break;
844+ default:
845+ newOrientation = mir_orientation_normal;
846+ }
847+ m_orientation = newOrientation;
848+}
849+
850+void Display::setDisplayOutput(MirDisplayOutput * output) {
851+ qWarning() << __PRETTY_FUNCTION__ << output;
852+ m_mirOutput = output;
853+ if (output) {
854+ m_connected = output->connected;
855+ m_enabled = output->used && output->power_mode == mir_power_mode_on;
856+ m_id = output->output_id;
857+ m_powerMode = static_cast<MirPowerMode>(output->power_mode);
858+ m_orientation = static_cast<MirOrientation>(output->orientation);
859+ qWarning() << "Sat display output, type:"
860+ << output->type
861+ << "connected:" << output->connected
862+ << "used:" << output->used
863+ << "orientation:" << output->orientation;
864+
865+ updateModes();
866+ updateOrientation();
867+ updateSizes();
868+ }
869+}
870
871=== added file 'plugins/brightness/display.h'
872--- plugins/brightness/display.h 1970-01-01 00:00:00 +0000
873+++ plugins/brightness/display.h 2016-01-03 21:35:16 +0000
874@@ -0,0 +1,119 @@
875+/*
876+ * Copyright (C) 2015 Canonical Ltd
877+ *
878+ * This program is free software: you can redistribute it and/or modify
879+ * it under the terms of the GNU General Public License version 3 as
880+ * published by the Free Software Foundation.
881+ *
882+ * This program is distributed in the hope that it will be useful,
883+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
884+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
885+ * GNU General Public License for more details.
886+ *
887+ * You should have received a copy of the GNU General Public License
888+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
889+ *
890+ * Authors:
891+ * Jonas G. Drange <jonas.drange@canonical.com>
892+ *
893+ * A abstraction of a display, currently only suitable for use with Mir.
894+ * Note: It is assumed that this class will eventually be replaced
895+ * by QScreen objects produced by platform abstraction APIs.
896+ */
897+
898+#ifndef DISPLAY_H
899+#define DISPLAY_H
900+
901+#include <QDBusInterface>
902+#include <QObject>
903+#include <QScreen>
904+#include <mir_toolkit/client_types.h>
905+
906+struct Display : QObject
907+{
908+ Q_OBJECT
909+
910+public:
911+
912+ Display() {}
913+ ~Display() {}
914+ Display(MirDisplayOutput * output);
915+ Q_PROPERTY( int id
916+ READ id
917+ CONSTANT )
918+ Q_PROPERTY( bool enabled
919+ READ enabled
920+ WRITE setEnabled
921+ NOTIFY enabledChanged )
922+ Q_PROPERTY( bool connected
923+ READ connected
924+ NOTIFY connectedChanged )
925+ Q_PROPERTY( QStringList availableModes
926+ READ availableModes
927+ NOTIFY availableModesChanged )
928+ Q_PROPERTY( QString mode
929+ READ mode
930+ WRITE setMode
931+ NOTIFY modeChanged )
932+ Q_PROPERTY( Orientation orientation
933+ READ orientation
934+ WRITE setOrientation
935+ NOTIFY orientationChanged )
936+
937+ enum Orientation {
938+ Normal, PortraitMode, LandscapeInvertedMode,
939+ PortraitInvertedMode
940+ };
941+
942+ Q_ENUMS(Orientation)
943+
944+ int id() const;
945+
946+ bool enabled() const;
947+ void setEnabled(const bool &enabled);
948+
949+ bool connected() const;
950+
951+ QStringList availableModes() const;
952+
953+ QString mode() const;
954+ void setMode(const QString &mode);
955+
956+ Orientation orientation() const;
957+ void setOrientation(const Orientation &orientation);
958+
959+ // TODO: Move to some private object as to not expose too much
960+ // MIR specific stuff in this model.
961+ MirDisplayOutput * getDisplayOutput() const;
962+ void setDisplayOutput(MirDisplayOutput * output);
963+
964+Q_SIGNALS:
965+ void enabledChanged();
966+ void connectedChanged();
967+ void availableModesChanged();
968+ void modeChanged();
969+ void orientationChanged();
970+
971+private:
972+ void updateModes();
973+ void updateOrientation();
974+ void updateSizes();
975+
976+ // TODO: hide this in some private object in this model
977+ MirDisplayOutput * m_mirOutput;
978+
979+ QSize m_size;
980+ QSizeF m_physicalSize;
981+ qreal m_refreshRate;
982+ MirOrientation m_orientation;
983+ QStringList m_availableModes;
984+ int m_currentMode;
985+ bool m_enabled;
986+ bool m_connected;
987+ MirPowerMode m_powerMode;
988+ int m_id;
989+};
990+
991+Q_DECLARE_METATYPE(Display*)
992+
993+#endif // DISPLAY_H
994
995=== added file 'plugins/brightness/displaymodel.cpp'
996--- plugins/brightness/displaymodel.cpp 1970-01-01 00:00:00 +0000
997+++ plugins/brightness/displaymodel.cpp 2016-01-03 21:35:16 +0000
998@@ -0,0 +1,133 @@
999+/*
1000+ * Copyright (C) 2015 Canonical Ltd
1001+ *
1002+ * This program is free software: you can redistribute it and/or modify
1003+ * it under the terms of the GNU General Public License version 3 as
1004+ * published by the Free Software Foundation.
1005+ *
1006+ * This program is distributed in the hope that it will be useful,
1007+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1008+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1009+ * GNU General Public License for more details.
1010+ *
1011+ * You should have received a copy of the GNU General Public License
1012+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1013+ *
1014+ * Authors:
1015+ * Jonas G. Drange <jonas.drange@canonical.com>
1016+ *
1017+ */
1018+
1019+#include <QDebug>
1020+#include "displaymodel.h"
1021+
1022+DisplayListModel::DisplayListModel(QObject *parent)
1023+ : QAbstractListModel(parent) {
1024+}
1025+
1026+void DisplayListModel::addDisplay(QSharedPointer<Display> &display) {
1027+ int at = rowCount();
1028+ for (int i = 0; i < m_displays.size(); ++i) {
1029+ if (display->id() < m_displays.at(i)->id()) {
1030+ at = i;
1031+ break;
1032+ }
1033+ }
1034+ beginInsertRows(QModelIndex(), at, at);
1035+ m_displays.insert(at, display);
1036+ endInsertRows();
1037+}
1038+
1039+int DisplayListModel::rowCount(const QModelIndex & parent) const {
1040+ Q_UNUSED(parent);
1041+ return m_displays.count();
1042+}
1043+
1044+QVariant DisplayListModel::data(const QModelIndex & index, int role) const {
1045+ QVariant ret;
1046+ if (index.row() < 0 || index.row() >= m_displays.count())
1047+ return ret;
1048+
1049+ auto display = m_displays[index.row()];
1050+ switch (role) {
1051+ case Qt::DisplayRole:
1052+ ret = QString("Display %1").arg(QString::number(display->id()));
1053+ break;
1054+ case EnabledRole:
1055+ ret = display->enabled();
1056+ break;
1057+ case ConnectedRole:
1058+ ret = display->connected();
1059+ break;
1060+ case ModeRole:
1061+ ret = display->mode();
1062+ break;
1063+ case AvailableModesRole:
1064+ ret = display->availableModes();
1065+ break;
1066+ case OrientationRole:
1067+ ret = display->orientation();
1068+ break;
1069+ }
1070+ return ret;
1071+}
1072+
1073+bool DisplayListModel::setData(const QModelIndex &index,
1074+ const QVariant &value,
1075+ int role)
1076+{
1077+ if (index.row() < 0 || index.row() >= m_displays.count())
1078+ return false;
1079+ auto display = m_displays[index.row()];
1080+ switch (role) {
1081+ case EnabledRole:
1082+ switch (static_cast<QMetaType::Type>(value.type())) {
1083+ case QMetaType::Bool:
1084+ case QMetaType::QChar:
1085+ case QMetaType::Int:
1086+ case QMetaType::UInt:
1087+ case QMetaType::LongLong:
1088+ case QMetaType::ULongLong:
1089+ display->setEnabled(value.toBool());
1090+ return true;
1091+
1092+ default:
1093+ break;
1094+ }
1095+
1096+ break;
1097+ }
1098+
1099+ return false;
1100+}
1101+
1102+QHash<int, QByteArray> DisplayListModel::roleNames() const {
1103+ QHash<int, QByteArray> roles;
1104+ roles[EnabledRole] = "enabled";
1105+ roles[ConnectedRole] = "connected";
1106+ roles[ModeRole] = "mode";
1107+ roles[AvailableModesRole] = "availableModes";
1108+ roles[OrientationRole] = "orientation";
1109+ // roles[ScaleRole] = "scale";
1110+ return roles;
1111+}
1112+
1113+QSharedPointer<Display> DisplayListModel::getDisplay(const int outputId) const {
1114+ QSharedPointer<Display> display;
1115+
1116+ for (int i=0, n=m_displays.size(); i<n; i++)
1117+ if (m_displays[i]->id() == outputId)
1118+ return m_displays[i];
1119+
1120+ return display;
1121+}
1122+
1123+QModelIndex DisplayListModel::index(int row, int column,
1124+ const QModelIndex & parent) const {
1125+ Q_UNUSED(parent);
1126+ Q_UNUSED(column);
1127+ return createIndex(row, column);
1128+}
1129+
1130+DisplayListModel::~DisplayListModel() {
1131+}
1132
1133=== added file 'plugins/brightness/displaymodel.h'
1134--- plugins/brightness/displaymodel.h 1970-01-01 00:00:00 +0000
1135+++ plugins/brightness/displaymodel.h 2016-01-03 21:35:16 +0000
1136@@ -0,0 +1,69 @@
1137+/*
1138+ * Copyright (C) 2015 Canonical Ltd
1139+ *
1140+ * This program is free software: you can redistribute it and/or modify
1141+ * it under the terms of the GNU General Public License version 3 as
1142+ * published by the Free Software Foundation.
1143+ *
1144+ * This program is distributed in the hope that it will be useful,
1145+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1146+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1147+ * GNU General Public License for more details.
1148+ *
1149+ * You should have received a copy of the GNU General Public License
1150+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1151+ *
1152+ * Authors:
1153+ * Jonas G. Drange <jonas.drange@canonical.com>
1154+ *
1155+ * A model for storing and accessing displays.
1156+ */
1157+
1158+#ifndef DISPLAY_MODEL_H
1159+#define DISPLAY_MODEL_H
1160+
1161+#include <QObject>
1162+#include <QAbstractListModel>
1163+#include <QSharedPointer>
1164+
1165+#include "display.h"
1166+
1167+class DisplayListModel : public QAbstractListModel
1168+{
1169+ Q_OBJECT
1170+
1171+public:
1172+ explicit DisplayListModel(QObject *parent = 0);
1173+ ~DisplayListModel();
1174+
1175+ enum Roles
1176+ {
1177+ // Qt::DisplayRole holds display name
1178+ EnabledRole = Qt::UserRole,
1179+ ConnectedRole,
1180+ ModeRole,
1181+ AvailableModesRole,
1182+ OrientationRole
1183+ };
1184+
1185+ void addDisplay(QSharedPointer<Display> &display);
1186+
1187+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
1188+ bool setData(const QModelIndex &index, const QVariant &value,
1189+ int role = Qt::EditRole);
1190+ int rowCount(const QModelIndex & parent = QModelIndex()) const;
1191+ QModelIndex index(int row, int column,
1192+ const QModelIndex & parent = QModelIndex()) const;
1193+
1194+ QSharedPointer<Display> getDisplay(const int outputId) const;
1195+
1196+ Q_INVOKABLE bool apply(const bool &enabled);
1197+
1198+protected:
1199+ QHash<int, QByteArray> roleNames() const;
1200+
1201+private:
1202+ QList<QSharedPointer<Display> > m_displays;
1203+};
1204+
1205+#endif // DISPLAY_MODEL_H
1206
1207=== added file 'plugins/brightness/displays.cpp'
1208--- plugins/brightness/displays.cpp 1970-01-01 00:00:00 +0000
1209+++ plugins/brightness/displays.cpp 2016-01-03 21:35:16 +0000
1210@@ -0,0 +1,75 @@
1211+/*
1212+ * Copyright (C) 2015 Canonical Ltd
1213+ *
1214+ * This program is free software: you can redistribute it and/or modify
1215+ * it under the terms of the GNU General Public License version 3 as
1216+ * published by the Free Software Foundation.
1217+ *
1218+ * This program is distributed in the hope that it will be useful,
1219+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1220+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1221+ * GNU General Public License for more details.
1222+ *
1223+ * You should have received a copy of the GNU General Public License
1224+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1225+ *
1226+ * Authors:
1227+ * Jonas G. Drange <jonas.drange@canonical.com>
1228+ *
1229+ */
1230+
1231+#include <QDebug>
1232+#include <QQmlEngine>
1233+
1234+#include "displays.h"
1235+
1236+Displays::Displays(QObject *parent) :
1237+ QObject(parent),
1238+ m_displaysModel(this),
1239+ m_mirDisplays(this) {
1240+
1241+ if (m_mirDisplays.isConnected()) {
1242+ updateAvailableMirDisplays();
1243+
1244+ connect(&m_mirDisplays, SIGNAL(configurationChanged()),
1245+ this, SLOT(updateAvailableMirDisplays()));
1246+ }
1247+}
1248+
1249+Displays::~Displays() {}
1250+
1251+QAbstractItemModel * Displays::displays() {
1252+ auto ret = &m_displaysModel;
1253+ QQmlEngine::setObjectOwnership(ret, QQmlEngine::CppOwnership);
1254+ return ret;
1255+}
1256+
1257+void Displays::applyDisplayConfiguration() {
1258+ qWarning() << "apply config";
1259+ MirDisplayConfiguration * conf = m_mirDisplays.getConfiguration();
1260+ for (unsigned int i = 0; i < conf->num_outputs; ++i) {
1261+ MirDisplayOutput output = conf->outputs[i];
1262+ QSharedPointer<Display> display = m_displaysModel.getDisplay(output.output_id);
1263+ conf->outputs[i] = *display->getDisplayOutput();
1264+ }
1265+ qWarning() << "Changed outputs.";
1266+
1267+ m_mirDisplays.applyConfiguration(conf);
1268+}
1269+
1270+void Displays::updateAvailableMirDisplays() {
1271+ MirDisplayConfiguration * conf = m_mirDisplays.getConfiguration();
1272+ for (unsigned int i = 0; i < conf->num_outputs; ++i) {
1273+ MirDisplayOutput output = conf->outputs[i];
1274+ QSharedPointer<Display> display = m_displaysModel.getDisplay(output.output_id);
1275+
1276+ if (display) {
1277+ qWarning() << __PRETTY_FUNCTION__ << "Updating existing display" << i;
1278+ display->setDisplayOutput(&output);
1279+ } else {
1280+ qWarning() << __PRETTY_FUNCTION__ << "Adding new display" << i;
1281+ QSharedPointer<Display> display = QSharedPointer<Display>::create(&output);
1282+ m_displaysModel.addDisplay(display);
1283+ }
1284+ }
1285+}
1286
1287=== added file 'plugins/brightness/displays.h'
1288--- plugins/brightness/displays.h 1970-01-01 00:00:00 +0000
1289+++ plugins/brightness/displays.h 2016-01-03 21:35:16 +0000
1290@@ -0,0 +1,51 @@
1291+/*
1292+ * Copyright (C) 2015 Canonical Ltd
1293+ *
1294+ * This program is free software: you can redistribute it and/or modify
1295+ * it under the terms of the GNU General Public License version 3 as
1296+ * published by the Free Software Foundation.
1297+ *
1298+ * This program is distributed in the hope that it will be useful,
1299+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1300+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1301+ * GNU General Public License for more details.
1302+ *
1303+ * You should have received a copy of the GNU General Public License
1304+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1305+ *
1306+ * Authors:
1307+ * Jonas G. Drange <jonas.drange@canonical.com>
1308+ *
1309+ * A Displays manager class. Currently only suitable for Mir.
1310+ * Note: It is assumed that the model will hold QScreen objects
1311+ * some time in the future, and thus lose it's tight coupling
1312+ * to Mir.
1313+ */
1314+
1315+#ifndef DISPLAYS_H
1316+#define DISPLAYS_H
1317+
1318+#include <QObject>
1319+#include <QDebug>
1320+
1321+#include "mirdisplays.h"
1322+#include "displaymodel.h"
1323+
1324+class Displays : public QObject
1325+{
1326+ Q_OBJECT
1327+public:
1328+ explicit Displays(QObject * parent = 0);
1329+ ~Displays();
1330+ QAbstractItemModel * displays();
1331+ void applyDisplayConfiguration();
1332+
1333+public Q_SLOTS:
1334+ void updateAvailableMirDisplays();
1335+
1336+private:
1337+ DisplayListModel m_displaysModel;
1338+ MirDisplays m_mirDisplays;
1339+};
1340+
1341+#endif // DISPLAYS_H
1342
1343=== added file 'plugins/brightness/mirdisplays.cpp'
1344--- plugins/brightness/mirdisplays.cpp 1970-01-01 00:00:00 +0000
1345+++ plugins/brightness/mirdisplays.cpp 2016-01-03 21:35:16 +0000
1346@@ -0,0 +1,85 @@
1347+/*
1348+ * Copyright (C) 2015 Canonical Ltd
1349+ *
1350+ * This program is free software: you can redistribute it and/or modify
1351+ * it under the terms of the GNU General Public License version 3 as
1352+ * published by the Free Software Foundation.
1353+ *
1354+ * This program is distributed in the hope that it will be useful,
1355+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1356+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1357+ * GNU General Public License for more details.
1358+ *
1359+ * You should have received a copy of the GNU General Public License
1360+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1361+ *
1362+ * Authors:
1363+ * Jonas G. Drange <jonas.drange@canonical.com>
1364+ */
1365+
1366+#include <QDebug>
1367+#include <QQmlEngine>
1368+#include <QGuiApplication>
1369+#include <qpa/qplatformnativeinterface.h>
1370+#include "mirdisplays.h"
1371+
1372+
1373+static void mir_display_change_callback(MirConnection *connection, void *context) {
1374+ qWarning() << "mir_display_change_callback" << context;
1375+ MirDisplayConfiguration *conf = mir_connection_create_display_config(
1376+ connection);
1377+ static_cast<MirDisplays*>(context)->setConfiguration(conf);
1378+
1379+}
1380+
1381+MirDisplays::MirDisplays(QObject *parent) :
1382+ QObject(parent),
1383+ m_mir_connection(nullptr),
1384+ m_configuration(nullptr) {
1385+ connect();
1386+ if (isConnected()) {
1387+ setConfiguration(
1388+ mir_connection_create_display_config(m_mir_connection));
1389+ }
1390+}
1391+
1392+MirDisplays::~MirDisplays() {}
1393+
1394+MirDisplayConfiguration * MirDisplays::getConfiguration() const {
1395+ return m_configuration;
1396+}
1397+
1398+bool MirDisplays::isConnected() {
1399+ return mir_connection_is_valid(m_mir_connection);
1400+}
1401+
1402+void MirDisplays::setConfiguration(MirDisplayConfiguration * conf) {
1403+ m_configuration = conf;
1404+}
1405+
1406+void MirDisplays::applyConfiguration(MirDisplayConfiguration * conf) {
1407+ mir_wait_for(mir_connection_apply_display_config(m_mir_connection, conf));
1408+ qWarning() << "mirdisplays applyConfiguration" << conf;
1409+
1410+ const char *error = "No error";
1411+ error = mir_connection_get_error_message(m_mir_connection);
1412+ qWarning() << "Mir apply configuration error:" << error;
1413+}
1414+
1415+void MirDisplays::connect() {
1416+ qWarning() << "Connecting...";
1417+ m_mir_connection = static_cast<MirConnection*>(
1418+ QGuiApplication::platformNativeInterface()
1419+ ->nativeResourceForIntegration("mirConnection")
1420+ );
1421+ if (m_mir_connection == nullptr || !isConnected()) {
1422+ const char *error = "Unknown error";
1423+ if (m_mir_connection != nullptr)
1424+ error = mir_connection_get_error_message(m_mir_connection);
1425+ qWarning() << error;
1426+ } else {
1427+ qWarning() << "Using mir as display server.";
1428+ mir_connection_set_display_config_change_callback(
1429+ m_mir_connection, mir_display_change_callback, this);
1430+ }
1431+}
1432
1433=== added file 'plugins/brightness/mirdisplays.h'
1434--- plugins/brightness/mirdisplays.h 1970-01-01 00:00:00 +0000
1435+++ plugins/brightness/mirdisplays.h 2016-01-03 21:35:16 +0000
1436@@ -0,0 +1,50 @@
1437+/*
1438+ * Copyright (C) 2015 Canonical Ltd
1439+ *
1440+ * This program is free software: you can redistribute it and/or modify
1441+ * it under the terms of the GNU General Public License version 3 as
1442+ * published by the Free Software Foundation.
1443+ *
1444+ * This program is distributed in the hope that it will be useful,
1445+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1446+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1447+ * GNU General Public License for more details.
1448+ *
1449+ * You should have received a copy of the GNU General Public License
1450+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1451+ *
1452+ * Authors:
1453+ * Jonas G. Drange <jonas.drange@canonical.com>
1454+ *
1455+ * This is a concrete DAO for obtaining the means to view and configure
1456+ * displays (outputs) in Mir.
1457+ */
1458+
1459+#ifndef MIRDISPLAYS_H
1460+#define MIRDISPLAYS_H
1461+
1462+#include <QObject>
1463+#include <QDebug>
1464+#include <mir_toolkit/mir_client_library.h>
1465+
1466+class MirDisplays : public QObject
1467+{
1468+ Q_OBJECT
1469+public:
1470+ explicit MirDisplays(QObject *parent = 0);
1471+ ~MirDisplays();
1472+ MirDisplayConfiguration * getConfiguration() const;
1473+ void setConfiguration(MirDisplayConfiguration * conf);
1474+ void applyConfiguration(MirDisplayConfiguration * conf);
1475+ bool isConnected();
1476+
1477+Q_SIGNALS:
1478+ void configurationChanged() const;
1479+
1480+private:
1481+ void connect();
1482+ MirConnection * m_mir_connection;
1483+ MirDisplayConfiguration * m_configuration;
1484+};
1485+
1486+#endif // MIRDISPLAYS_H
1487
1488=== modified file 'plugins/brightness/plugin.cpp'
1489--- plugins/brightness/plugin.cpp 2014-07-23 13:44:31 +0000
1490+++ plugins/brightness/plugin.cpp 2016-01-03 21:35:16 +0000
1491@@ -22,14 +22,17 @@
1492
1493 #include <QtQml>
1494 #include <QtQml/QQmlContext>
1495+#include "display.h"
1496 #include "brightness.h"
1497
1498-
1499 void BackendPlugin::registerTypes(const char *uri)
1500 {
1501 Q_ASSERT(uri == QLatin1String("Ubuntu.SystemSettings.Brightness"));
1502
1503+ // qRegisterMetaType<Display::OrientationMode>();
1504 qmlRegisterType<Brightness>(uri, 1, 0, "UbuntuBrightnessPanel");
1505+ qmlRegisterType<Display>(uri, 1, 0, "Display");
1506+ qRegisterMetaType<Display*>("Display*");
1507 }
1508
1509 void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
1510
1511=== modified file 'plugins/brightness/plugin/CMakeLists.txt'
1512--- plugins/brightness/plugin/CMakeLists.txt 2014-01-27 13:01:26 +0000
1513+++ plugins/brightness/plugin/CMakeLists.txt 2016-01-03 21:35:16 +0000
1514@@ -1,8 +1,8 @@
1515-include_directories(${CMAKE_CURRENT_BINARY_DIR})
1516+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${Qt5Gui_PRIVATE_INCLUDE_DIRS} ${MIR_INCLUDE_DIRS})
1517
1518 add_definitions(-DQT_NO_KEYWORDS)
1519
1520 add_library(brightness-plugin SHARED brightness-plugin.h brightness-plugin.cpp)
1521 qt5_use_modules(brightness-plugin Core Qml DBus)
1522-target_link_libraries(brightness-plugin SystemSettings)
1523+target_link_libraries(brightness-plugin SystemSettings uss-displays ${Qt5Gui_PRIVATE_LDFLAGS} ${MIR_LDFLAGS})
1524 install(TARGETS brightness-plugin DESTINATION ${PLUGIN_MODULE_DIR})
1525
1526=== modified file 'plugins/brightness/plugin/brightness-plugin.cpp'
1527--- plugins/brightness/plugin/brightness-plugin.cpp 2014-07-23 13:44:31 +0000
1528+++ plugins/brightness/plugin/brightness-plugin.cpp 2016-01-03 21:35:16 +0000
1529@@ -19,12 +19,18 @@
1530 */
1531
1532 #include "brightness-plugin.h"
1533+#include "../mirdisplays.h"
1534
1535 #include <QDebug>
1536 #include <QDBusInterface>
1537 #include <QStringList>
1538 #include <SystemSettings/ItemBase>
1539
1540+#include <libintl.h>
1541+QString _(const char *text){
1542+ return QString::fromUtf8(dgettext(0, text));
1543+}
1544+
1545 using namespace SystemSettings;
1546
1547 class BrightnessItem: public ItemBase
1548@@ -33,8 +39,11 @@
1549
1550 public:
1551 explicit BrightnessItem(const QVariantMap &staticData, QObject *parent = 0);
1552+ void setDisplayName(const QString &name);
1553 void setVisibility(bool visible);
1554
1555+private:
1556+ int getNumberOfDisplays();
1557 };
1558
1559
1560@@ -47,7 +56,30 @@
1561 QDBusConnection::systemBus());
1562
1563 // Hide the plugin if powerd isn't running; it's redundant currentlys
1564- setVisibility(m_powerdIface.isValid());
1565+ //setVisibility(m_powerdIface.isValid());
1566+ setVisibility(true);
1567+
1568+ if (getNumberOfDisplays() == 0) {
1569+ setDisplayName(_("Brightness"));
1570+ } else {
1571+ setDisplayName(_("Brightness & Display"));
1572+ }
1573+}
1574+
1575+int BrightnessItem::getNumberOfDisplays() {
1576+ MirDisplays mirDisplays;
1577+ int outputs = 0;
1578+
1579+ if (mirDisplays.isConnected()) {
1580+ MirDisplayConfiguration *conf = mirDisplays.getConfiguration();
1581+ outputs = conf->num_outputs;
1582+ }
1583+ return outputs;
1584+}
1585+
1586+void BrightnessItem::setDisplayName(const QString &name)
1587+{
1588+ setName(name);
1589 }
1590
1591 void BrightnessItem::setVisibility(bool visible)

Subscribers

People subscribed via source and target branches