Mir

Merge lp:~afrantzis/mir/bring-back-r631-fixed into lp:~mir-team/mir/trunk

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Alexandros Frantzis
Approved revision: no longer in the source branch.
Merged at revision: 938
Proposed branch: lp:~afrantzis/mir/bring-back-r631-fixed
Merge into: lp:~mir-team/mir/trunk
Diff against target: 2095 lines (+897/-209)
43 files modified
include/client/mir_toolkit/mir_client_library.h (+11/-0)
include/platform/mir/graphics/display_configuration.h (+5/-0)
include/server/mir/frontend/event_sink.h (+5/-0)
include/shared/mir_toolkit/client_types.h (+9/-0)
include/test/mir_test/display_config_matchers.h (+83/-28)
include/test/mir_test_doubles/null_event_sink.h (+1/-0)
include/test/mir_test_doubles/stub_display_configuration.h (+95/-0)
src/client/connection_configuration.h (+2/-0)
src/client/default_connection_configuration.cpp (+11/-1)
src/client/default_connection_configuration.h (+2/-0)
src/client/display_configuration.cpp (+95/-29)
src/client/display_configuration.h (+32/-2)
src/client/mir_client_library.cpp (+9/-2)
src/client/mir_connection.cpp (+8/-5)
src/client/mir_connection.h (+5/-0)
src/client/rpc/make_rpc_channel.h (+2/-0)
src/client/rpc/make_socket_rpc_channel.cpp (+2/-1)
src/client/rpc/mir_socket_rpc_channel.cpp (+11/-2)
src/client/rpc/mir_socket_rpc_channel.h (+3/-0)
src/server/frontend/event_sender.cpp (+31/-10)
src/server/frontend/event_sender.h (+7/-0)
src/server/frontend/protobuf_buffer_packer.cpp (+30/-0)
src/server/frontend/protobuf_buffer_packer.h (+6/-0)
src/server/frontend/session_mediator.cpp (+2/-24)
src/server/graphics/android/android_display.cpp (+2/-1)
src/server/graphics/gbm/real_kms_display_configuration.cpp (+5/-2)
src/shared/protobuf/mir_protobuf.proto (+6/-4)
tests/integration-tests/test_display_info.cpp (+194/-51)
tests/mir_test_doubles/test_protobuf_client.cpp (+5/-1)
tests/mir_test_framework/testing_server_options.cpp (+2/-1)
tests/unit-tests/client/CMakeLists.txt (+1/-0)
tests/unit-tests/client/test_client_display_conf.cpp (+78/-0)
tests/unit-tests/client/test_mir_connection.cpp (+6/-0)
tests/unit-tests/frontend/CMakeLists.txt (+1/-0)
tests/unit-tests/frontend/stress_protobuf_communicator.cpp (+5/-1)
tests/unit-tests/frontend/test_event_sender.cpp (+68/-0)
tests/unit-tests/frontend/test_session_mediator.cpp (+7/-28)
tests/unit-tests/frontend/test_session_mediator_gbm.cpp (+3/-7)
tests/unit-tests/graphics/gbm/test_gbm_cursor.cpp (+5/-1)
tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp (+18/-4)
tests/unit-tests/graphics/gbm/test_overlapping_output_grouping.cpp (+3/-1)
tests/unit-tests/graphics/test_default_display_configuration_policy.cpp (+16/-2)
tests/unit-tests/graphics/test_display_configuration.cpp (+5/-1)
To merge this branch: bzr merge lp:~afrantzis/mir/bring-back-r631-fixed
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+178933@code.launchpad.net

Commit message

Bring back revision 931 with a fix for the crash it caused (LP: #1209053).

Description of the change

Bring back revision 931 with a fix for the crash it caused (LP: #1209053).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

LGTM

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

looks good to me...
apologies for getting the pixel format for the display wrong in the backed out revision

review: Approve

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_client_library.h'
2--- include/client/mir_toolkit/mir_client_library.h 2013-08-07 03:08:54 +0000
3+++ include/client/mir_toolkit/mir_client_library.h 2013-08-07 10:32:28 +0000
4@@ -109,6 +109,17 @@
5 MirDisplayConfiguration* mir_connection_create_display_config(MirConnection *connection);
6
7 /**
8+ * Register a callback to be called when the DisplayConfiguration changes. Once a change has occurred,
9+ * you can use mir_connection_create_display_config to see the new configuration
10+ * \param [in] connection The connection
11+ * \param [in] callback The function to be called when a display change occurs
12+ * \param [in,out] context User data passed to the callback function
13+ */
14+void mir_connection_set_display_config_change_callback(
15+ MirConnection* connection,
16+ mir_display_config_callback callback, void* context);
17+
18+/**
19 * Destroy the DisplayConfiguration resource acquired from mir_connection_create_display_config
20 * \param [in] display_configuration The display_configuration information resource to be destroyed
21 */
22
23=== modified file 'include/platform/mir/graphics/display_configuration.h'
24--- include/platform/mir/graphics/display_configuration.h 2013-08-07 03:08:54 +0000
25+++ include/platform/mir/graphics/display_configuration.h 2013-08-07 10:32:28 +0000
26@@ -22,6 +22,7 @@
27 #include "mir/int_wrapper.h"
28 #include "mir/geometry/size.h"
29 #include "mir/geometry/point.h"
30+#include "mir/geometry/pixel_format.h"
31
32 #include <functional>
33 #include <vector>
34@@ -61,6 +62,8 @@
35 DisplayConfigurationOutputId id;
36 /** The id of the card the output is connected to. */
37 DisplayConfigurationCardId card_id;
38+ /** The pixel formats supported by the output */
39+ std::vector<geometry::PixelFormat> pixel_formats;
40 /** The modes supported by the output. */
41 std::vector<DisplayConfigurationMode> modes;
42 /** The physical size of the output. */
43@@ -73,6 +76,8 @@
44 geometry::Point top_left;
45 /** The index in the 'modes' vector of the current output mode. */
46 size_t current_mode_index;
47+ /** The index in the 'pixel_format' vector of the current output pixel format. */
48+ size_t current_format_index;
49 };
50
51 std::ostream& operator<<(std::ostream& out, DisplayConfigurationMode const& val);
52
53=== modified file 'include/server/mir/frontend/event_sink.h'
54--- include/server/mir/frontend/event_sink.h 2013-08-07 03:08:54 +0000
55+++ include/server/mir/frontend/event_sink.h 2013-08-07 10:32:28 +0000
56@@ -23,6 +23,10 @@
57
58 namespace mir
59 {
60+namespace graphics
61+{
62+class DisplayConfiguration;
63+}
64 namespace frontend
65 {
66 class EventSink
67@@ -31,6 +35,7 @@
68 virtual ~EventSink() = default;
69
70 virtual void handle_event(MirEvent const& e) = 0;
71+ virtual void handle_display_config_change(graphics::DisplayConfiguration const& config) = 0;
72
73 protected:
74 EventSink() = default;
75
76=== modified file 'include/shared/mir_toolkit/client_types.h'
77--- include/shared/mir_toolkit/client_types.h 2013-08-07 03:08:54 +0000
78+++ include/shared/mir_toolkit/client_types.h 2013-08-07 10:32:28 +0000
79@@ -76,6 +76,15 @@
80 MirSurface* surface, MirEvent const* event, void* context);
81
82 /**
83+ * Callback called when a display config change has occurred
84+ * \param [in] connection The connection associated with the display change
85+ * \param [in,out] context The context provided by client
86+ */
87+
88+typedef void (*mir_display_config_callback)(
89+ MirConnection* connection, void* callback);
90+
91+/**
92 * The order of components in a format enum matches the
93 * order of the components as they would be written in an
94 * integer representing a pixel value of that format.
95
96=== modified file 'include/test/mir_test/display_config_matchers.h'
97--- include/test/mir_test/display_config_matchers.h 2013-08-07 03:08:54 +0000
98+++ include/test/mir_test/display_config_matchers.h 2013-08-07 10:32:28 +0000
99@@ -19,15 +19,27 @@
100 #ifndef MIR_TEST_DISPLAY_CONFIG_MATCHERS_H_
101 #define MIR_TEST_DISPLAY_CONFIG_MATCHERS_H_
102
103+#include "mir_protobuf.pb.h"
104+#include "mir_toolkit/client_types.h"
105+#include "mir/geometry/pixel_format.h"
106 #include <gmock/gmock.h>
107
108+//avoid a valgrind complaint by defining printer for this type
109+static void PrintTo(MirDisplayConfiguration const&, ::std::ostream*) __attribute__ ((unused));
110+void PrintTo(MirDisplayConfiguration const&, ::std::ostream*)
111+{
112+}
113+
114 namespace mir
115 {
116 namespace protobuf
117 {
118
119-//avoid a valgrind complaint by defining printer for this type
120 class Connection;
121+static void PrintTo(mir::protobuf::DisplayConfiguration const&, ::std::ostream*) __attribute__ ((unused));
122+void PrintTo(mir::protobuf::DisplayConfiguration const&, ::std::ostream*) {}
123+
124+static void PrintTo(mir::protobuf::Connection const&, ::std::ostream*) __attribute__ ((unused));
125 void PrintTo(mir::protobuf::Connection const&, ::std::ostream*)
126 {
127 }
128@@ -35,7 +47,7 @@
129 }
130 namespace test
131 {
132-MATCHER_P2(ClientTypeConfigMatches, config, formats, "")
133+MATCHER_P(ClientTypeConfigMatches, config, "")
134 {
135 //ASSERT_ doesn't work in MATCHER_P apparently.
136 EXPECT_EQ(config.size(), arg->num_displays);
137@@ -66,14 +78,12 @@
138 EXPECT_FLOAT_EQ(mode.vrefresh_hz, arg_mode.refresh_rate);
139 }
140
141- //TODO: display formats currently is just the formats supported by the allocator. should be
142- // the formats the display can handle, once we have interfaces from mg::Display for that
143- EXPECT_EQ(0u, arg_display.current_output_format);
144- EXPECT_EQ(formats.size(), arg_display.num_output_formats);
145- if (formats.size() != arg_display.num_output_formats) return false;
146- for (j = 0u; j < formats.size(); j++)
147+ EXPECT_EQ(info.current_format_index, arg_display.current_output_format);
148+ EXPECT_EQ(info.pixel_formats.size(), arg_display.num_output_formats);
149+ if (info.pixel_formats.size() != arg_display.num_output_formats) return false;
150+ for (j = 0u; j < info.pixel_formats.size(); j++)
151 {
152- EXPECT_EQ(formats[j], static_cast<mir::geometry::PixelFormat>(arg_display.output_formats[j]));
153+ EXPECT_EQ(info.pixel_formats[j], static_cast<mir::geometry::PixelFormat>(arg_display.output_formats[j]));
154 }
155 }
156 return true;
157@@ -81,8 +91,7 @@
158 return false;
159 }
160
161-
162-MATCHER_P2(ProtobufConfigMatches, config, formats, "")
163+MATCHER_P(ProtobufConfigMatches, config, "")
164 {
165 //ASSERT_ doesn't work in MATCHER_P apparently.
166 EXPECT_EQ(config.size(), arg.display_output_size());
167@@ -92,19 +101,19 @@
168 for (auto const& info : config)
169 {
170 auto& arg_display = arg.display_output(i++);
171- EXPECT_EQ(info->connected, arg_display.connected());
172- EXPECT_EQ(info->used, arg_display.used());
173- EXPECT_EQ(info->id.as_value(), arg_display.output_id());
174- EXPECT_EQ(info->card_id.as_value(), arg_display.card_id());
175- EXPECT_EQ(info->physical_size_mm.width.as_uint32_t(), arg_display.physical_width_mm());
176- EXPECT_EQ(info->physical_size_mm.height.as_uint32_t(), arg_display.physical_height_mm());
177- EXPECT_EQ(static_cast<int>(info->top_left.x.as_uint32_t()), arg_display.position_x());
178- EXPECT_EQ(static_cast<int>(info->top_left.y.as_uint32_t()), arg_display.position_y());
179- EXPECT_EQ(info->current_mode_index, arg_display.current_mode());
180- EXPECT_EQ(info->modes.size(), arg_display.mode_size());
181- if (info->modes.size() != static_cast<unsigned int>(arg_display.mode_size())) return false;
182+ EXPECT_EQ(info.connected, arg_display.connected());
183+ EXPECT_EQ(info.used, arg_display.used());
184+ EXPECT_EQ(info.id.as_value(), arg_display.output_id());
185+ EXPECT_EQ(info.card_id.as_value(), arg_display.card_id());
186+ EXPECT_EQ(info.physical_size_mm.width.as_uint32_t(), arg_display.physical_width_mm());
187+ EXPECT_EQ(info.physical_size_mm.height.as_uint32_t(), arg_display.physical_height_mm());
188+ EXPECT_EQ(static_cast<int>(info.top_left.x.as_uint32_t()), arg_display.position_x());
189+ EXPECT_EQ(static_cast<int>(info.top_left.y.as_uint32_t()), arg_display.position_y());
190+ EXPECT_EQ(info.current_mode_index, arg_display.current_mode());
191+ EXPECT_EQ(info.modes.size(), arg_display.mode_size());
192+ if (info.modes.size() != static_cast<unsigned int>(arg_display.mode_size())) return false;
193 auto j = 0u;
194- for (auto const& mode : info->modes)
195+ for (auto const& mode : info.modes)
196 {
197 auto& arg_mode = arg_display.mode(j++);
198 EXPECT_EQ(mode.size.width.as_uint32_t(), arg_mode.horizontal_resolution());
199@@ -112,18 +121,64 @@
200 EXPECT_FLOAT_EQ(mode.vrefresh_hz, arg_mode.refresh_rate());
201 }
202
203- EXPECT_EQ(0u, arg_display.current_format());
204- EXPECT_EQ(formats.size(), arg_display.pixel_format_size());
205- if (formats.size() != static_cast<unsigned int>(arg_display.pixel_format_size())) return false;
206- for (j=0u; j<formats.size(); j++)
207+ EXPECT_EQ(info.current_format_index, arg_display.current_format());
208+ EXPECT_EQ(info.pixel_formats.size(), arg_display.pixel_format_size());
209+ if (info.pixel_formats.size() != static_cast<unsigned int>(arg_display.pixel_format_size())) return false;
210+ for ( j = 0u; j < info.pixel_formats.size(); j++)
211 {
212- EXPECT_EQ(formats[j], static_cast<mir::geometry::PixelFormat>(arg_display.pixel_format(j)));
213+ EXPECT_EQ(info.pixel_formats[j], static_cast<mir::geometry::PixelFormat>(arg_display.pixel_format(j)));
214 }
215 }
216 return true;;
217 }
218 return false;
219 }
220+
221+MATCHER_P(ClientTypeMatchesProtobuf, config, "")
222+{
223+ //ASSERT_ doesn't work in MATCHER_P apparently.
224+ EXPECT_EQ(config.display_output_size(), arg.num_displays);
225+ if (config.display_output_size() == static_cast<int>(arg.num_displays))
226+ {
227+ for (auto i = 0u; i < arg.num_displays; i++)
228+ {
229+ auto& conf_display = config.display_output(i);
230+ auto& arg_display = arg.displays[i];
231+ EXPECT_EQ(conf_display.connected(), arg_display.connected);
232+ EXPECT_EQ(conf_display.used(), arg_display.used);
233+ EXPECT_EQ(conf_display.output_id(), arg_display.output_id);
234+ EXPECT_EQ(conf_display.card_id(), arg_display.card_id);
235+ EXPECT_EQ(conf_display.physical_width_mm(), arg_display.physical_width_mm);
236+ EXPECT_EQ(conf_display.physical_height_mm(), arg_display.physical_height_mm);
237+ EXPECT_EQ(conf_display.position_x(), arg_display.position_x);
238+ EXPECT_EQ(conf_display.position_y(), arg_display.position_y);
239+
240+ EXPECT_EQ(conf_display.current_mode(), arg_display.current_mode);
241+ EXPECT_EQ(conf_display.mode_size(), arg_display.num_modes);
242+ if (conf_display.mode_size() != static_cast<int>(arg_display.num_modes)) return false;
243+ for (auto j = 0u; j < arg_display.num_modes; j++)
244+ {
245+ auto const& conf_mode = conf_display.mode(j);
246+ auto const& arg_mode = arg_display.modes[j];
247+ EXPECT_EQ(conf_mode.horizontal_resolution(), arg_mode.horizontal_resolution);
248+ EXPECT_EQ(conf_mode.vertical_resolution(), arg_mode.vertical_resolution);
249+ EXPECT_FLOAT_EQ(conf_mode.refresh_rate(), arg_mode.refresh_rate);
250+ }
251+
252+ EXPECT_EQ(conf_display.current_format(), arg_display.current_output_format);
253+ EXPECT_EQ(conf_display.pixel_format_size(), arg_display.num_output_formats);
254+ if (conf_display.pixel_format_size() != static_cast<int>(arg_display.num_output_formats)) return false;
255+ for (auto j = 0u; j < arg_display.num_output_formats; j++)
256+ {
257+ EXPECT_EQ(conf_display.pixel_format(j), arg_display.output_formats[j]);
258+ }
259+ }
260+ return true;
261+ }
262+ return false;
263+}
264+
265+
266 }
267 }
268 #endif /* MIR_TEST_DISPLAY_CONFIG_MATCHERS_H_ */
269
270=== modified file 'include/test/mir_test_doubles/null_event_sink.h'
271--- include/test/mir_test_doubles/null_event_sink.h 2013-08-07 03:08:54 +0000
272+++ include/test/mir_test_doubles/null_event_sink.h 2013-08-07 10:32:28 +0000
273@@ -29,6 +29,7 @@
274 struct NullEventSink : public frontend::EventSink
275 {
276 void handle_event(MirEvent const&) {}
277+ void handle_display_config_change(graphics::DisplayConfiguration const&) {}
278 };
279 }
280 }
281
282=== added file 'include/test/mir_test_doubles/stub_display_configuration.h'
283--- include/test/mir_test_doubles/stub_display_configuration.h 1970-01-01 00:00:00 +0000
284+++ include/test/mir_test_doubles/stub_display_configuration.h 2013-08-07 10:32:28 +0000
285@@ -0,0 +1,95 @@
286+/*
287+ * Copyright © 2013 Canonical Ltd.
288+ *
289+ * This program is free software: you can redistribute it and/or modify it
290+ * under the terms of the GNU General Public License version 3,
291+ * as published by the Free Software Foundation.
292+ *
293+ * This program is distributed in the hope that it will be useful,
294+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
295+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
296+ * GNU General Public License for more details.
297+ *
298+ * You should have received a copy of the GNU General Public License
299+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
300+ *
301+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
302+ */
303+
304+#ifndef MIR_TEST_DOUBLES_STUB_DISPLAY_CONFIGURATION_H_
305+#define MIR_TEST_DOUBLES_STUB_DISPLAY_CONFIGURATION_H_
306+#include "mir/graphics/display_configuration.h"
307+#include <vector>
308+
309+namespace mir
310+{
311+namespace test
312+{
313+namespace doubles
314+{
315+
316+class StubDisplayConfig : public graphics::DisplayConfiguration
317+{
318+public:
319+ StubDisplayConfig()
320+ {
321+ /* construct a non-trivial dummy display config to send */
322+ int mode_index = 0;
323+ for (auto i = 0u; i < 3u; i++)
324+ {
325+ std::vector<graphics::DisplayConfigurationMode> modes;
326+ std::vector<geometry::PixelFormat> pfs{
327+ geometry::PixelFormat::bgr_888,
328+ geometry::PixelFormat::abgr_8888,
329+ geometry::PixelFormat::xbgr_8888};
330+
331+ for (auto j = 0u; j <= i; j++)
332+ {
333+ geometry::Size sz{mode_index*4, mode_index*3};
334+ graphics::DisplayConfigurationMode mode{sz, 10.0f * mode_index };
335+ mode_index++;
336+ modes.push_back(mode);
337+ }
338+
339+ size_t mode_index = modes.size() - 1;
340+ geometry::Size physical_size{};
341+ geometry::Point top_left{};
342+ graphics::DisplayConfigurationOutput output{
343+ graphics::DisplayConfigurationOutputId{static_cast<int>(i)},
344+ graphics::DisplayConfigurationCardId{static_cast<int>(i)},
345+ pfs, modes,
346+ physical_size,
347+ ((i % 2) == 0),
348+ ((i % 2) == 1),
349+ top_left,
350+ mode_index, 1u
351+ };
352+
353+ outputs.push_back(output);
354+ }
355+ };
356+
357+ void for_each_card(std::function<void(graphics::DisplayConfigurationCard const&)>) const
358+ {
359+ }
360+
361+ void for_each_output(std::function<void(graphics::DisplayConfigurationOutput const&)> f) const
362+ {
363+ for (auto& disp : outputs)
364+ {
365+ f(disp);
366+ }
367+ }
368+
369+ void configure_output(graphics::DisplayConfigurationOutputId, bool, geometry::Point, size_t)
370+ {
371+ }
372+
373+ std::vector<graphics::DisplayConfigurationOutput> outputs;
374+};
375+
376+}
377+}
378+}
379+
380+#endif /* MIR_TEST_DOUBLES_STUB_DISPLAY_CONFIGURATION_H_ */
381
382=== modified file 'src/client/connection_configuration.h'
383--- src/client/connection_configuration.h 2013-08-07 03:08:54 +0000
384+++ src/client/connection_configuration.h 2013-08-07 10:32:28 +0000
385@@ -48,6 +48,7 @@
386 class SurfaceMap;
387 class Logger;
388 class ClientPlatformFactory;
389+class DisplayConfiguration;
390
391 class ConnectionConfiguration
392 {
393@@ -59,6 +60,7 @@
394 virtual std::shared_ptr<mir::logging::Logger> the_logger() = 0;
395 virtual std::shared_ptr<ClientPlatformFactory> the_client_platform_factory() = 0;
396 virtual std::shared_ptr<input::receiver::InputPlatform> the_input_platform() = 0;
397+ virtual std::shared_ptr<DisplayConfiguration> the_display_configuration() = 0;
398
399 protected:
400 ConnectionConfiguration() = default;
401
402=== modified file 'src/client/default_connection_configuration.cpp'
403--- src/client/default_connection_configuration.cpp 2013-08-07 03:08:54 +0000
404+++ src/client/default_connection_configuration.cpp 2013-08-07 10:32:28 +0000
405@@ -18,6 +18,7 @@
406
407 #include "default_connection_configuration.h"
408
409+#include "display_configuration.h"
410 #include "rpc/make_rpc_channel.h"
411 #include "rpc/null_rpc_report.h"
412 #include "mir/logging/dumb_console_logger.h"
413@@ -58,7 +59,7 @@
414 [this]
415 {
416 return mcl::rpc::make_rpc_channel(
417- the_socket_file(), the_surface_map(), the_rpc_report());
418+ the_socket_file(), the_surface_map(), the_display_configuration(), the_rpc_report());
419 });
420 }
421
422@@ -115,3 +116,12 @@
423 return std::make_shared<mcl::rpc::NullRpcReport>();
424 });
425 }
426+
427+std::shared_ptr<mcl::DisplayConfiguration> mcl::DefaultConnectionConfiguration::the_display_configuration()
428+{
429+ return display_configuration(
430+ []
431+ {
432+ return std::make_shared<mcl::DisplayConfiguration>();
433+ });
434+}
435
436=== modified file 'src/client/default_connection_configuration.h'
437--- src/client/default_connection_configuration.h 2013-08-07 03:08:54 +0000
438+++ src/client/default_connection_configuration.h 2013-08-07 10:32:28 +0000
439@@ -45,6 +45,7 @@
440 std::shared_ptr<mir::logging::Logger> the_logger();
441 std::shared_ptr<ClientPlatformFactory> the_client_platform_factory();
442 std::shared_ptr<input::receiver::InputPlatform> the_input_platform();
443+ std::shared_ptr<DisplayConfiguration> the_display_configuration();
444
445 virtual std::string the_socket_file();
446 virtual std::shared_ptr<rpc::RpcReport> the_rpc_report();
447@@ -55,6 +56,7 @@
448 CachedPtr<ClientPlatformFactory> client_platform_factory;
449 CachedPtr<input::receiver::InputPlatform> input_platform;
450 CachedPtr<SurfaceMap> surface_map;
451+ CachedPtr<DisplayConfiguration> display_configuration;
452
453 CachedPtr<rpc::RpcReport> rpc_report;
454
455
456=== modified file 'src/client/display_configuration.cpp'
457--- src/client/display_configuration.cpp 2013-08-07 03:08:54 +0000
458+++ src/client/display_configuration.cpp 2013-08-07 10:32:28 +0000
459@@ -31,14 +31,29 @@
460 for(auto i=0u; i< config->num_displays; i++)
461 {
462 if (config->displays[i].modes)
463- ::operator delete(config->displays[i].modes);
464+ delete[] config->displays[i].modes;
465 if (config->displays[i].output_formats)
466- ::operator delete(config->displays[i].output_formats);
467+ delete[] config->displays[i].output_formats;
468 }
469 if (config->displays)
470- ::operator delete(config->displays);
471-
472- ::operator delete(config);
473+ delete[] config->displays;
474+
475+ delete config;
476+}
477+
478+mcl::DisplayOutput::DisplayOutput(size_t num_modes_, size_t num_formats)
479+{
480+ num_modes = num_modes_;
481+ modes = new MirDisplayMode[num_modes];
482+
483+ num_output_formats = num_formats;
484+ output_formats = new MirPixelFormat[num_formats];
485+}
486+
487+mcl::DisplayOutput::~DisplayOutput()
488+{
489+ delete[] modes;
490+ delete[] output_formats;
491 }
492
493 namespace
494@@ -48,7 +63,7 @@
495 output.card_id = msg.card_id();
496 output.output_id = msg.output_id();
497
498- for(auto i=0u; i < output.num_modes; i++)
499+ for (auto i = 0u; i < output.num_modes; i++)
500 {
501 auto mode = msg.mode(i);
502 output.modes[i].horizontal_resolution = mode.horizontal_resolution();
503@@ -57,7 +72,7 @@
504 }
505 output.current_mode = msg.current_mode();
506
507- for(auto i=0u; i < output.num_output_formats; i++)
508+ for (auto i = 0u; i < output.num_output_formats; i++)
509 {
510 output.output_formats[i] = static_cast<MirPixelFormat>(msg.pixel_format(i));
511 }
512@@ -70,26 +85,77 @@
513 output.physical_width_mm = msg.physical_width_mm();
514 output.physical_height_mm = msg.physical_height_mm();
515 }
516-}
517-
518-MirDisplayConfiguration* mcl::set_display_config_from_message(mp::Connection const& connection_msg)
519-{
520- auto config = static_cast<MirDisplayConfiguration*>(::operator new(sizeof(MirDisplayConfiguration)));
521- config->num_displays = connection_msg.display_output_size();
522- config->displays = static_cast<MirDisplayOutput*>(::operator new(sizeof(MirDisplayOutput) * config->num_displays));
523-
524- for(auto i=0u; i < config->num_displays; i++)
525- {
526- auto output = connection_msg.display_output(i);
527- config->displays[i].num_output_formats = output.pixel_format_size();
528- config->displays[i].output_formats = static_cast<MirPixelFormat*>(
529- ::operator new(sizeof(MirPixelFormat)*config->displays[i].num_output_formats));
530-
531- config->displays[i].num_modes = output.mode_size();
532- config->displays[i].modes = static_cast<MirDisplayMode*>(
533- ::operator new(sizeof(MirDisplayMode)*config->displays[i].num_modes));
534-
535- fill_display_output(config->displays[i], output);
536- }
537- return config;
538+
539+}
540+
541+
542+mcl::DisplayConfiguration::DisplayConfiguration()
543+ : notify_change([]{})
544+{
545+}
546+
547+mcl::DisplayConfiguration::~DisplayConfiguration()
548+{
549+}
550+
551+void mcl::DisplayConfiguration::update_configuration(mp::Connection const& connection_msg)
552+{
553+ std::unique_lock<std::mutex> lk(guard);
554+ outputs.clear();
555+ for (auto i = 0; i < connection_msg.display_output_size(); i++)
556+ {
557+ auto const& msg_output = connection_msg.display_output(i);
558+ auto output = std::make_shared<mcl::DisplayOutput>(msg_output.mode_size(), msg_output.pixel_format_size());
559+ fill_display_output(*output, msg_output);
560+ outputs.push_back(output);
561+ }
562+}
563+
564+void mcl::DisplayConfiguration::update_configuration(mp::DisplayConfiguration const& msg)
565+{
566+ {
567+ std::unique_lock<std::mutex> lk(guard);
568+ outputs.clear();
569+ for (auto i = 0; i < msg.display_output_size(); i++)
570+ {
571+ auto const& msg_output = msg.display_output(i);
572+ auto output = std::make_shared<mcl::DisplayOutput>(msg_output.mode_size(), msg_output.pixel_format_size());
573+ fill_display_output(*output, msg_output);
574+ outputs.push_back(output);
575+ }
576+ }
577+
578+ notify_change();
579+}
580+
581+//user is responsible for freeing the returned value
582+MirDisplayConfiguration* mcl::DisplayConfiguration::copy_to_client() const
583+{
584+ std::unique_lock<std::mutex> lk(guard);
585+ auto new_config = new MirDisplayConfiguration;
586+ new_config->num_displays = outputs.size();
587+ new_config->displays = new MirDisplayOutput[new_config->num_displays];
588+
589+ auto i=0u;
590+ for (auto const& out : outputs)
591+ {
592+ auto new_info = &new_config->displays[i++];
593+ MirDisplayOutput* output = out.get();
594+ std::memcpy(new_info, output, sizeof(MirDisplayOutput));
595+
596+ new_info->output_formats = new MirPixelFormat[new_info->num_output_formats];
597+ auto format_size = sizeof(MirPixelFormat) * new_info->num_output_formats;
598+ std::memcpy(new_info->output_formats, output->output_formats, format_size);
599+
600+ new_info->modes = new MirDisplayMode[new_info->num_modes];
601+ auto mode_size = sizeof(MirDisplayMode)* new_info->num_modes;
602+ std::memcpy(new_info->modes, output->modes, mode_size);
603+ }
604+ return new_config;
605+}
606+
607+void mcl::DisplayConfiguration::set_display_change_handler(std::function<void()> const& fn)
608+{
609+ std::unique_lock<std::mutex> lk(guard);
610+ notify_change = fn;
611 }
612
613=== modified file 'src/client/display_configuration.h'
614--- src/client/display_configuration.h 2013-08-07 03:08:54 +0000
615+++ src/client/display_configuration.h 2013-08-07 10:32:28 +0000
616@@ -22,14 +22,44 @@
617 #include "mir_toolkit/client_types.h"
618 #include "mir_protobuf.pb.h"
619
620+#include <mutex>
621+#include <functional>
622+#include <vector>
623+#include <memory>
624+
625 namespace mir
626 {
627 namespace client
628 {
629+class DisplayOutput : public MirDisplayOutput
630+{
631+public:
632+ DisplayOutput(size_t num_modes_, size_t num_formats);
633+ ~DisplayOutput();
634+};
635
636-//convenient helpers
637+//convenient helper
638 void delete_config_storage(MirDisplayConfiguration* config);
639-MirDisplayConfiguration* set_display_config_from_message(mir::protobuf::Connection const& connection_msg);
640+
641+class DisplayConfiguration
642+{
643+public:
644+ DisplayConfiguration();
645+ ~DisplayConfiguration();
646+
647+ void update_configuration(mir::protobuf::Connection const& msg);
648+ void update_configuration(mir::protobuf::DisplayConfiguration const& msg);
649+ void set_display_change_handler(std::function<void()> const&);
650+
651+ //copying to a c POD, so kinda kludgy
652+ MirDisplayConfiguration* copy_to_client() const;
653+
654+private:
655+ std::mutex mutable guard;
656+ std::vector<std::shared_ptr<DisplayOutput>> outputs;
657+ std::function<void()> notify_change;
658+};
659+
660
661 }
662 }
663
664=== modified file 'src/client/mir_client_library.cpp'
665--- src/client/mir_client_library.cpp 2013-08-07 03:08:54 +0000
666+++ src/client/mir_client_library.cpp 2013-08-07 10:32:28 +0000
667@@ -239,7 +239,7 @@
668
669 MirDisplayConfiguration* mir_connection_create_display_config(MirConnection *connection)
670 {
671- if (connection)
672+ if (connection)
673 return connection->create_copy_of_display_config();
674 return nullptr;
675 }
676@@ -397,10 +397,17 @@
677 return surf ? surf->attrib(mir_surface_attrib_swapinterval) : -1;
678 }
679
680+void mir_connection_set_display_config_change_callback(MirConnection* connection,
681+ mir_display_config_callback callback, void* context)
682+{
683+ if (connection)
684+ connection->register_display_change_callback(callback, context);
685+}
686+
687 MirWaitHandle* mir_connection_apply_display_config(MirConnection *connection, MirDisplayConfiguration* display_configuration)
688 {
689 if (!connection)
690 return NULL;
691
692- return connection->configure_display(display_configuration);
693+ return connection->configure_display(display_configuration);
694 }
695
696=== modified file 'src/client/mir_connection.cpp'
697--- src/client/mir_connection.cpp 2013-08-07 03:08:54 +0000
698+++ src/client/mir_connection.cpp 2013-08-07 10:32:28 +0000
699@@ -49,6 +49,7 @@
700 logger(conf.the_logger()),
701 client_platform_factory(conf.the_client_platform_factory()),
702 input_platform(conf.the_input_platform()),
703+ display_configuration(conf.the_display_configuration()),
704 surface_map(conf.the_surface_map())
705 {
706 {
707@@ -156,6 +157,7 @@
708 */
709 platform = client_platform_factory->create_client_platform(this);
710 native_display = platform->create_egl_native_display();
711+ display_configuration->update_configuration(connect_result);
712 }
713
714 callback(this, context);
715@@ -275,11 +277,7 @@
716 MirDisplayConfiguration* MirConnection::create_copy_of_display_config()
717 {
718 std::lock_guard<std::recursive_mutex> lock(mutex);
719- if (!connect_result.has_error() && (connect_result.display_output_size() > 0))
720- {
721- return mcl::set_display_config_from_message(connect_result);
722- }
723- return nullptr;
724+ return display_configuration->copy_to_client();
725 }
726
727 void MirConnection::possible_pixel_formats(MirPixelFormat* formats,
728@@ -324,6 +322,11 @@
729 surface_map->insert(id, surface);
730 }
731
732+void MirConnection::register_display_change_callback(mir_display_config_callback callback, void* context)
733+{
734+ display_configuration->set_display_change_handler(std::bind(callback, this, context));
735+}
736+
737 bool MirConnection::validate_user_display_config(MirDisplayConfiguration* config)
738 {
739 std::lock_guard<std::recursive_mutex> lock(mutex);
740
741=== modified file 'src/client/mir_connection.h'
742--- src/client/mir_connection.h 2013-08-07 03:08:54 +0000
743+++ src/client/mir_connection.h 2013-08-07 10:32:28 +0000
744@@ -43,6 +43,7 @@
745 class ConnectionConfiguration;
746 class ClientPlatformFactory;
747 class SurfaceMap;
748+class DisplayConfiguration;
749
750 namespace rpc
751 {
752@@ -98,6 +99,8 @@
753 mir_drm_auth_magic_callback callback,
754 void* context);
755
756+ void register_display_change_callback(mir_display_config_callback callback, void* context);
757+
758 void populate(MirPlatformPackage& platform_package);
759 MirDisplayConfiguration* create_copy_of_display_config();
760 void possible_pixel_formats(MirPixelFormat* formats,
761@@ -144,6 +147,8 @@
762 std::mutex release_wait_handle_guard;
763 std::vector<MirWaitHandle*> release_wait_handles;
764
765+ std::shared_ptr<mir::client::DisplayConfiguration> const display_configuration;
766+
767 std::shared_ptr<mir::client::SurfaceMap> surface_map;
768 static std::mutex connection_guard;
769 static std::unordered_set<MirConnection*> valid_connections;
770
771=== modified file 'src/client/rpc/make_rpc_channel.h'
772--- src/client/rpc/make_rpc_channel.h 2013-08-07 03:08:54 +0000
773+++ src/client/rpc/make_rpc_channel.h 2013-08-07 10:32:28 +0000
774@@ -25,6 +25,7 @@
775 namespace client
776 {
777 class SurfaceMap;
778+class DisplayConfiguration;
779
780 namespace rpc
781 {
782@@ -34,6 +35,7 @@
783 std::shared_ptr<MirBasicRpcChannel>
784 make_rpc_channel(std::string const& name,
785 std::shared_ptr<SurfaceMap> const& map,
786+ std::shared_ptr<DisplayConfiguration> const& disp_conf,
787 std::shared_ptr<RpcReport> const& rpc_report);
788 }
789 }
790
791=== modified file 'src/client/rpc/make_socket_rpc_channel.cpp'
792--- src/client/rpc/make_socket_rpc_channel.cpp 2013-08-07 03:08:54 +0000
793+++ src/client/rpc/make_socket_rpc_channel.cpp 2013-08-07 10:32:28 +0000
794@@ -25,7 +25,8 @@
795 std::shared_ptr<mclr::MirBasicRpcChannel>
796 mclr::make_rpc_channel(std::string const& name,
797 std::shared_ptr<mcl::SurfaceMap> const& map,
798+ std::shared_ptr<mcl::DisplayConfiguration> const& disp_conf,
799 std::shared_ptr<RpcReport> const& rpc_report)
800 {
801- return std::make_shared<MirSocketRpcChannel>(name, map, rpc_report);
802+ return std::make_shared<MirSocketRpcChannel>(name, map, disp_conf, rpc_report);
803 }
804
805=== modified file 'src/client/rpc/mir_socket_rpc_channel.cpp'
806--- src/client/rpc/mir_socket_rpc_channel.cpp 2013-08-07 03:08:54 +0000
807+++ src/client/rpc/mir_socket_rpc_channel.cpp 2013-08-07 10:32:28 +0000
808@@ -22,6 +22,7 @@
809 #include "mir/protobuf/google_protobuf_guard.h"
810 #include "../surface_map.h"
811 #include "../mir_surface.h"
812+#include "../display_configuration.h"
813
814 #include "mir_protobuf.pb.h" // For Buffer frig
815 #include "mir_protobuf_wire.pb.h"
816@@ -45,13 +46,15 @@
817 mclr::MirSocketRpcChannel::MirSocketRpcChannel(
818 std::string const& endpoint,
819 std::shared_ptr<mcl::SurfaceMap> const& surface_map,
820+ std::shared_ptr<DisplayConfiguration> const& disp_config,
821 std::shared_ptr<RpcReport> const& rpc_report) :
822 rpc_report(rpc_report),
823 pending_calls(rpc_report),
824 work(io_service),
825 endpoint(endpoint),
826 socket(io_service),
827- surface_map(surface_map)
828+ surface_map(surface_map),
829+ display_configuration(disp_config)
830 {
831 socket.connect(endpoint);
832
833@@ -319,6 +322,12 @@
834 mir::protobuf::EventSequence seq;
835
836 seq.ParseFromString(event);
837+
838+ if (seq.has_display_configuration())
839+ {
840+ display_configuration->update_configuration(seq.display_configuration());
841+ }
842+
843 int const nevents = seq.event_size();
844 for (int i = 0; i != nevents; ++i)
845 {
846@@ -350,7 +359,7 @@
847 {
848 rpc_report->event_parsing_failed(event);
849 }
850- }
851+ }
852 }
853 }
854
855
856=== modified file 'src/client/rpc/mir_socket_rpc_channel.h'
857--- src/client/rpc/mir_socket_rpc_channel.h 2013-08-07 03:08:54 +0000
858+++ src/client/rpc/mir_socket_rpc_channel.h 2013-08-07 10:32:28 +0000
859@@ -41,6 +41,7 @@
860
861 namespace client
862 {
863+class DisplayConfiguration;
864 class SurfaceMap;
865 namespace rpc
866 {
867@@ -52,6 +53,7 @@
868 public:
869 MirSocketRpcChannel(std::string const& endpoint,
870 std::shared_ptr<SurfaceMap> const& surface_map,
871+ std::shared_ptr<DisplayConfiguration> const& disp_config,
872 std::shared_ptr<RpcReport> const& rpc_report);
873 ~MirSocketRpcChannel();
874
875@@ -84,6 +86,7 @@
876 mir::protobuf::wire::Result read_message_body(const size_t body_size);
877
878 std::shared_ptr<SurfaceMap> surface_map;
879+ std::shared_ptr<DisplayConfiguration> display_configuration;
880 };
881
882 }
883
884=== modified file 'src/server/frontend/event_sender.cpp'
885--- src/server/frontend/event_sender.cpp 2013-08-07 03:08:54 +0000
886+++ src/server/frontend/event_sender.cpp 2013-08-07 10:32:28 +0000
887@@ -17,11 +17,15 @@
888 */
889
890 #include "mir/frontend/client_constants.h"
891+#include "mir/graphics/display_configuration.h"
892 #include "event_sender.h"
893 #include "message_sender.h"
894+#include "protobuf_buffer_packer.h"
895+
896 #include "mir_protobuf_wire.pb.h"
897 #include "mir_protobuf.pb.h"
898
899+namespace mg = mir::graphics;
900 namespace mfd = mir::frontend::detail;
901 namespace mp = mir::protobuf;
902
903@@ -41,15 +45,32 @@
904 mp::Event *ev = seq.add_event();
905 ev->set_raw(&e, sizeof(MirEvent));
906
907- std::string buffer;
908- buffer.reserve(serialization_buffer_size);
909- seq.SerializeToString(&buffer);
910-
911- mir::protobuf::wire::Result result;
912- result.add_events(buffer);
913-
914- result.SerializeToString(&buffer);
915-
916- sender->send(buffer);
917+ send_event_sequence(seq);
918 }
919 }
920+
921+void mfd::EventSender::handle_display_config_change(graphics::DisplayConfiguration const& display_config)
922+{
923+ mp::EventSequence seq;
924+ auto message = seq.mutable_display_configuration();
925+
926+ display_config.for_each_output([&message](mg::DisplayConfigurationOutput const& config)
927+ {
928+ auto disp = message->add_display_output();
929+ mfd::pack_protobuf_display_output(disp, config);
930+ });
931+
932+ send_event_sequence(seq);
933+}
934+
935+void mfd::EventSender::send_event_sequence(mp::EventSequence& seq)
936+{
937+ std::string send_buffer;
938+ send_buffer.reserve(serialization_buffer_size);
939+ seq.SerializeToString(&send_buffer);
940+
941+ mir::protobuf::wire::Result result;
942+ result.add_events(send_buffer);
943+ result.SerializeToString(&send_buffer);
944+ sender->send(send_buffer);
945+}
946
947=== modified file 'src/server/frontend/event_sender.h'
948--- src/server/frontend/event_sender.h 2013-08-07 03:08:54 +0000
949+++ src/server/frontend/event_sender.h 2013-08-07 10:32:28 +0000
950@@ -24,6 +24,10 @@
951
952 namespace mir
953 {
954+namespace protobuf
955+{
956+class EventSequence;
957+}
958 namespace frontend
959 {
960 namespace detail
961@@ -35,8 +39,11 @@
962 public:
963 explicit EventSender(std::shared_ptr<MessageSender> const& socket_sender);
964 void handle_event(MirEvent const& e);
965+ void handle_display_config_change(graphics::DisplayConfiguration const& config);
966
967 private:
968+ void send_event_sequence(protobuf::EventSequence&);
969+
970 std::shared_ptr<MessageSender> const sender;
971 };
972
973
974=== modified file 'src/server/frontend/protobuf_buffer_packer.cpp'
975--- src/server/frontend/protobuf_buffer_packer.cpp 2013-08-07 03:08:54 +0000
976+++ src/server/frontend/protobuf_buffer_packer.cpp 2013-08-07 10:32:28 +0000
977@@ -18,8 +18,38 @@
978
979 #include "protobuf_buffer_packer.h"
980
981+#include "mir/graphics/display_configuration.h"
982+#include "mir_protobuf.pb.h"
983+
984 namespace mfd=mir::frontend::detail;
985
986+void mfd::pack_protobuf_display_output(protobuf::DisplayOutput* output,
987+ graphics::DisplayConfigurationOutput const& config)
988+{
989+ output->set_output_id(config.id.as_value());
990+ output->set_card_id(config.card_id.as_value());
991+ output->set_connected(config.connected);
992+ output->set_used(config.used);
993+ output->set_physical_width_mm(config.physical_size_mm.width.as_uint32_t());
994+ output->set_physical_height_mm(config.physical_size_mm.height.as_uint32_t());
995+ output->set_position_x(config.top_left.x.as_uint32_t());
996+ output->set_position_y(config.top_left.y.as_uint32_t());
997+ for (auto const& mode : config.modes)
998+ {
999+ auto output_mode = output->add_mode();
1000+ output_mode->set_horizontal_resolution(mode.size.width.as_uint32_t());
1001+ output_mode->set_vertical_resolution(mode.size.height.as_uint32_t());
1002+ output_mode->set_refresh_rate(mode.vrefresh_hz);
1003+ }
1004+ output->set_current_mode(config.current_mode_index);
1005+
1006+ for (auto const& pf : config.pixel_formats)
1007+ {
1008+ output->add_pixel_format(static_cast<uint32_t>(pf));
1009+ }
1010+ output->set_current_format(config.current_format_index);
1011+}
1012+
1013 mfd::ProtobufBufferPacker::ProtobufBufferPacker(protobuf::Buffer* response)
1014 : buffer_response(response)
1015 {
1016
1017=== modified file 'src/server/frontend/protobuf_buffer_packer.h'
1018--- src/server/frontend/protobuf_buffer_packer.h 2013-08-07 03:08:54 +0000
1019+++ src/server/frontend/protobuf_buffer_packer.h 2013-08-07 10:32:28 +0000
1020@@ -24,11 +24,17 @@
1021
1022 namespace mir
1023 {
1024+namespace graphics
1025+{
1026+struct DisplayConfigurationOutput;
1027+}
1028 namespace frontend
1029 {
1030 namespace detail
1031 {
1032
1033+void pack_protobuf_display_output(protobuf::DisplayOutput* output, graphics::DisplayConfigurationOutput const&);
1034+
1035 class ProtobufBufferPacker : public graphics::BufferIPCPacker
1036 {
1037 public:
1038
1039=== modified file 'src/server/frontend/session_mediator.cpp'
1040--- src/server/frontend/session_mediator.cpp 2013-08-07 03:08:54 +0000
1041+++ src/server/frontend/session_mediator.cpp 2013-08-07 10:32:28 +0000
1042@@ -98,33 +98,11 @@
1043 platform->add_fd(ipc_fds);
1044
1045 auto display_config = display_changer->active_configuration();
1046- auto supported_pfs = buffer_allocator->supported_pixel_formats();
1047- display_config->for_each_output([&response, &supported_pfs](mg::DisplayConfigurationOutput const& config)
1048+ display_config->for_each_output([&response](mg::DisplayConfigurationOutput const& config)
1049 {
1050 auto output = response->add_display_output();
1051- output->set_output_id(config.id.as_value());
1052- output->set_card_id(config.card_id.as_value());
1053- output->set_connected(config.connected);
1054- output->set_used(config.used);
1055- output->set_physical_width_mm(config.physical_size_mm.width.as_uint32_t());
1056- output->set_physical_height_mm(config.physical_size_mm.height.as_uint32_t());
1057- output->set_position_x(config.top_left.x.as_uint32_t());
1058- output->set_position_y(config.top_left.y.as_uint32_t());
1059- for (auto const& mode : config.modes)
1060- {
1061- auto output_mode = output->add_mode();
1062- output_mode->set_horizontal_resolution(mode.size.width.as_uint32_t());
1063- output_mode->set_vertical_resolution(mode.size.height.as_uint32_t());
1064- output_mode->set_refresh_rate(mode.vrefresh_hz);
1065- }
1066- output->set_current_mode(config.current_mode_index);
1067+ mfd::pack_protobuf_display_output(output, config);
1068
1069- for (auto const& pf : supported_pfs)
1070- {
1071- output->add_pixel_format(static_cast<uint32_t>(pf));
1072- }
1073- //TODO: should set the actual display format from the display, once display lets us at that info
1074- output->set_current_format(0);
1075 });
1076
1077 resource_cache->save_resource(response, ipc_package);
1078
1079=== modified file 'src/server/graphics/android/android_display.cpp'
1080--- src/server/graphics/android/android_display.cpp 2013-08-07 03:08:54 +0000
1081+++ src/server/graphics/android/android_display.cpp 2013-08-07 10:32:28 +0000
1082@@ -56,12 +56,13 @@
1083 AndroidDisplayConfiguration(geom::Size const& display_size)
1084 : configuration{mg::DisplayConfigurationOutputId{0},
1085 mg::DisplayConfigurationCardId{0},
1086+ {geom::PixelFormat::abgr_8888},
1087 {mg::DisplayConfigurationMode{display_size,0.0f}},
1088 geom::Size{0,0},
1089 true,
1090 true,
1091 geom::Point{0,0},
1092- 0}
1093+ 0, 0}
1094 {
1095 }
1096 void for_each_card(std::function<void(mg::DisplayConfigurationCard const&)>) const
1097
1098=== modified file 'src/server/graphics/gbm/real_kms_display_configuration.cpp'
1099--- src/server/graphics/gbm/real_kms_display_configuration.cpp 2013-08-07 03:08:54 +0000
1100+++ src/server/graphics/gbm/real_kms_display_configuration.cpp 2013-08-07 10:32:28 +0000
1101@@ -170,6 +170,9 @@
1102 bool connected{connector.connection == DRM_MODE_CONNECTED};
1103 size_t current_mode_index{std::numeric_limits<size_t>::max()};
1104 std::vector<DisplayConfigurationMode> modes;
1105+ std::vector<geom::PixelFormat> formats {geom::PixelFormat::argb_8888,
1106+ geom::PixelFormat::xrgb_8888};
1107+
1108 drmModeModeInfo current_mode_info = drmModeModeInfo();
1109
1110 /* Get information about the current mode */
1111@@ -201,8 +204,8 @@
1112
1113 if (iter == outputs.end())
1114 {
1115- outputs.push_back({id, card_id, modes, physical_size,
1116- connected, false, geom::Point(), current_mode_index});
1117+ outputs.push_back({id, card_id, formats, modes, physical_size,
1118+ connected, false, geom::Point(), current_mode_index, 0u});
1119 }
1120 else
1121 {
1122
1123=== modified file 'src/shared/protobuf/mir_protobuf.proto'
1124--- src/shared/protobuf/mir_protobuf.proto 2013-08-07 03:08:54 +0000
1125+++ src/shared/protobuf/mir_protobuf.proto 2013-08-07 10:32:28 +0000
1126@@ -144,12 +144,14 @@
1127 optional bytes raw = 1; // MirEvent structure
1128 }
1129
1130+message DisplayConfiguration {
1131+ repeated DisplayOutput display_output = 1;
1132+ optional string error = 127;
1133+}
1134+
1135 message EventSequence {
1136 repeated Event event = 1;
1137-}
1138-
1139-message DisplayConfiguration {
1140- repeated DisplayOutput display_output = 1;
1141+ optional DisplayConfiguration display_configuration = 2;
1142 optional string error = 127;
1143 }
1144
1145
1146=== modified file 'tests/integration-tests/test_display_info.cpp'
1147--- tests/integration-tests/test_display_info.cpp 2013-08-07 03:08:54 +0000
1148+++ tests/integration-tests/test_display_info.cpp 2013-08-07 10:32:28 +0000
1149@@ -17,23 +17,30 @@
1150 */
1151
1152 #include "mir/graphics/display.h"
1153-#include "mir/graphics/display_configuration.h"
1154 #include "mir/graphics/buffer.h"
1155 #include "mir/frontend/session_authorizer.h"
1156 #include "mir/graphics/graphic_buffer_allocator.h"
1157+#include "mir/frontend/protobuf_ipc_factory.h"
1158+#include "mir/frontend/resource_cache.h"
1159+#include "mir/frontend/session_mediator.h"
1160
1161 #include "mir_test_framework/display_server_test_fixture.h"
1162+#include "mir_test_framework/cross_process_sync.h"
1163 #include "mir_test_doubles/stub_buffer.h"
1164 #include "mir_test_doubles/null_display.h"
1165+#include "mir_test_doubles/null_event_sink.h"
1166 #include "mir_test_doubles/null_display_config.h"
1167 #include "mir_test_doubles/null_display_changer.h"
1168 #include "mir_test_doubles/stub_display_buffer.h"
1169 #include "mir_test_doubles/null_platform.h"
1170 #include "mir_test/display_config_matchers.h"
1171+#include "mir_test_doubles/stub_display_configuration.h"
1172 #include "mir_test/fake_shared.h"
1173
1174 #include "mir_toolkit/mir_client_library.h"
1175
1176+#include <condition_variable>
1177+#include <thread>
1178 #include <gmock/gmock.h>
1179 #include <gtest/gtest.h>
1180
1181@@ -48,52 +55,6 @@
1182
1183 namespace
1184 {
1185-class StubDisplayConfig : public mtd::NullDisplayConfig
1186-{
1187-public:
1188- StubDisplayConfig()
1189- {
1190- /* construct a non-trivial dummy display config to send */
1191- int mode_index = 0;
1192- for (auto i = 0u; i < 3u; i++)
1193- {
1194- std::vector<mg::DisplayConfigurationMode> modes;
1195- for (auto j = 0u; j <= i; j++)
1196- {
1197- geom::Size sz{mode_index*4, mode_index*3};
1198- mg::DisplayConfigurationMode mode{sz, 10.0f * mode_index };
1199- mode_index++;
1200- modes.push_back(mode);
1201- }
1202-
1203- size_t mode_index = modes.size() - 1;
1204- geom::Size physical_size{};
1205- geom::Point top_left{};
1206- mg::DisplayConfigurationOutput output{
1207- mg::DisplayConfigurationOutputId{static_cast<int>(i)},
1208- mg::DisplayConfigurationCardId{static_cast<int>(i)},
1209- modes,
1210- physical_size,
1211- ((i % 2) == 0),
1212- ((i % 2) == 1),
1213- top_left,
1214- mode_index
1215- };
1216-
1217- outputs.push_back(output);
1218- }
1219- };
1220-
1221- void for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const override
1222- {
1223- for (auto& disp : outputs)
1224- {
1225- f(disp);
1226- }
1227- }
1228-
1229- std::vector<mg::DisplayConfigurationOutput> outputs;
1230-};
1231
1232 class StubDisplay : public mtd::NullDisplay
1233 {
1234@@ -117,10 +78,13 @@
1235 {
1236 return mt::fake_shared(stub_display_config);
1237 }
1238- static StubDisplayConfig stub_display_config;
1239+
1240+ static mtd::StubDisplayConfig stub_display_config;
1241+private:
1242+ mtd::NullDisplayBuffer display_buffer;
1243 };
1244-StubDisplayConfig StubChanger::stub_display_config;
1245
1246+mtd::StubDisplayConfig StubChanger::stub_display_config;
1247
1248 char const* const mir_test_socket = mtf::test_socket_file().c_str();
1249
1250@@ -209,8 +173,7 @@
1251 auto connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
1252 auto configuration = mir_connection_create_display_config(connection);
1253
1254- EXPECT_THAT(configuration, mt::ClientTypeConfigMatches(StubChanger::stub_display_config.outputs,
1255- StubGraphicBufferAllocator::pixel_formats));
1256+ EXPECT_THAT(configuration, mt::ClientTypeConfigMatches(StubChanger::stub_display_config.outputs));
1257
1258 mir_display_config_destroy(configuration);
1259 mir_connection_release(connection);
1260@@ -327,3 +290,183 @@
1261
1262 launch_client_process(client_config);
1263 }
1264+
1265+
1266+namespace
1267+{
1268+class EventSinkSkimmingIpcFactory : public mf::ProtobufIpcFactory
1269+{
1270+public:
1271+ EventSinkSkimmingIpcFactory(
1272+ std::shared_ptr<mf::Shell> const& shell,
1273+ std::shared_ptr<mf::SessionMediatorReport> const& sm_report,
1274+ std::shared_ptr<mf::MessageProcessorReport> const& mr_report,
1275+ std::shared_ptr<mg::Platform> const& graphics_platform,
1276+ std::shared_ptr<msh::DisplayChanger> const& graphics_changer,
1277+ std::shared_ptr<mg::GraphicBufferAllocator> const& buffer_allocator)
1278+ : shell(shell),
1279+ sm_report(sm_report),
1280+ mp_report(mr_report),
1281+ cache(std::make_shared<mf::ResourceCache>()),
1282+ graphics_platform(graphics_platform),
1283+ graphics_changer(graphics_changer),
1284+ buffer_allocator(buffer_allocator),
1285+ last_event_sink(std::make_shared<mtd::NullEventSink>())
1286+ {
1287+ }
1288+
1289+ std::shared_ptr<mf::EventSink> last_clients_event_sink()
1290+ {
1291+ return std::move(last_event_sink);
1292+ }
1293+
1294+private:
1295+ std::shared_ptr<mf::Shell> shell;
1296+ std::shared_ptr<mf::SessionMediatorReport> const sm_report;
1297+ std::shared_ptr<mf::MessageProcessorReport> const mp_report;
1298+ std::shared_ptr<mf::ResourceCache> const cache;
1299+ std::shared_ptr<mg::Platform> const graphics_platform;
1300+ std::shared_ptr<msh::DisplayChanger> const graphics_changer;
1301+ std::shared_ptr<mg::GraphicBufferAllocator> const buffer_allocator;
1302+ std::shared_ptr<mf::EventSink> last_event_sink;
1303+
1304+ virtual std::shared_ptr<mir::protobuf::DisplayServer> make_ipc_server(
1305+ std::shared_ptr<mf::EventSink> const& sink, bool)
1306+ {
1307+ last_event_sink = sink;
1308+ return std::make_shared<mf::SessionMediator>(
1309+ shell,
1310+ graphics_platform,
1311+ graphics_changer,
1312+ buffer_allocator,
1313+ sm_report,
1314+ sink,
1315+ resource_cache());
1316+ }
1317+
1318+ virtual std::shared_ptr<mf::ResourceCache> resource_cache()
1319+ {
1320+ return cache;
1321+ }
1322+
1323+ virtual std::shared_ptr<mf::MessageProcessorReport> report()
1324+ {
1325+ return mp_report;
1326+ }
1327+
1328+};
1329+
1330+}
1331+
1332+TEST_F(BespokeDisplayServerTestFixture, display_change_notification)
1333+{
1334+ mtf::CrossProcessSync client_ready_fence;
1335+ mtf::CrossProcessSync send_event_fence;
1336+
1337+ struct ServerConfig : TestingServerConfiguration
1338+ {
1339+ ServerConfig(mtf::CrossProcessSync const& send_event_fence)
1340+ : send_event_fence(send_event_fence)
1341+ {
1342+ }
1343+
1344+ std::shared_ptr<mg::Platform> the_graphics_platform() override
1345+ {
1346+ if (!platform)
1347+ platform = std::make_shared<StubPlatform>();
1348+ return platform;
1349+ }
1350+
1351+ std::shared_ptr<mir::frontend::ProtobufIpcFactory> the_ipc_factory(
1352+ std::shared_ptr<mf::Shell> const& shell,
1353+ std::shared_ptr<mg::GraphicBufferAllocator> const& allocator) override
1354+ {
1355+ if (!ipc_factory)
1356+ {
1357+ ipc_factory = std::make_shared<EventSinkSkimmingIpcFactory>(
1358+ shell,
1359+ the_session_mediator_report(),
1360+ the_message_processor_report(),
1361+ the_graphics_platform(),
1362+ the_shell_display_changer(), allocator);
1363+ }
1364+ return ipc_factory;
1365+ }
1366+
1367+ void exec() override
1368+ {
1369+ change_thread = std::move(std::thread([this](){
1370+ send_event_fence.wait_for_signal_ready_for(std::chrono::milliseconds(1000));
1371+ auto notifier = ipc_factory->last_clients_event_sink();
1372+ notifier->handle_display_config_change(StubChanger::stub_display_config);
1373+ }));
1374+ }
1375+
1376+ void on_exit() override
1377+ {
1378+ change_thread.join();
1379+ }
1380+
1381+ mtf::CrossProcessSync send_event_fence;
1382+ std::shared_ptr<EventSinkSkimmingIpcFactory> ipc_factory;
1383+ std::shared_ptr<StubPlatform> platform;
1384+ std::thread change_thread;
1385+ } server_config(send_event_fence);
1386+
1387+ struct Client : TestingClientConfiguration
1388+ {
1389+ Client(mtf::CrossProcessSync const& client_ready_fence)
1390+ : client_ready_fence(client_ready_fence)
1391+ {
1392+ }
1393+
1394+ static void change_handler(MirConnection* connection, void* context)
1395+ {
1396+ auto configuration = mir_connection_create_display_config(connection);
1397+
1398+ EXPECT_THAT(configuration, mt::ClientTypeConfigMatches(StubChanger::stub_display_config.outputs));
1399+ mir_display_config_destroy(configuration);
1400+
1401+ auto client_config = (Client*) context;
1402+ client_config->notify_callback();
1403+ }
1404+
1405+ void notify_callback()
1406+ {
1407+ callback_called = true;
1408+ callback_wait.notify_all();
1409+ }
1410+ void exec()
1411+ {
1412+ std::unique_lock<std::mutex> lk(mut);
1413+ MirConnection* connection = mir_connect_sync(mir_test_socket, "notifier");
1414+ callback_called = false;
1415+
1416+ mir_connection_set_display_config_change_callback(connection, &change_handler, this);
1417+
1418+ client_ready_fence.try_signal_ready_for(std::chrono::milliseconds(1000));
1419+
1420+ while(!callback_called)
1421+ {
1422+ callback_wait.wait(lk);
1423+ }
1424+
1425+ mir_connection_release(connection);
1426+ }
1427+
1428+ mtf::CrossProcessSync client_ready_fence;
1429+
1430+ std::mutex mut;
1431+ std::condition_variable callback_wait;
1432+ bool callback_called;
1433+ } client_config(client_ready_fence);
1434+
1435+ launch_server_process(server_config);
1436+ launch_client_process(client_config);
1437+
1438+ run_in_test_process([&]
1439+ {
1440+ client_ready_fence.wait_for_signal_ready_for(std::chrono::milliseconds(1000));
1441+ send_event_fence.try_signal_ready_for(std::chrono::milliseconds(1000));
1442+ });
1443+}
1444
1445=== modified file 'tests/mir_test_doubles/test_protobuf_client.cpp'
1446--- tests/mir_test_doubles/test_protobuf_client.cpp 2013-08-07 03:08:54 +0000
1447+++ tests/mir_test_doubles/test_protobuf_client.cpp 2013-08-07 10:32:28 +0000
1448@@ -20,6 +20,7 @@
1449 #include "mir_test_doubles/mock_rpc_report.h"
1450
1451 #include "src/client/connection_surface_map.h"
1452+#include "src/client/display_configuration.h"
1453 #include "src/client/rpc/make_rpc_channel.h"
1454 #include "src/client/rpc/mir_basic_rpc_channel.h"
1455
1456@@ -32,7 +33,10 @@
1457 int timeout_ms) :
1458 rpc_report(std::make_shared<testing::NiceMock<doubles::MockRpcReport>>()),
1459 channel(mir::client::rpc::make_rpc_channel(
1460- socket_file,std::make_shared<mir::client::ConnectionSurfaceMap>(),rpc_report)),
1461+ socket_file,
1462+ std::make_shared<mir::client::ConnectionSurfaceMap>(),
1463+ std::make_shared<mir::client::DisplayConfiguration>(),
1464+ rpc_report)),
1465 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
1466 maxwait(timeout_ms),
1467 connect_done_called(false),
1468
1469=== modified file 'tests/mir_test_framework/testing_server_options.cpp'
1470--- tests/mir_test_framework/testing_server_options.cpp 2013-08-07 03:08:54 +0000
1471+++ tests/mir_test_framework/testing_server_options.cpp 2013-08-07 10:32:28 +0000
1472@@ -79,7 +79,8 @@
1473 {
1474 mg::DisplayConfigurationOutput dummy_output_config{
1475 mg::DisplayConfigurationOutputId{0}, mg::DisplayConfigurationCardId{0},
1476- modes, geom::Size{}, true, true, geom::Point{0,0}, 0};
1477+ std::vector<geom::PixelFormat>{geom::PixelFormat::abgr_8888},
1478+ modes, geom::Size{}, true, true, geom::Point{0,0}, 0, 0};
1479
1480 f(dummy_output_config);
1481 }
1482
1483=== modified file 'tests/unit-tests/client/CMakeLists.txt'
1484--- tests/unit-tests/client/CMakeLists.txt 2013-08-07 03:08:54 +0000
1485+++ tests/unit-tests/client/CMakeLists.txt 2013-08-07 10:32:28 +0000
1486@@ -6,6 +6,7 @@
1487 ${CMAKE_CURRENT_SOURCE_DIR}/test_client_mir_surface.cpp
1488 ${CMAKE_CURRENT_SOURCE_DIR}/test_mir_connection.cpp
1489 ${CMAKE_CURRENT_SOURCE_DIR}/test_wait_handle.cpp
1490+ ${CMAKE_CURRENT_SOURCE_DIR}/test_client_display_conf.cpp
1491 )
1492
1493 if(MIR_PLATFORM STREQUAL "android")
1494
1495=== added file 'tests/unit-tests/client/test_client_display_conf.cpp'
1496--- tests/unit-tests/client/test_client_display_conf.cpp 1970-01-01 00:00:00 +0000
1497+++ tests/unit-tests/client/test_client_display_conf.cpp 2013-08-07 10:32:28 +0000
1498@@ -0,0 +1,78 @@
1499+/*
1500+ * Copyright © 2013 Canonical Ltd.
1501+ *
1502+ * This program is free software: you can redistribute it and/or modify
1503+ * it under the terms of the GNU General Public License version 3 as
1504+ * published by the Free Software Foundation.
1505+ *
1506+ * This program is distributed in the hope that it will be useful,
1507+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1508+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1509+ * GNU General Public License for more details.
1510+ *
1511+ * You should have received a copy of the GNU General Public License
1512+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1513+ *
1514+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1515+ */
1516+
1517+#include "src/client/display_configuration.h"
1518+
1519+#include "mir_test/display_config_matchers.h"
1520+#include "gtest/gtest.h"
1521+
1522+namespace mp = mir::protobuf;
1523+namespace mcl = mir::client;
1524+namespace mt = mir::test;
1525+
1526+namespace
1527+{
1528+void fill(mp::DisplayOutput* out)
1529+{
1530+ out->add_pixel_format(4);
1531+ out->set_current_format(45);
1532+ auto mode = out->add_mode();
1533+ mode->set_horizontal_resolution(4);
1534+ mode->set_vertical_resolution(558);
1535+ mode->set_refresh_rate(4.33f);
1536+ out->set_current_mode(0);
1537+ out->set_position_x(5);
1538+ out->set_position_y(6);
1539+ out->set_card_id(7);
1540+ out->set_output_id(8);
1541+ out->set_connected(1);
1542+ out->set_used(1);
1543+ out->set_physical_width_mm(11);
1544+ out->set_physical_height_mm(12);
1545+}
1546+}
1547+
1548+TEST(TestDisplayConfiguration, configuration_storage)
1549+{
1550+ mp::Connection connect_result;
1551+ fill(connect_result.add_display_output());
1552+ fill(connect_result.add_display_output());
1553+
1554+ mcl::DisplayConfiguration internal_config;
1555+
1556+ internal_config.update_configuration(connect_result);
1557+ MirDisplayConfiguration *info;
1558+ info = internal_config.copy_to_client();
1559+
1560+ EXPECT_THAT(*info, mt::ClientTypeMatchesProtobuf(connect_result));
1561+ mcl::delete_config_storage(info);
1562+
1563+ int called_count = 0u;
1564+ internal_config.set_display_change_handler([&]() { called_count++; });
1565+
1566+ mp::DisplayConfiguration new_result;
1567+ fill(new_result.add_display_output());
1568+
1569+ internal_config.update_configuration(new_result);
1570+
1571+ info = internal_config.copy_to_client();
1572+ EXPECT_THAT(*info, mt::ClientTypeMatchesProtobuf(new_result));
1573+ EXPECT_EQ(1u, called_count);
1574+
1575+ mcl::delete_config_storage(info);
1576+}
1577
1578=== modified file 'tests/unit-tests/client/test_mir_connection.cpp'
1579--- tests/unit-tests/client/test_mir_connection.cpp 2013-08-07 03:08:54 +0000
1580+++ tests/unit-tests/client/test_mir_connection.cpp 2013-08-07 10:32:28 +0000
1581@@ -124,6 +124,7 @@
1582 std::shared_ptr<mcl::ClientPlatform> const& platform,
1583 std::shared_ptr<mcl::rpc::MirBasicRpcChannel> const& channel)
1584 : DefaultConnectionConfiguration(""),
1585+ disp_config(std::make_shared<mcl::DisplayConfiguration>()),
1586 platform{platform},
1587 channel{channel}
1588 {
1589@@ -139,7 +140,12 @@
1590 return std::make_shared<StubClientPlatformFactory>(platform);
1591 }
1592
1593+ std::shared_ptr<mcl::DisplayConfiguration> the_display_configuration() override
1594+ {
1595+ return disp_config;
1596+ }
1597 private:
1598+ std::shared_ptr<mcl::DisplayConfiguration> disp_config;
1599 std::shared_ptr<mcl::ClientPlatform> const platform;
1600 std::shared_ptr<mcl::rpc::MirBasicRpcChannel> const channel;
1601 };
1602
1603=== modified file 'tests/unit-tests/frontend/CMakeLists.txt'
1604--- tests/unit-tests/frontend/CMakeLists.txt 2013-08-07 03:08:54 +0000
1605+++ tests/unit-tests/frontend/CMakeLists.txt 2013-08-07 10:32:28 +0000
1606@@ -8,6 +8,7 @@
1607 ${CMAKE_CURRENT_SOURCE_DIR}/test_resource_cache.cpp
1608 ${CMAKE_CURRENT_SOURCE_DIR}/test_session_mediator.cpp
1609 ${CMAKE_CURRENT_SOURCE_DIR}/test_socket_session.cpp
1610+ ${CMAKE_CURRENT_SOURCE_DIR}/test_event_sender.cpp
1611 )
1612
1613 # TODO this test is a mess - something better is needed.
1614
1615=== modified file 'tests/unit-tests/frontend/stress_protobuf_communicator.cpp'
1616--- tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2013-08-07 03:08:54 +0000
1617+++ tests/unit-tests/frontend/stress_protobuf_communicator.cpp 2013-08-07 10:32:28 +0000
1618@@ -26,6 +26,7 @@
1619 #include "mir_test/test_protobuf_server.h"
1620
1621 #include "src/client/connection_surface_map.h"
1622+#include "src/client/display_configuration.h"
1623 #include "src/client/rpc/null_rpc_report.h"
1624 #include "src/client/rpc/make_rpc_channel.h"
1625 #include "src/client/rpc/mir_basic_rpc_channel.h"
1626@@ -172,7 +173,10 @@
1627 int timeout_ms) :
1628 rpc_report(std::make_shared<mir::client::rpc::NullRpcReport>()),
1629 channel(mir::client::rpc::make_rpc_channel(
1630- socket_file, std::make_shared<mir::client::ConnectionSurfaceMap>(), rpc_report)),
1631+ socket_file,
1632+ std::make_shared<mir::client::ConnectionSurfaceMap>(),
1633+ std::make_shared<mir::client::DisplayConfiguration>(),
1634+ rpc_report)),
1635 display_server(channel.get(), ::google::protobuf::Service::STUB_DOESNT_OWN_CHANNEL),
1636 maxwait(timeout_ms),
1637 connect_done_called(false),
1638
1639=== added file 'tests/unit-tests/frontend/test_event_sender.cpp'
1640--- tests/unit-tests/frontend/test_event_sender.cpp 1970-01-01 00:00:00 +0000
1641+++ tests/unit-tests/frontend/test_event_sender.cpp 2013-08-07 10:32:28 +0000
1642@@ -0,0 +1,68 @@
1643+/*
1644+ * Copyright © 2013 Canonical Ltd.
1645+ *
1646+ * This program is free software: you can redistribute it and/or modify
1647+ * it under the terms of the GNU General Public License version 3 as
1648+ * published by the Free Software Foundation.
1649+ *
1650+ * This program is distributed in the hope that it will be useful,
1651+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1652+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1653+ * GNU General Public License for more details.
1654+ *
1655+ * You should have received a copy of the GNU General Public License
1656+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1657+ *
1658+ * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
1659+ */
1660+
1661+#include "src/server/frontend/message_sender.h"
1662+#include "src/server/frontend/event_sender.h"
1663+#include "mir_test_doubles/stub_display_configuration.h"
1664+#include "mir_test/display_config_matchers.h"
1665+#include "mir_test/fake_shared.h"
1666+
1667+#include <vector>
1668+#include "mir_protobuf.pb.h"
1669+#include "mir_protobuf_wire.pb.h"
1670+#include <gtest/gtest.h>
1671+#include <gmock/gmock.h>
1672+
1673+namespace mt=mir::test;
1674+namespace mtd=mir::test::doubles;
1675+namespace mfd=mir::frontend::detail;
1676+namespace geom=mir::geometry;
1677+
1678+namespace
1679+{
1680+struct MockMsgSender : public mfd::MessageSender
1681+{
1682+ MOCK_METHOD1(send, void(std::string const&));
1683+ MOCK_METHOD1(send_fds, void(std::vector<int32_t> const&));
1684+};
1685+}
1686+
1687+TEST(TestEventSender, display_send)
1688+{
1689+ using namespace testing;
1690+
1691+ mtd::StubDisplayConfig config;
1692+ MockMsgSender mock_msg_sender;
1693+
1694+ auto msg_validator = [&config](std::string const& msg){
1695+ mir::protobuf::wire::Result wire;
1696+ wire.ParseFromString(msg);
1697+ std::string str = wire.events(0);
1698+ mir::protobuf::EventSequence seq;
1699+ seq.ParseFromString(str);
1700+ EXPECT_THAT(seq.display_configuration(), mt::ProtobufConfigMatches(config.outputs));
1701+ };
1702+
1703+ EXPECT_CALL(mock_msg_sender, send(_))
1704+ .Times(1)
1705+ .WillOnce(Invoke(msg_validator));
1706+
1707+ mfd::EventSender sender(mt::fake_shared(mock_msg_sender));
1708+
1709+ sender.handle_display_config_change(config);
1710+}
1711
1712=== modified file 'tests/unit-tests/frontend/test_session_mediator.cpp'
1713--- tests/unit-tests/frontend/test_session_mediator.cpp 2013-08-07 03:08:54 +0000
1714+++ tests/unit-tests/frontend/test_session_mediator.cpp 2013-08-07 10:32:28 +0000
1715@@ -30,6 +30,7 @@
1716 #include "mir_test_doubles/mock_display.h"
1717 #include "mir_test_doubles/mock_display_changer.h"
1718 #include "mir_test_doubles/null_display.h"
1719+#include "mir_test_doubles/null_event_sink.h"
1720 #include "mir_test_doubles/null_display_changer.h"
1721 #include "mir_test_doubles/mock_display.h"
1722 #include "mir_test_doubles/mock_shell.h"
1723@@ -37,6 +38,7 @@
1724 #include "mir_test_doubles/mock_buffer.h"
1725 #include "mir_test_doubles/stub_session.h"
1726 #include "mir_test_doubles/stub_surface_builder.h"
1727+#include "mir_test_doubles/stub_display_configuration.h"
1728 #include "mir_test/display_config_matchers.h"
1729 #include "mir_test/fake_shared.h"
1730 #include "mir/frontend/event_sink.h"
1731@@ -160,12 +162,6 @@
1732 std::shared_ptr<mg::Buffer> const&));
1733 };
1734
1735-class NullEventSink : public mir::frontend::EventSink
1736-{
1737-public:
1738- void handle_event(MirEvent const& ) override {}
1739-};
1740-
1741 struct SessionMediatorTest : public ::testing::Test
1742 {
1743 SessionMediatorTest()
1744@@ -177,7 +173,7 @@
1745 resource_cache{std::make_shared<mf::ResourceCache>()},
1746 mediator{shell, graphics_platform, graphics_changer,
1747 buffer_allocator, report,
1748- std::make_shared<NullEventSink>(),
1749+ std::make_shared<mtd::NullEventSink>(),
1750 resource_cache},
1751 stubbed_session{std::make_shared<StubbedSession>()},
1752 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
1753@@ -333,15 +329,8 @@
1754 {
1755 using namespace testing;
1756 geom::Size sz{1022, 2411};
1757-
1758- std::vector<mg::DisplayConfigurationMode> modes{{sz, 344.0f},{sz, 234.0f}};
1759- mg::DisplayConfigurationOutput output{
1760- mg::DisplayConfigurationOutputId{static_cast<int>(3)},
1761- mg::DisplayConfigurationCardId{static_cast<int>(2)},
1762- modes, sz, true, false,
1763- geom::Point{4,12}, 0u};
1764
1765- StubConfig config(mt::fake_shared(output));
1766+ mtd::StubDisplayConfig config;
1767
1768 auto mock_display = std::make_shared<mtd::MockDisplayChanger>();
1769 EXPECT_CALL(*mock_display, active_configuration())
1770@@ -350,7 +339,7 @@
1771 mf::SessionMediator mediator(
1772 shell, graphics_platform, mock_display,
1773 buffer_allocator, report,
1774- std::make_shared<NullEventSink>(),
1775+ std::make_shared<mtd::NullEventSink>(),
1776 resource_cache);
1777
1778 mp::ConnectParameters connect_parameters;
1779@@ -359,19 +348,9 @@
1780 connection.clear_display_info();
1781 connection.clear_display_output();
1782
1783- std::vector<geom::PixelFormat> const pixel_formats{
1784- geom::PixelFormat::bgr_888,
1785- geom::PixelFormat::abgr_8888,
1786- geom::PixelFormat::xbgr_8888
1787- };
1788-
1789- EXPECT_CALL(*buffer_allocator, supported_pixel_formats())
1790- .WillOnce(Return(pixel_formats));
1791-
1792-
1793 mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1794
1795- EXPECT_THAT(connection, mt::ProtobufConfigMatches(config.outputs, pixel_formats));
1796+ EXPECT_THAT(connection, mt::ProtobufConfigMatches(config.outputs));
1797 }
1798
1799 TEST_F(SessionMediatorTest, creating_surface_packs_response_with_input_fds)
1800@@ -511,7 +490,7 @@
1801
1802 mf::SessionMediator session_mediator{
1803 shell, graphics_platform, mock_display_selector,
1804- buffer_allocator, report, std::make_shared<NullEventSink>(), resource_cache};
1805+ buffer_allocator, report, std::make_shared<mtd::NullEventSink>(), resource_cache};
1806
1807 session_mediator.connect(nullptr, &connect_parameters, &connection, null_callback.get());
1808
1809
1810=== modified file 'tests/unit-tests/frontend/test_session_mediator_gbm.cpp'
1811--- tests/unit-tests/frontend/test_session_mediator_gbm.cpp 2013-08-07 03:08:54 +0000
1812+++ tests/unit-tests/frontend/test_session_mediator_gbm.cpp 2013-08-07 10:32:28 +0000
1813@@ -29,6 +29,8 @@
1814 #include <boost/exception/errinfo_errno.hpp>
1815 #include <boost/throw_exception.hpp>
1816
1817+#include "mir_test_doubles/null_display.h"
1818+#include "mir_test_doubles/null_event_sink.h"
1819 #include "mir_test_doubles/null_display_changer.h"
1820 #include "mir_test_doubles/null_platform.h"
1821 #include "mir_test_doubles/mock_session.h"
1822@@ -73,12 +75,6 @@
1823 MOCK_METHOD1(drm_auth_magic, void(drm_magic_t));
1824 };
1825
1826-class NullEventSink : public mir::frontend::EventSink
1827-{
1828-public:
1829- void handle_event(MirEvent const& ) override {}
1830-};
1831-
1832 struct SessionMediatorGBMTest : public ::testing::Test
1833 {
1834 SessionMediatorGBMTest()
1835@@ -90,7 +86,7 @@
1836 resource_cache{std::make_shared<mf::ResourceCache>()},
1837 mediator{shell, mock_platform, display_changer,
1838 buffer_allocator, report,
1839- std::make_shared<NullEventSink>(),
1840+ std::make_shared<mtd::NullEventSink>(),
1841 resource_cache},
1842 null_callback{google::protobuf::NewPermanentCallback(google::protobuf::DoNothing)}
1843 {
1844
1845=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_cursor.cpp'
1846--- tests/unit-tests/graphics/gbm/test_gbm_cursor.cpp 2013-08-07 03:08:54 +0000
1847+++ tests/unit-tests/graphics/gbm/test_gbm_cursor.cpp 2013-08-07 10:32:28 +0000
1848@@ -90,6 +90,7 @@
1849 {
1850 mg::DisplayConfigurationOutputId{10},
1851 card_id,
1852+ {},
1853 {
1854 {geom::Size{10, 20}, 59.9},
1855 {geom::Size{200, 100}, 59.9},
1856@@ -98,12 +99,14 @@
1857 true,
1858 true,
1859 geom::Point{0, 0},
1860- 1
1861+ 1,
1862+ 0
1863 });
1864 outputs.push_back(
1865 {
1866 mg::DisplayConfigurationOutputId{11},
1867 card_id,
1868+ {},
1869 {
1870 {geom::Size{200, 200}, 59.9},
1871 {geom::Size{100, 200}, 59.9},
1872@@ -112,6 +115,7 @@
1873 true,
1874 true,
1875 geom::Point{100, 50},
1876+ 0,
1877 0
1878 });
1879 }
1880
1881=== modified file 'tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp'
1882--- tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-08-07 03:08:54 +0000
1883+++ tests/unit-tests/graphics/gbm/test_gbm_display_configuration.cpp 2013-08-07 10:32:28 +0000
1884@@ -174,31 +174,37 @@
1885 {
1886 mg::DisplayConfigurationOutputId{connector0_id},
1887 mg::DisplayConfigurationCardId{0},
1888+ {},
1889 conf_modes0,
1890 connector0_physical_size_mm,
1891 true,
1892 true,
1893 geom::Point(),
1894- 1
1895+ 1,
1896+ 0
1897 },
1898 {
1899 mg::DisplayConfigurationOutputId{connector1_id},
1900 mg::DisplayConfigurationCardId{0},
1901+ {},
1902 std::vector<mg::DisplayConfigurationMode>(),
1903 connector1_physical_size_mm,
1904 false,
1905 false,
1906 geom::Point(),
1907+ std::numeric_limits<size_t>::max(),
1908 std::numeric_limits<size_t>::max()
1909 },
1910 {
1911 mg::DisplayConfigurationOutputId{connector2_id},
1912 mg::DisplayConfigurationCardId{0},
1913+ {},
1914 std::vector<mg::DisplayConfigurationMode>(),
1915 connector2_physical_size_mm,
1916 false,
1917 false,
1918 geom::Point(),
1919+ std::numeric_limits<size_t>::max(),
1920 std::numeric_limits<size_t>::max()
1921 }
1922 };
1923@@ -323,22 +329,26 @@
1924 {
1925 mg::DisplayConfigurationOutputId(connector_ids[0]),
1926 mg::DisplayConfigurationCardId{0},
1927+ {},
1928 conf_modes0,
1929 connector_physical_sizes_mm_before[0],
1930 true,
1931 true,
1932 geom::Point(),
1933- 1
1934+ 1,
1935+ 0
1936 },
1937 {
1938 mg::DisplayConfigurationOutputId(connector_ids[1]),
1939 mg::DisplayConfigurationCardId{0},
1940+ {},
1941 std::vector<mg::DisplayConfigurationMode>(),
1942 connector_physical_sizes_mm_before[1],
1943 false,
1944 false,
1945 geom::Point(),
1946- std::numeric_limits<size_t>::max()
1947+ std::numeric_limits<size_t>::max(),
1948+ std::numeric_limits<size_t>::max()
1949 },
1950 };
1951
1952@@ -347,22 +357,26 @@
1953 {
1954 mg::DisplayConfigurationOutputId(connector_ids[0]),
1955 mg::DisplayConfigurationCardId{0},
1956+ {},
1957 std::vector<mg::DisplayConfigurationMode>(),
1958 connector_physical_sizes_mm_after[0],
1959 false,
1960 true,
1961 geom::Point(),
1962+ std::numeric_limits<size_t>::max(),
1963 std::numeric_limits<size_t>::max()
1964 },
1965 {
1966 mg::DisplayConfigurationOutputId(connector_ids[1]),
1967 mg::DisplayConfigurationCardId{0},
1968+ {},
1969 conf_modes0,
1970 connector_physical_sizes_mm_after[1],
1971 true,
1972 false,
1973 geom::Point(),
1974- 1
1975+ 1,
1976+ 0
1977 },
1978 };
1979
1980
1981=== modified file 'tests/unit-tests/graphics/gbm/test_overlapping_output_grouping.cpp'
1982--- tests/unit-tests/graphics/gbm/test_overlapping_output_grouping.cpp 2013-08-07 03:08:54 +0000
1983+++ tests/unit-tests/graphics/gbm/test_overlapping_output_grouping.cpp 2013-08-07 10:32:28 +0000
1984@@ -69,12 +69,14 @@
1985 {
1986 mg::DisplayConfigurationOutputId(i),
1987 mg::DisplayConfigurationCardId{1},
1988+ {},
1989 modes,
1990 {100, 100},
1991 connected,
1992 used,
1993 rect.top_left,
1994- i - 1
1995+ i - 1,
1996+ 0
1997 };
1998
1999 f(output);
2000
2001=== modified file 'tests/unit-tests/graphics/test_default_display_configuration_policy.cpp'
2002--- tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-08-07 03:08:54 +0000
2003+++ tests/unit-tests/graphics/test_default_display_configuration_policy.cpp 2013-08-07 10:32:28 +0000
2004@@ -40,6 +40,9 @@
2005 mg::DisplayConfigurationOutputId{10},
2006 card_id,
2007 {
2008+ {geom::PixelFormat::abgr_8888}
2009+ },
2010+ {
2011 {geom::Size{123, 111}, 59.9},
2012 {geom::Size{123, 111}, 59.9},
2013 {geom::Size{123, 111}, 59.9}
2014@@ -48,7 +51,8 @@
2015 true,
2016 false,
2017 geom::Point{geom::X{123}, geom::Y{343}},
2018- 1
2019+ 1,
2020+ 0
2021 });
2022 /* Connected without modes */
2023 outputs.push_back(
2024@@ -56,10 +60,12 @@
2025 mg::DisplayConfigurationOutputId{11},
2026 card_id,
2027 {},
2028+ {},
2029 geom::Size{566, 111},
2030 true,
2031 false,
2032 geom::Point(),
2033+ std::numeric_limits<size_t>::max(),
2034 std::numeric_limits<size_t>::max()
2035 });
2036 /* Connected with a single mode */
2037@@ -68,12 +74,16 @@
2038 mg::DisplayConfigurationOutputId{12},
2039 card_id,
2040 {
2041+ {geom::PixelFormat::abgr_8888}
2042+ },
2043+ {
2044 {geom::Size{523, 555}, 60.0},
2045 },
2046 geom::Size{324, 642},
2047 true,
2048 false,
2049 geom::Point(),
2050+ 0,
2051 0
2052 });
2053 /* Not connected */
2054@@ -81,12 +91,16 @@
2055 {
2056 mg::DisplayConfigurationOutputId{13},
2057 card_id,
2058+ {
2059+ {geom::PixelFormat::abgr_8888}
2060+ },
2061 {},
2062 geom::Size{324, 642},
2063 false,
2064 false,
2065 geom::Point(),
2066- 1
2067+ 1,
2068+ 0
2069 });
2070 }
2071
2072
2073=== modified file 'tests/unit-tests/graphics/test_display_configuration.cpp'
2074--- tests/unit-tests/graphics/test_display_configuration.cpp 2013-08-07 03:08:54 +0000
2075+++ tests/unit-tests/graphics/test_display_configuration.cpp 2013-08-07 10:32:28 +0000
2076@@ -31,6 +31,9 @@
2077 mg::DisplayConfigurationOutputId{3},
2078 mg::DisplayConfigurationCardId{2},
2079 {
2080+ {geom::PixelFormat::abgr_8888}
2081+ },
2082+ {
2083 {geom::Size{10, 20}, 60.0},
2084 {geom::Size{10, 20}, 59.0},
2085 {geom::Size{15, 20}, 59.0}
2086@@ -39,7 +42,8 @@
2087 true,
2088 true,
2089 geom::Point(),
2090- 2
2091+ 2,
2092+ 0
2093 };
2094
2095 }

Subscribers

People subscribed via source and target branches