Merge lp:~vanvugt/mir/output-model into lp:mir
- output-model
- Merge into development-branch
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alan Griffiths | Abstain | ||
Mir CI Bot | continuous-integration | Approve | |
Cemil Azizoglu (community) | Approve | ||
Review via email:
|
This proposal has been superseded by a proposal from 2016-12-09.
Commit message
Add a descriptive string for the connected monitor, if available.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mir CI Bot (mir-ci-bot) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3865
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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:/
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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).
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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:/
>
> 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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mir CI Bot (mir-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:3868
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel van Vugt (vanvugt) wrote : | # |
^^^
Bug 1616312
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Mir CI Bot (mir-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:3869
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Alan Griffiths (alan-griffiths) wrote : | # |
54 and 4 are still "magic"
Preview Diff
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 | +} |
PASSED: Continuous integration, rev:3864 /mir-jenkins. ubuntu. com/job/ mir-ci/ 2299/ /mir-jenkins. ubuntu. com/job/ build-mir/ 2992 /mir-jenkins. ubuntu. com/job/ build-0- fetch/3057 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 3049 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 3049 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= yakkety/ 3049 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= yakkety/ 3021 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= yakkety/ 3021/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 3021 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 3021/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= yakkety/ 3021 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= yakkety/ 3021/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 3021 /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 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 3021 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 3021/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 3021 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 3021/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 2299/rebuild
https:/