Mir

Merge lp:~vanvugt/mir/output-model into lp:mir

Proposed by Daniel van Vugt
Status: Superseded
Proposed branch: lp:~vanvugt/mir/output-model
Merge into: lp:mir
Diff against target: 447 lines (+338/-0)
10 files modified
include/client/mir_toolkit/mir_display_configuration.h (+12/-0)
src/client/display_configuration_api.cpp (+25/-0)
src/client/symbols.map (+1/-0)
src/include/common/mir/edid.h (+144/-0)
src/protobuf/mir_protobuf.proto (+1/-0)
src/server/report/logging/display_configuration_report.cpp (+17/-0)
src/utils/out.c (+4/-0)
tests/acceptance-tests/test_new_display_configuration.cpp (+68/-0)
tests/unit-tests/CMakeLists.txt (+1/-0)
tests/unit-tests/test_edid.cpp (+65/-0)
To merge this branch: bzr merge lp:~vanvugt/mir/output-model
Reviewer Review Type Date Requested Status
Alan Griffiths Abstain
Mir CI Bot continuous-integration Approve
Cemil Azizoglu (community) Approve
Review via email: mp+312238@code.launchpad.net

This proposal has been superseded by a proposal from 2016-12-09.

Commit message

Add a descriptive string for the connected monitor, if available.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3864
https://mir-jenkins.ubuntu.com/job/mir-ci/2299/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/2992
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/3057
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/3049
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/3049
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/3049
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3021/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3021
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3021/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/2299/rebuild

review: Approve (continuous-integration)
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3865
https://mir-jenkins.ubuntu.com/job/mir-ci/2300/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/2993
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/3058
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/3050
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/3050
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/3050
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3022/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3022/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3022/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3022/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3022/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3022
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3022/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/2300/rebuild

review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Hmm, I might have gone overboard with the fallback logic. That's needed apparently on laptops and tablets which don't provide a nice "monitor name". There's a risk though that the fallback vendor and product codes are just confusing to people. Although they're useful to me as someone who likes to modify/fix laptop screens, that's not a user-friendly activity.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Looks good other than the typo ('nul' instead of 'null')

+ * \returns A nul-terminated string or NULL if none available. This string

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

That's not a typo. "nul" refers to character '\0' to distinguish it from "NULL" which is a pointer.

  https://en.wikipedia.org/wiki/Null_character

Although Google suggests the industry has changed in recent years and often likes to spell it as "null" these days. I don't mind too much either way but "nul" with a single L is historically the more accurate term when referring to character zero.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Mild "needs fixing" for the magic numbers (in particular there's a relationship between 13 and 14 that ought to be explicit).

review: Needs Fixing
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

> That's not a typo. "nul" refers to character '\0' to distinguish it from
> "NULL" which is a pointer.
>
> https://en.wikipedia.org/wiki/Null_character
>
> Although Google suggests the industry has changed in recent years and often
> likes to spell it as "null" these days. I don't mind too much either way but
> "nul" with a single L is historically the more accurate term when referring to
> character zero.

Didn't know that. Thanks.

Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

FAILED: Continuous integration, rev:3868
https://mir-jenkins.ubuntu.com/job/mir-ci/2341/
Executed test runs:
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-mir/3055/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/3121
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/3113
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/3113
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/3113
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3084
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3084/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3084
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3084/artifact/output/*zip*/output.zip
    FAILURE: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3084/console
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3084
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3084/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3084
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3084/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3084
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3084/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/2341/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:3869
https://mir-jenkins.ubuntu.com/job/mir-ci/2345/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/3059
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/3125
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/3117
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/3117
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=yakkety/3117
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=yakkety/3088/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/3088/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=yakkety/3088/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/3088/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/3088/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3088
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/3088/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/2345/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

54 and 4 are still "magic"

review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/client/mir_toolkit/mir_display_configuration.h'
2--- include/client/mir_toolkit/mir_display_configuration.h 2016-12-08 04:08:06 +0000
3+++ include/client/mir_toolkit/mir_display_configuration.h 2016-12-09 06:37:22 +0000
4@@ -373,6 +373,18 @@
5 void mir_output_disable(MirOutput* output);
6
7 /**
8+ * Get a descriptive manufacturer/model string for the connected display.
9+ * The format of this string is arbitrary and driver-specific but should be
10+ * human-readable and helpful for someone to identify which physical display
11+ * this is. Note this function is not called get_name because that would imply
12+ * the returned value is different for each output, whereas it may not be.
13+ *
14+ * \returns A nul-terminated string or NULL if none available. This string
15+ * remains valid for the lifetime of the MirOutput object.
16+ */
17+char const* mir_output_get_model(MirOutput const* output);
18+
19+/**
20 * Get the physical width of the connected display, in millimetres.
21 *
22 * A best-effort report of the physical width of the display connected to this
23
24=== modified file 'src/client/display_configuration_api.cpp'
25--- src/client/display_configuration_api.cpp 2016-12-08 04:08:06 +0000
26+++ src/client/display_configuration_api.cpp 2016-12-09 06:37:22 +0000
27@@ -21,6 +21,7 @@
28 #include "mir/output_type_names.h"
29 #include "display_configuration.h"
30 #include "mir/uncaught.h"
31+#include "mir/edid.h"
32
33 namespace mcl = mir::client;
34 namespace mp = mir::protobuf;
35@@ -86,6 +87,30 @@
36 output->set_used(0);
37 }
38
39+char const* mir_output_get_model(MirOutput const* output)
40+{
41+ // In future this might be provided by the server itself...
42+ if (output->has_model())
43+ return output->model().c_str();
44+
45+ // But if not we use the same member for caching our EDID probe...
46+ using mir::EDID;
47+ if (mir_output_get_edid_size(output) >= EDID::minimum_size)
48+ {
49+ auto edid = reinterpret_cast<EDID const*>(mir_output_get_edid(output));
50+ EDID::MonitorName name;
51+ if (!edid->get_monitor_name(name))
52+ {
53+ auto len = edid->get_manufacturer(name);
54+ snprintf(name+len, sizeof(name)-len, " %hu", edid->product_code());
55+ }
56+ const_cast<MirOutput*>(output)->set_model(name);
57+ return output->model().c_str();
58+ }
59+
60+ return nullptr;
61+}
62+
63 int mir_display_config_get_max_simultaneous_outputs(MirDisplayConfig const* config)
64 {
65 return config->display_card(0).max_simultaneous_outputs();
66
67=== modified file 'src/client/symbols.map'
68--- src/client/symbols.map 2016-12-08 04:08:06 +0000
69+++ src/client/symbols.map 2016-12-09 06:37:22 +0000
70@@ -502,4 +502,5 @@
71 mir_touchpad_configuration_set_middle_mouse_button_emulation;
72 mir_touchpad_configuration_set_scroll_modes;
73 mir_touchpad_configuration_set_tap_to_click;
74+ mir_output_get_model;
75 } MIR_CLIENT_0.25;
76
77=== added file 'src/include/common/mir/edid.h'
78--- src/include/common/mir/edid.h 1970-01-01 00:00:00 +0000
79+++ src/include/common/mir/edid.h 2016-12-09 06:37:22 +0000
80@@ -0,0 +1,144 @@
81+/*
82+ * Copyright © 2016 Canonical Ltd.
83+ *
84+ * This program is free software: you can redistribute it and/or modify it
85+ * under the terms of the GNU Lesser General Public License version 3,
86+ * as published by the Free Software Foundation.
87+ *
88+ * This program is distributed in the hope that it will be useful,
89+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
90+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
91+ * GNU Lesser General Public License for more details.
92+ *
93+ * You should have received a copy of the GNU Lesser General Public License
94+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
95+ *
96+ * Authored by: Daniel van Vugt <daniel.van.vugt@canonical.com>
97+ */
98+
99+#ifndef MIR_EDID_H_
100+#define MIR_EDID_H_
101+
102+#include <endian.h>
103+#include <cstdint>
104+#include <cstring>
105+
106+namespace mir
107+{
108+
109+struct EDID
110+{
111+ EDID() = delete;
112+ EDID(EDID const&) = delete;
113+ EDID(EDID const&&) = delete;
114+
115+ enum { minimum_size = 128 };
116+ typedef char MonitorName[14]; // up to 13 characters
117+ typedef char Manufacturer[4]; // always 3 characters
118+
119+ size_t get_monitor_name(MonitorName str) const
120+ {
121+ size_t len = get_string(string_monitor_name, str);
122+ if (char* pad = strchr(str, '\n'))
123+ {
124+ *pad = '\0';
125+ len = pad - str;
126+ }
127+ return len;
128+ }
129+
130+ size_t get_manufacturer(Manufacturer str) const
131+ {
132+ // Confusingly this field is more like big endian. Others are little.
133+ auto man = static_cast<uint16_t>(manufacturer[0]) << 8 | manufacturer[1];
134+ str[0] = ((man >> 10) & 31) + 'A' - 1;
135+ str[1] = ((man >> 5) & 31) + 'A' - 1;
136+ str[2] = (man & 31) + 'A' - 1;
137+ str[3] = '\0';
138+ return 3;
139+ }
140+
141+ uint16_t product_code() const
142+ {
143+ return le16toh(product_code_le);
144+ }
145+
146+private:
147+ /* Pretty much every field in an EDID requires some kind of conversion
148+ and reinterpretation. So keep those details private... */
149+
150+ enum StringDescriptorType
151+ {
152+ string_monitor_serial_number = 0xff,
153+ string_unspecified_text = 0xfe,
154+ string_monitor_name = 0xfc,
155+ };
156+
157+ size_t get_string(StringDescriptorType type, char str[14]) const
158+ {
159+ size_t len = 0;
160+ for (int d = 0; d < 4; ++d)
161+ {
162+ auto& desc = descriptor[d];
163+ if (!desc.other.zero0 && desc.other.type == type)
164+ {
165+ len = sizeof desc.other.text;
166+ memcpy(str, desc.other.text, len);
167+ break;
168+ }
169+ }
170+ str[len] = '\0';
171+ return len;
172+ }
173+
174+ union Descriptor
175+ {
176+ struct
177+ {
178+ uint16_t pixel_clock_le;
179+ uint8_t todo[16];
180+ } detailed_timing;
181+ struct
182+ {
183+ uint16_t zero0;
184+ uint8_t zero2;
185+ uint8_t type;
186+ uint8_t zero4;
187+ uint8_t text[13];
188+ } other;
189+ };
190+
191+ /* 0x00 */ uint8_t header[8];
192+ /* 0x08 */ uint8_t manufacturer[2];
193+ /* 0x0a */ uint16_t product_code_le;
194+ /* 0x0c */ uint32_t serial_number_le;
195+ /* 0x10 */ uint8_t week_of_manufacture;
196+ /* 0x11 */ uint8_t year_of_manufacture;
197+ /* 0x12 */ uint8_t edid_version;
198+ /* 0x13 */ uint8_t edid_revision;
199+ /* 0x14 */ uint8_t input_bitmap;
200+ /* 0x15 */ uint8_t max_horz_cm;
201+ /* 0x16 */ uint8_t max_vert_cm;
202+ /* 0x17 */ uint8_t gamma;
203+ /* 0x18 */ uint8_t features_bitmap;
204+ /* 0x19 */ uint8_t red_green_bits_1to0;
205+ /* 0x1a */ uint8_t blue_white_bits_1to0;
206+ /* 0x1b */ uint8_t red_x_bits_9to2;
207+ /* 0x1c */ uint8_t red_y_bits_9to2;
208+ /* 0x1d */ uint8_t green_x_bits_9to2;
209+ /* 0x1e */ uint8_t green_y_bits_9to2;
210+ /* 0x1f */ uint8_t blue_x_bits_9to2;
211+ /* 0x20 */ uint8_t blue_y_bits_9to2;
212+ /* 0x21 */ uint8_t white_x_bits_9to2;
213+ /* 0x22 */ uint8_t white_y_bits_9to2;
214+ /* 0x23 */ uint8_t established_timings[2];
215+ /* 0x25 */ uint8_t reserved_timings;
216+ /* 0x26 */ uint8_t standard_timings[2][8];
217+ /* 0x36 */ Descriptor descriptor[4];
218+ /* 0x7e */ uint8_t num_extensions; /* each is another 128-byte block */
219+ /* 0x7f */ uint8_t checksum;
220+};
221+
222+} // namespace mir
223+
224+#endif // MIR_EDID_H_
225
226=== modified file 'src/protobuf/mir_protobuf.proto'
227--- src/protobuf/mir_protobuf.proto 2016-12-08 04:08:06 +0000
228+++ src/protobuf/mir_protobuf.proto 2016-12-09 06:37:22 +0000
229@@ -241,6 +241,7 @@
230 optional bytes gamma_blue = 22;
231 optional uint32 gamma_supported = 23;
232 optional bytes edid = 24;
233+ optional string model = 25;
234 }
235
236 message Connection {
237
238=== modified file 'src/server/report/logging/display_configuration_report.cpp'
239--- src/server/report/logging/display_configuration_report.cpp 2016-11-30 03:00:24 +0000
240+++ src/server/report/logging/display_configuration_report.cpp 2016-12-09 06:37:22 +0000
241@@ -20,6 +20,7 @@
242 #include "mir/graphics/display_configuration.h"
243 #include "mir/output_type_names.h"
244 #include "mir/logging/logger.h"
245+#include "mir/edid.h"
246
247 #include <boost/exception/diagnostic_information.hpp>
248 #include <cmath>
249@@ -93,6 +94,22 @@
250 );
251 if (out.connected)
252 {
253+ using mir::EDID;
254+ if (out.edid.size() >= EDID::minimum_size)
255+ {
256+ auto edid = reinterpret_cast<EDID const*>(out.edid.data());
257+ EDID::MonitorName name;
258+ if (edid->get_monitor_name(name))
259+ logger->log(component, severity,
260+ "%sEDID monitor name: %s", indent, name);
261+ EDID::Manufacturer man;
262+ edid->get_manufacturer(man);
263+ logger->log(component, severity,
264+ "%sEDID manufacturer: %s", indent, man);
265+ logger->log(component, severity,
266+ "%sEDID product code: %hu", indent, edid->product_code());
267+ }
268+
269 int width_mm = out.physical_size_mm.width.as_int();
270 int height_mm = out.physical_size_mm.height.as_int();
271 float inches =
272
273=== modified file 'src/utils/out.c'
274--- src/utils/out.c 2016-12-08 04:08:06 +0000
275+++ src/utils/out.c 2016-12-09 06:37:22 +0000
276@@ -426,6 +426,10 @@
277
278 if (state == mir_output_connection_state_connected)
279 {
280+ char const* model = mir_output_get_model(out);
281+ if (model)
282+ printf(", \"%s\"", model);
283+
284 MirOutputMode const* current_mode =
285 mir_output_get_current_mode(out);
286 if (current_mode)
287
288=== modified file 'tests/acceptance-tests/test_new_display_configuration.cpp'
289--- tests/acceptance-tests/test_new_display_configuration.cpp 2016-12-08 04:08:06 +0000
290+++ tests/acceptance-tests/test_new_display_configuration.cpp 2016-12-09 06:37:22 +0000
291@@ -1085,6 +1085,74 @@
292 client.disconnect();
293 }
294
295+TEST_F(DisplayConfigurationTest, client_receives_model_string_from_edid)
296+{
297+ static unsigned char const edid[129] =
298+ "\x00\xff\xff\xff\xff\xff\xff\x00\x10\xac\x46\xf0\x4c\x4a\x31\x41"
299+ "\x05\x19\x01\x04\xb5\x34\x20\x78\x3a\x1d\xf5\xae\x4f\x35\xb3\x25"
300+ "\x0d\x50\x54\xa5\x4b\x00\x81\x80\xa9\x40\xd1\x00\x71\x4f\x01\x01"
301+ "\x01\x01\x01\x01\x01\x01\x28\x3c\x80\xa0\x70\xb0\x23\x40\x30\x20"
302+ "\x36\x00\x06\x44\x21\x00\x00\x1a\x00\x00\x00\xff\x00\x59\x43\x4d"
303+ "\x30\x46\x35\x31\x52\x41\x31\x4a\x4c\x0a\x00\x00\x00\xfc\x00\x44"
304+ "\x45\x4c\x4c\x20\x55\x32\x34\x31\x33\x0a\x20\x20\x00\x00\x00\xfd"
305+ "\x00\x38\x4c\x1e\x51\x11\x00\x0a\x20\x20\x20\x20\x20\x20\x01\x42";
306+
307+ mtd::StubDisplayConfigurationOutput monitor{
308+ mg::DisplayConfigurationOutputId{48},
309+ {{{1920, 1200}, 60.0}},
310+ {mir_pixel_format_abgr_8888}};
311+ monitor.edid.assign(edid, edid+128);
312+
313+ auto config = std::make_shared<mtd::StubDisplayConfig>(
314+ std::vector<mg::DisplayConfigurationOutput>{monitor});
315+
316+ apply_config_change_and_wait_for_propagation(config);
317+
318+ DisplayClient client{new_connection()};
319+ client.connect();
320+
321+ auto base_config = client.get_base_config();
322+ auto output = mir_display_config_get_output(base_config.get(), 0);
323+
324+ EXPECT_STREQ("DELL U2413", mir_output_get_model(output));
325+
326+ client.disconnect();
327+}
328+
329+TEST_F(DisplayConfigurationTest, client_receives_fallback_string_from_edid)
330+{
331+ static unsigned char const edid[129] =
332+ "\x00\xff\xff\xff\xff\xff\xff\x00\x10\xac\x46\xf0\x4c\x4a\x31\x41"
333+ "\x05\x19\x01\x04\xb5\x34\x20\x78\x3a\x1d\xf5\xae\x4f\x35\xb3\x25"
334+ "\x0d\x50\x54\xa5\x4b\x00\x81\x80\xa9\x40\xd1\x00\x71\x4f\x01\x01"
335+ "\x01\x01\x01\x01\x01\x01\x28\x3c\x80\xa0\x70\xb0\x23\x40\x30\x20"
336+ "\x36\x00\x06\x44\x21\x00\x00\x1a\x00\x00\x00\xff\x00\x59\x43\x4d"
337+ "\x30\x46\x35\x31\x52\x41\x31\x4a\x4c\x0a\x00\x00\x00\x11\x00\x44"
338+ "\x45\x4c\x4c\x20\x55\x32\x34\x31\x33\x0a\x20\x20\x00\x00\x00\xfd"
339+ "\x00\x38\x4c\x1e\x51\x11\x00\x0a\x20\x20\x20\x20\x20\x20\x01\x42";
340+
341+ mtd::StubDisplayConfigurationOutput monitor{
342+ mg::DisplayConfigurationOutputId{2},
343+ {{{3210, 2800}, 60.0}},
344+ {mir_pixel_format_abgr_8888}};
345+ monitor.edid.assign(edid, edid+128);
346+
347+ auto config = std::make_shared<mtd::StubDisplayConfig>(
348+ std::vector<mg::DisplayConfigurationOutput>{monitor});
349+
350+ apply_config_change_and_wait_for_propagation(config);
351+
352+ DisplayClient client{new_connection()};
353+ client.connect();
354+
355+ auto base_config = client.get_base_config();
356+ auto output = mir_display_config_get_output(base_config.get(), 0);
357+
358+ EXPECT_STREQ("DEL 61510", mir_output_get_model(output));
359+
360+ client.disconnect();
361+}
362+
363 namespace
364 {
365 MATCHER_P(IsSameModeAs, mode, "")
366
367=== modified file 'tests/unit-tests/CMakeLists.txt'
368--- tests/unit-tests/CMakeLists.txt 2016-11-15 23:48:01 +0000
369+++ tests/unit-tests/CMakeLists.txt 2016-12-09 06:37:22 +0000
370@@ -82,6 +82,7 @@
371 test_posix_rw_mutex.cpp
372 test_posix_timestamp.cpp
373 test_observer_multiplexer.cpp
374+ test_edid.cpp
375 )
376
377 CMAKE_DEPENDENT_OPTION(
378
379=== added file 'tests/unit-tests/test_edid.cpp'
380--- tests/unit-tests/test_edid.cpp 1970-01-01 00:00:00 +0000
381+++ tests/unit-tests/test_edid.cpp 2016-12-09 06:37:22 +0000
382@@ -0,0 +1,65 @@
383+/*
384+ * Copyright © 2016 Canonical Ltd.
385+ *
386+ * This program is free software: you can redistribute it and/or modify it
387+ * under the terms of the GNU General Public License version 3,
388+ * as published by the Free Software Foundation.
389+ *
390+ * This program is distributed in the hope that it will be useful,
391+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
392+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
393+ * GNU General Public License for more details.
394+ *
395+ * You should have received a copy of the GNU General Public License
396+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
397+ *
398+ * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
399+ */
400+
401+#include "mir/edid.h"
402+#include <gtest/gtest.h>
403+
404+using mir::EDID;
405+
406+namespace
407+{
408+unsigned char const dell_u2413_edid[129] =
409+ "\x00\xff\xff\xff\xff\xff\xff\x00\x10\xac\x46\xf0\x4c\x4a\x31\x41"
410+ "\x05\x19\x01\x04\xb5\x34\x20\x78\x3a\x1d\xf5\xae\x4f\x35\xb3\x25"
411+ "\x0d\x50\x54\xa5\x4b\x00\x81\x80\xa9\x40\xd1\x00\x71\x4f\x01\x01"
412+ "\x01\x01\x01\x01\x01\x01\x28\x3c\x80\xa0\x70\xb0\x23\x40\x30\x20"
413+ "\x36\x00\x06\x44\x21\x00\x00\x1a\x00\x00\x00\xff\x00\x59\x43\x4d"
414+ "\x30\x46\x35\x31\x52\x41\x31\x4a\x4c\x0a\x00\x00\x00\xfc\x00\x44"
415+ "\x45\x4c\x4c\x20\x55\x32\x34\x31\x33\x0a\x20\x20\x00\x00\x00\xfd"
416+ "\x00\x38\x4c\x1e\x51\x11\x00\x0a\x20\x20\x20\x20\x20\x20\x01\x42";
417+} // namespace
418+
419+TEST(EDID, has_correct_size)
420+{
421+ EXPECT_EQ(128u, sizeof(EDID));
422+ EXPECT_EQ(128u, EDID::minimum_size);
423+}
424+
425+TEST(EDID, can_get_name)
426+{
427+ auto edid = reinterpret_cast<EDID const*>(dell_u2413_edid);
428+ EDID::MonitorName name;
429+ int len = edid->get_monitor_name(name);
430+ EXPECT_EQ(10, len);
431+ EXPECT_STREQ("DELL U2413", name);
432+}
433+
434+TEST(EDID, can_get_manufacturer)
435+{
436+ auto edid = reinterpret_cast<EDID const*>(dell_u2413_edid);
437+ EDID::Manufacturer man;
438+ int len = edid->get_manufacturer(man);
439+ EXPECT_EQ(3, len);
440+ EXPECT_STREQ("DEL", man);
441+}
442+
443+TEST(EDID, can_get_product_code)
444+{
445+ auto edid = reinterpret_cast<EDID const*>(dell_u2413_edid);
446+ EXPECT_EQ(61510u, edid->product_code());
447+}

Subscribers

People subscribed via source and target branches