Merge lp:~alan-griffiths/mir/a-simpler-server-setup into lp:mir
- a-simpler-server-setup
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Alan Griffiths |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1984 |
Proposed branch: | lp:~alan-griffiths/mir/a-simpler-server-setup |
Merge into: | lp:mir |
Diff against target: |
713 lines (+630/-0) 5 files modified
include/server/mir/server.h (+217/-0) server-ABI-sha1sums (+1/-0) src/server/CMakeLists.txt (+1/-0) src/server/server.cpp (+373/-0) src/server/symbols.map (+38/-0) |
To merge this branch: | bzr merge lp:~alan-griffiths/mir/a-simpler-server-setup |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Kevin DuBois (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Alexandros Frantzis (community) | Approve | ||
Cemil Azizoglu (community) | Needs Fixing | ||
Andreas Pokorny (community) | Approve | ||
Review via email: mp+237990@code.launchpad.net |
Commit message
mir: A simpler to use (and easier to maintain) way to customise and run a Mir server
Description of the change
mir: A simpler to use (and easier to maintain) way to customise and run a Mir server
The idea is to provide a declarative API for setting up the server that doesn't tie the client code into DefautServerCon
Functions can be added to mir::Server without breaking backward API as they are non-virtual.
If clients are able to use an interface like this we can move DefaultServerCo
This is extracted from lp:~alan-griffiths/mir/spike-a-simpler-server-setup/+merge/237625 by dropping the experimental changes to examples used as a proof-of-concept.
I'd like to land this and then work through the examples and acceptance tests to ensure they are implementable in terms of this interface. (Doing this as a single MP would be hard to review.)
NOTE: there is an alternative proposal, please consider both approaches when voting:
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1973
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1973
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
Rebuilding (third time lucky?)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1973
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1973
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
65 +
Extra blank line.
219 + bool exit_status{false};
220 + std::weak_
222 + ServerConfigura
Since ABI break protection is a major concern, we should hide all of these in 'Self'.
Nit (non-blocking):
227 +class detail:
As mentioned in the past, I am not fond of this mechanism, but if people find it more convenient...
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1975
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Andreas Pokorny (andreas-pokorny) wrote : | # |
the header checksums contain additional files probably left overs from merges?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1976
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1977
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Oh, a Server class like I've been asking for for almost two years :D
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1979
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
218 + struct ServerConfigura
Do we need this?
513 + self->server_config = nullptr;
Indentation (tab instead of spaces)
523 + std::cerr << "DEBUG: " << __PRETTY_FUNCTION__ << std::endl;
Not needed.
Andreas Pokorny (andreas-pokorny) wrote : | # |
Two more things:
Whats the thought behind writing {*this} instead of just *this?
I think:
523 + std::cerr << "DEBUG: " << __PRETTY_FUNCTION__ << std::endl;
and iostream is not needed anymore?
Alan Griffiths (alan-griffiths) wrote : | # |
> Two more things:
>
> Whats the thought behind writing {*this} instead of just *this?
We're constructing a helper object (which as the constructor isn't tagged explicit could be done the way you suggest).
> I think:
>
> 523 + std::cerr << "DEBUG: " << __PRETTY_FUNCTION__ << std::endl;
Done
> and iostream is not needed anymore?
std::cerr is used: "mir::report_
Andreas Pokorny (andreas-pokorny) wrote : | # |
> > Two more things:
> >
> > Whats the thought behind writing {*this} instead of just *this?
>
> We're constructing a helper object (which as the constructor isn't tagged
> explicit could be done the way you suggest).
ok, my gcc didnt complain about - maybe clang would.
Andreas Pokorny (andreas-pokorny) wrote : | # |
> > > Two more things:
> > >
> > > Whats the thought behind writing {*this} instead of just *this?
> >
> > We're constructing a helper object (which as the constructor isn't tagged
> > explicit could be done the way you suggest).
>
> ok, my gcc didnt complain about - maybe clang would.
misunderstood what you just said. interesting syntax idea to indicate the conversion in the return statement.
Kevin DuBois (kdub) wrote : | # |
So I guess I favor this MP over the alternative, mostly because this one is more straightforward to reason (from a user's perspective) about what is available for use.
In light of the proposed plan, the following is more of a comment; but I'm concerned that we're exposing too much of our internal composition scheduling with the functions that remain exposed. (It would be good for mir's ease-of-use to be able to reuse MultiThreadedCo
nits:
#1
31 +namespace compositor{ class Compositor; }
spacing
#2
148 + /// \return the graphics display options.
151 + /// \return the graphics platform options.
In light of the other mentions of 'options' in this header, we should drop 'options' off the end of these comments
#3
detail:
AdditionalConfi
#4
OptionType::null seems more like OptionType::bool to me.
Alexandros Frantzis (afrantzis) wrote : | # |
> 218 + struct ServerConfigura
> Do we need this?
What I meant was: do we need for this to be a private mir::Server struct instead of a only a struct inside server.cpp ? Doesn't affect ABI either way, but there is no point exposing the type at all either.
208 + void override_
209 +
210 + /// Sets a wrapper functor for creating the session coordinator.
211 + void wrap_session_
Lines are too long and there is too much repetition, so I think the code would benefit from function types for the parameters, e.g.:
template<typename T> using Builder = std::function<
template<typename T> using Wrapper = std::function<
Alan Griffiths (alan-griffiths) wrote : | # |
> #3
> detail:
> AdditionalConfi
> stronger name.
Or I could just drop the chaining functionality this supports.
Any opinions? (I know Alexandros would drop it>)
> #4
> OptionType::null seems more like OptionType::bool to me.
Not so. This is a flag that exists or not, not one that takes [true|false]
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1981
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
> > 218 + struct ServerConfigura
> > Do we need this?
>
> What I meant was: do we need for this to be a private mir::Server struct
> instead of a only a struct inside server.cpp ? Doesn't affect ABI either way,
> but there is no point exposing the type at all either.
It isn't obvious, but either Self needs to be a public type or there needs to be a way of giving ServerConfiguration access to it.
> 208 + void override_
> <scene:
> 209 +
> 210 + /// Sets a wrapper functor for creating the session coordinator.
> 211 + void wrap_session_
> essionCoordinat
> const& wrapper);
>
> Lines are too long and there is too much repetition, so I think the code would
> benefit from function types for the parameters, e.g.:
>
> template<typename T> using Builder = std::function<
> template<typename T> using Wrapper =
> std::function<
This would make the declarations more concise.
But it makes it harder for the user see the type they need to supply as a parameter.
Alan Griffiths (alan-griffiths) wrote : | # |
> nits:
> #1
> 31 +namespace compositor{ class Compositor; }
> spacing
>
> #2
> 148 + /// \return the graphics display options.
> 151 + /// \return the graphics platform options.
> In light of the other mentions of 'options' in this header, we should drop
> 'options' off the end of these comments
fixed
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
1. Should we reserve a buffer zone after accessors, overrides, and wrappers for future expansion? Otherwise we'll likely have interleaved accessors/
2. No tests?
3.
s/hander/handler
111 + /// If set_command_
114 + void set_command_
115 + std::function<
365 + std::function<
439 + std::function<
441 + if (command_
442 + return std::make_
493 + auto const options = configuration_
701 + mir::Server:
4.
s/add/Add
s/an/a
125 + /// add an callback to be invoked when the server has been initialized,
5.
s/set/Set
107 + /// set a handler for any command line options Mir does not recognise.
6.
66 + * These are the commands used to start and stop.
Based on this comment, to be consistent, should 'run' be named 'start'?
71 + /// Run the Mir server until it exits
72 + void run();
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1982
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
> It isn't obvious, but either Self needs to be a public type or there needs to be a
> way of giving ServerConfiguration access to it.
Ah, indeed.
> This would make the declarations more concise.
> But it makes it harder for the user see the type they need to supply as a parameter.
Perhaps the first couple times the user will have to look up the type definition (which isn't hard since it will be in the same code block). But subsequently the user will read, e.g., "WrapperFunctio
Alan Griffiths (alan-griffiths) wrote : | # |
> 1. Should we reserve a buffer zone after accessors, overrides, and wrappers
> for future expansion? Otherwise we'll likely have interleaved
> accessors/
A buffer zone where? These are non-virtual functions.
> 2. No tests?
True. If you can think of an effective way to test that the system gets configured & run correctly then I'd be delighted to add them.
In practice, this will get exercised properly when the acceptance tests get migrated to this interface. (Which is on my TODO list.)
> 3.
> s/hander/handler
> 111 + /// If set_command_
> is to exit by
> 114 + void set_command_
> 115 + std::function<
> command_
> 365 + std::function<
> command_
> 439 + std::function<
> command_
> 441 + if (command_
> 442 + return std::make_
> command_
> 493 + auto const options = configuration_
> self->argv, self->command_
> 701 + mir::Server:
Fixed
> 4.
> s/add/Add
> s/an/a
> 125 + /// add an callback to be invoked when the server has been
> initialized,
Fixed
> 5.
> s/set/Set
> 107 + /// set a handler for any command line options Mir does not
> recognise.
Fixed.
> 6.
> 66 + * These are the commands used to start and stop.
> Based on this comment, to be consistent, should 'run' be named 'start'?
> 71 + /// Run the Mir server until it exits
> 72 + void run();
Alan Griffiths (alan-griffiths) wrote : | # |
> > This would make the declarations more concise.
> > But it makes it harder for the user see the type they need to supply as a
> parameter.
>
> Perhaps the first couple times the user will have to look up the type
> definition (which isn't hard since it will be in the same code block). But
> subsequently the user will read, e.g., "WrapperFunctio
> what's expected, instead of having to mentally reparse the long parameter type
> every time.
The first couple of times are the "barrier to entry" - after that it doesn't matter which way we write them as the user knows what to expect and doesn't read the parameter type.
It is *very* important to make adopting Mir as easy as possible.
Practically, can we land with this spelling and I'll MP your suggestion on top of that for discussion? (It isn't an API/ABI change.)
Alan Griffiths (alan-griffiths) wrote : | # |
> 227 +class detail:
>
> As mentioned in the past, I am not fond of this mechanism, but if people find
> it more convenient...
dropped
Alexandros Frantzis (afrantzis) wrote : | # |
> The first couple of times are the "barrier to entry" - after that it doesn't matter
> which way we write them as the user knows what to expect and doesn't read the parameter type.
We may be consistent, but we should make this explicit and easily discoverable. Users can't really be sure that the signature is the same without re-reading the (long and not easily parsable) parameter type.
> It is *very* important to make adopting Mir as easy as possible.
I doubt that this is a barrier to adoption. If we think that target developers can't bother to find a definition in the same code block they are currently looking at, then we should surely get rid of "detail:
> Practically, can we land with this spelling and I'll MP your suggestion on
No problem.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1983
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1986
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : | # |
okay, looks good to me
Preview Diff
1 | === added file 'include/server/mir/server.h' | |||
2 | --- include/server/mir/server.h 1970-01-01 00:00:00 +0000 | |||
3 | +++ include/server/mir/server.h 2014-10-15 09:19:21 +0000 | |||
4 | @@ -0,0 +1,217 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright © 2014 Canonical Ltd. | ||
7 | 3 | * | ||
8 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
9 | 5 | * under the terms of the GNU General Public License version 3, | ||
10 | 6 | * as published by the Free Software Foundation. | ||
11 | 7 | * | ||
12 | 8 | * This program is distributed in the hope that it will be useful, | ||
13 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | 11 | * GNU General Public License for more details. | ||
16 | 12 | * | ||
17 | 13 | * You should have received a copy of the GNU General Public License | ||
18 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | 15 | * | ||
20 | 16 | * Authored By: Alan Griffiths <alan@octopull.co.uk> | ||
21 | 17 | */ | ||
22 | 18 | |||
23 | 19 | #ifndef MIR_SERVER_H_ | ||
24 | 20 | #define MIR_SERVER_H_ | ||
25 | 21 | |||
26 | 22 | #include <functional> | ||
27 | 23 | #include <memory> | ||
28 | 24 | |||
29 | 25 | namespace mir | ||
30 | 26 | { | ||
31 | 27 | namespace compositor { class Compositor; } | ||
32 | 28 | namespace frontend { class SessionAuthorizer; } | ||
33 | 29 | namespace graphics { class Platform; class Display; class GLConfig; } | ||
34 | 30 | namespace input { class CompositeEventFilter; class InputDispatcher; class CursorListener; } | ||
35 | 31 | namespace options { class Option; } | ||
36 | 32 | namespace shell { class FocusSetter; class DisplayLayout; } | ||
37 | 33 | namespace scene | ||
38 | 34 | { | ||
39 | 35 | class PlacementStrategy; | ||
40 | 36 | class SessionListener; | ||
41 | 37 | class PromptSessionListener; | ||
42 | 38 | class SurfaceConfigurator; | ||
43 | 39 | class SessionCoordinator; | ||
44 | 40 | class SurfaceCoordinator; | ||
45 | 41 | } | ||
46 | 42 | |||
47 | 43 | class MainLoop; | ||
48 | 44 | class ServerStatusListener; | ||
49 | 45 | |||
50 | 46 | enum class OptionType | ||
51 | 47 | { | ||
52 | 48 | null, | ||
53 | 49 | integer, | ||
54 | 50 | string | ||
55 | 51 | }; | ||
56 | 52 | |||
57 | 53 | /// Customise and run a Mir server. | ||
58 | 54 | class Server | ||
59 | 55 | { | ||
60 | 56 | public: | ||
61 | 57 | Server(); | ||
62 | 58 | |||
63 | 59 | /** @name Essential operations | ||
64 | 60 | * These are the commands used to run and stop. | ||
65 | 61 | * @{ */ | ||
66 | 62 | /// set the command line (this must remain valid while run() is called) | ||
67 | 63 | void set_command_line(int argc, char const* argv[]); | ||
68 | 64 | |||
69 | 65 | /// Run the Mir server until it exits | ||
70 | 66 | void run(); | ||
71 | 67 | |||
72 | 68 | /// Tell the Mir server to exit | ||
73 | 69 | void stop(); | ||
74 | 70 | |||
75 | 71 | /// returns true if and only if server exited normally. Otherwise false. | ||
76 | 72 | bool exited_normally(); | ||
77 | 73 | /** @} */ | ||
78 | 74 | |||
79 | 75 | /** @name Configuration options | ||
80 | 76 | * @{ */ | ||
81 | 77 | /// Add user configuration option(s) to Mir's option handling. | ||
82 | 78 | /// These will be resolved during initialisation from the command line, | ||
83 | 79 | /// environment variables, a config file or the supplied default. | ||
84 | 80 | void add_configuration_option( | ||
85 | 81 | std::string const& option, | ||
86 | 82 | std::string const& description, | ||
87 | 83 | int default_value); | ||
88 | 84 | |||
89 | 85 | /// Add user configuration option(s) to Mir's option handling. | ||
90 | 86 | /// These will be resolved during initialisation from the command line, | ||
91 | 87 | /// environment variables, a config file or the supplied default. | ||
92 | 88 | void add_configuration_option( | ||
93 | 89 | std::string const& option, | ||
94 | 90 | std::string const& description, | ||
95 | 91 | std::string const& default_value); | ||
96 | 92 | |||
97 | 93 | /// Add user configuration option(s) to Mir's option handling. | ||
98 | 94 | /// These will be resolved during initialisation from the command line, | ||
99 | 95 | /// environment variables, a config file or the supplied default. | ||
100 | 96 | void add_configuration_option( | ||
101 | 97 | std::string const& option, | ||
102 | 98 | std::string const& description, | ||
103 | 99 | OptionType type); | ||
104 | 100 | |||
105 | 101 | /// Set a handler for any command line options Mir does not recognise. | ||
106 | 102 | /// This will be invoked if any unrecognised options are found during initialisation. | ||
107 | 103 | /// Any unrecognised arguments are passed to this function. The pointers remain valid | ||
108 | 104 | /// for the duration of the call only. | ||
109 | 105 | /// If set_command_line_handler is not called the default action is to exit by | ||
110 | 106 | /// throwing mir::AbnormalExit (which will be handled by the exception handler prior to | ||
111 | 107 | /// exiting run(). | ||
112 | 108 | void set_command_line_handler( | ||
113 | 109 | std::function<void(int argc, char const* const* argv)> const& command_line_hander); | ||
114 | 110 | |||
115 | 111 | /// Returns the configuration options. | ||
116 | 112 | /// This will be null before initialization completes. It will be available | ||
117 | 113 | /// when the init_callback has been invoked (and thereafter until the server exits). | ||
118 | 114 | auto get_options() const -> std::shared_ptr<options::Option>; | ||
119 | 115 | /** @} */ | ||
120 | 116 | |||
121 | 117 | /** @name Using hooks into the run() logic | ||
122 | 118 | * @{ */ | ||
123 | 119 | /// Add a callback to be invoked when the server has been initialized, | ||
124 | 120 | /// but before it starts. This allows client code to get access Mir objects. | ||
125 | 121 | /// If multiple callbacks are added they will be invoked in the sequence added. | ||
126 | 122 | void add_init_callback(std::function<void()> const& init_callback); | ||
127 | 123 | |||
128 | 124 | /// Set a handler for exceptions. This is invoked in a catch (...) block and | ||
129 | 125 | /// the exception can be re-thrown to retrieve type information. | ||
130 | 126 | /// The default action is to call mir::report_exception(std::cerr) | ||
131 | 127 | void set_exception_handler(std::function<void()> const& exception_handler); | ||
132 | 128 | /** @} */ | ||
133 | 129 | |||
134 | 130 | /** @name Getting access to Mir subsystems | ||
135 | 131 | * These will throw before initialization starts or after the server exits. | ||
136 | 132 | * They may be invoked by the functors that provide alternative implementations of | ||
137 | 133 | * Mir subsystems and when the init_callback is invoked (and thereafter | ||
138 | 134 | * until the server exits). | ||
139 | 135 | * @{ */ | ||
140 | 136 | /// \return the composite event filter. | ||
141 | 137 | auto the_composite_event_filter() const -> std::shared_ptr<input::CompositeEventFilter>; | ||
142 | 138 | |||
143 | 139 | /// \return the cursor listener. | ||
144 | 140 | auto the_cursor_listener() const -> std::shared_ptr<input::CursorListener>; | ||
145 | 141 | |||
146 | 142 | /// \return the graphics display. | ||
147 | 143 | auto the_display() const -> std::shared_ptr<graphics::Display>; | ||
148 | 144 | |||
149 | 145 | /// \return the graphics platform. | ||
150 | 146 | auto the_graphics_platform() const -> std::shared_ptr<graphics::Platform>; | ||
151 | 147 | |||
152 | 148 | /// \return the main loop. | ||
153 | 149 | auto the_main_loop() const -> std::shared_ptr<MainLoop>; | ||
154 | 150 | |||
155 | 151 | /// \return the prompt session listener. | ||
156 | 152 | auto the_prompt_session_listener() const -> std::shared_ptr<scene::PromptSessionListener>; | ||
157 | 153 | |||
158 | 154 | /// \return the session authorizer. | ||
159 | 155 | auto the_session_authorizer() const -> std::shared_ptr<frontend::SessionAuthorizer>; | ||
160 | 156 | |||
161 | 157 | /// \return the session listener. | ||
162 | 158 | auto the_session_listener() const -> std::shared_ptr<scene::SessionListener>; | ||
163 | 159 | |||
164 | 160 | /// \return the display layout. | ||
165 | 161 | auto the_shell_display_layout() const -> std::shared_ptr<shell::DisplayLayout>; | ||
166 | 162 | |||
167 | 163 | /// \return the surface configurator. | ||
168 | 164 | auto the_surface_configurator() const -> std::shared_ptr<scene::SurfaceConfigurator>; | ||
169 | 165 | /** @} */ | ||
170 | 166 | |||
171 | 167 | /** @name Providing custom implementation | ||
172 | 168 | * Provide alternative implementations of Mir subsystems: the functors will be invoked during initialization | ||
173 | 169 | * (this is only useful before initialization starts). | ||
174 | 170 | * @{ */ | ||
175 | 171 | /// Sets an override functor for creating the compositor. | ||
176 | 172 | void override_the_compositor(std::function<std::shared_ptr<compositor::Compositor>()> const& compositor_builder); | ||
177 | 173 | |||
178 | 174 | /// Sets an override functor for creating the cursor listener. | ||
179 | 175 | void override_the_cursor_listener(std::function<std::shared_ptr<input::CursorListener>()> const& cursor_listener_builder); | ||
180 | 176 | |||
181 | 177 | /// Sets an override functor for creating the gl config. | ||
182 | 178 | void override_the_gl_config(std::function<std::shared_ptr<graphics::GLConfig>()> const& gl_config_builder); | ||
183 | 179 | |||
184 | 180 | /// Sets an override functor for creating the input dispatcher. | ||
185 | 181 | void override_the_input_dispatcher(std::function<std::shared_ptr<input::InputDispatcher>()> const& input_dispatcher_builder); | ||
186 | 182 | |||
187 | 183 | /// Sets an override functor for creating the placement strategy. | ||
188 | 184 | void override_the_placement_strategy(std::function<std::shared_ptr<scene::PlacementStrategy>()> const& placement_strategy_builder); | ||
189 | 185 | |||
190 | 186 | /// Sets an override functor for creating the prompt session listener. | ||
191 | 187 | void override_the_prompt_session_listener(std::function<std::shared_ptr<scene::PromptSessionListener>()> const& prompt_session_listener_builder); | ||
192 | 188 | |||
193 | 189 | /// Sets an override functor for creating the status listener. | ||
194 | 190 | void override_the_server_status_listener(std::function<std::shared_ptr<ServerStatusListener>()> const& server_status_listener_builder); | ||
195 | 191 | |||
196 | 192 | /// Sets an override functor for creating the session authorizer. | ||
197 | 193 | void override_the_session_authorizer(std::function<std::shared_ptr<frontend::SessionAuthorizer>()> const& session_authorizer_builder); | ||
198 | 194 | |||
199 | 195 | /// Sets an override functor for creating the session listener. | ||
200 | 196 | void override_the_session_listener(std::function<std::shared_ptr<scene::SessionListener>()> const& session_listener_builder); | ||
201 | 197 | |||
202 | 198 | /// Sets an override functor for creating the shell focus setter. | ||
203 | 199 | void override_the_shell_focus_setter(std::function<std::shared_ptr<shell::FocusSetter>()> const& focus_setter_builder); | ||
204 | 200 | |||
205 | 201 | /// Sets an override functor for creating the surface configurator. | ||
206 | 202 | void override_the_surface_configurator(std::function<std::shared_ptr<scene::SurfaceConfigurator>()> const& surface_configurator_builder); | ||
207 | 203 | |||
208 | 204 | /// Sets a wrapper functor for creating the session coordinator. | ||
209 | 205 | void wrap_session_coordinator(std::function<std::shared_ptr<scene::SessionCoordinator>(std::shared_ptr<scene::SessionCoordinator> const& wrapped)> const& wrapper); | ||
210 | 206 | |||
211 | 207 | /// Sets a wrapper functor for creating the surface coordinator. | ||
212 | 208 | void wrap_surface_coordinator(std::function<std::shared_ptr<scene::SurfaceCoordinator>(std::shared_ptr<scene::SurfaceCoordinator> const& wrapped)> const& wrapper); | ||
213 | 209 | /** @} */ | ||
214 | 210 | |||
215 | 211 | private: | ||
216 | 212 | struct ServerConfiguration; | ||
217 | 213 | struct Self; | ||
218 | 214 | std::shared_ptr<Self> const self; | ||
219 | 215 | }; | ||
220 | 216 | } | ||
221 | 217 | #endif /* SERVER_H_ */ | ||
222 | 0 | 218 | ||
223 | === modified file 'server-ABI-sha1sums' | |||
224 | --- server-ABI-sha1sums 2014-10-14 17:55:14 +0000 | |||
225 | +++ server-ABI-sha1sums 2014-10-15 09:19:21 +0000 | |||
226 | @@ -95,6 +95,7 @@ | |||
227 | 95 | 993e9f458ffc4288d304413f3fa0b1dcc95a093d include/server/mir/scene/surface_observer.h | 95 | 993e9f458ffc4288d304413f3fa0b1dcc95a093d include/server/mir/scene/surface_observer.h |
228 | 96 | 7ef3e99901168cda296d74d05a979f47bf9c3ff1 include/server/mir/server_action_queue.h | 96 | 7ef3e99901168cda296d74d05a979f47bf9c3ff1 include/server/mir/server_action_queue.h |
229 | 97 | 8d83a51c278b8b71866d2178d9b6387c1f91a7d0 include/server/mir/server_configuration.h | 97 | 8d83a51c278b8b71866d2178d9b6387c1f91a7d0 include/server/mir/server_configuration.h |
230 | 98 | 5d79d4a973b597d7cc1de766bd0ef3d30b389e18 include/server/mir/server.h | ||
231 | 98 | 86098b500339bfccd07a9bed8298f75a68b18f5c include/server/mir/server_status_listener.h | 99 | 86098b500339bfccd07a9bed8298f75a68b18f5c include/server/mir/server_status_listener.h |
232 | 99 | 860c04f32b60e680140148dc9dc2295de145b9c1 include/server/mir/shell/display_layout.h | 100 | 860c04f32b60e680140148dc9dc2295de145b9c1 include/server/mir/shell/display_layout.h |
233 | 100 | 6a2107b01feae13060d5c305804906e53c52e0be include/server/mir/shell/focus_controller.h | 101 | 6a2107b01feae13060d5c305804906e53c52e0be include/server/mir/shell/focus_controller.h |
234 | 101 | 102 | ||
235 | === modified file 'src/server/CMakeLists.txt' | |||
236 | --- src/server/CMakeLists.txt 2014-10-10 05:44:12 +0000 | |||
237 | +++ src/server/CMakeLists.txt 2014-10-15 09:19:21 +0000 | |||
238 | @@ -32,6 +32,7 @@ | |||
239 | 32 | default_server_configuration.cpp | 32 | default_server_configuration.cpp |
240 | 33 | asio_main_loop.cpp | 33 | asio_main_loop.cpp |
241 | 34 | default_emergency_cleanup.cpp | 34 | default_emergency_cleanup.cpp |
242 | 35 | server.cpp | ||
243 | 35 | ) | 36 | ) |
244 | 36 | 37 | ||
245 | 37 | set(MIR_SERVER_OBJECTS | 38 | set(MIR_SERVER_OBJECTS |
246 | 38 | 39 | ||
247 | === added file 'src/server/server.cpp' | |||
248 | --- src/server/server.cpp 1970-01-01 00:00:00 +0000 | |||
249 | +++ src/server/server.cpp 2014-10-15 09:19:21 +0000 | |||
250 | @@ -0,0 +1,373 @@ | |||
251 | 1 | /* | ||
252 | 2 | * Copyright © 2014 Canonical Ltd. | ||
253 | 3 | * | ||
254 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
255 | 5 | * under the terms of the GNU General Public License version 3, | ||
256 | 6 | * as published by the Free Software Foundation. | ||
257 | 7 | * | ||
258 | 8 | * This program is distributed in the hope that it will be useful, | ||
259 | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
260 | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
261 | 11 | * GNU General Public License for more details. | ||
262 | 12 | * | ||
263 | 13 | * You should have received a copy of the GNU General Public License | ||
264 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
265 | 15 | * | ||
266 | 16 | * Authored By: Alan Griffiths <alan@octopull.co.uk> | ||
267 | 17 | */ | ||
268 | 18 | |||
269 | 19 | #include "mir/server.h" | ||
270 | 20 | |||
271 | 21 | #include "mir/options/default_configuration.h" | ||
272 | 22 | #include "mir/default_server_configuration.h" | ||
273 | 23 | #include "mir/main_loop.h" | ||
274 | 24 | #include "mir/report_exception.h" | ||
275 | 25 | #include "mir/run_mir.h" | ||
276 | 26 | |||
277 | 27 | #include <iostream> | ||
278 | 28 | |||
279 | 29 | namespace mo = mir::options; | ||
280 | 30 | |||
281 | 31 | #define FOREACH_WRAPPER(MACRO)\ | ||
282 | 32 | MACRO(session_coordinator)\ | ||
283 | 33 | MACRO(surface_coordinator) | ||
284 | 34 | |||
285 | 35 | #define FOREACH_OVERRIDE(MACRO)\ | ||
286 | 36 | MACRO(compositor)\ | ||
287 | 37 | MACRO(cursor_listener)\ | ||
288 | 38 | MACRO(gl_config)\ | ||
289 | 39 | MACRO(input_dispatcher)\ | ||
290 | 40 | MACRO(placement_strategy)\ | ||
291 | 41 | MACRO(prompt_session_listener)\ | ||
292 | 42 | MACRO(server_status_listener)\ | ||
293 | 43 | MACRO(session_authorizer)\ | ||
294 | 44 | MACRO(session_listener)\ | ||
295 | 45 | MACRO(shell_focus_setter)\ | ||
296 | 46 | MACRO(surface_configurator) | ||
297 | 47 | |||
298 | 48 | #define FOREACH_ACCESSOR(MACRO)\ | ||
299 | 49 | MACRO(the_composite_event_filter)\ | ||
300 | 50 | MACRO(the_display)\ | ||
301 | 51 | MACRO(the_graphics_platform)\ | ||
302 | 52 | MACRO(the_main_loop)\ | ||
303 | 53 | MACRO(the_prompt_session_listener)\ | ||
304 | 54 | MACRO(the_session_authorizer)\ | ||
305 | 55 | MACRO(the_session_listener)\ | ||
306 | 56 | MACRO(the_shell_display_layout)\ | ||
307 | 57 | MACRO(the_surface_configurator) | ||
308 | 58 | |||
309 | 59 | #define MIR_SERVER_BUILDER(name)\ | ||
310 | 60 | std::function<std::result_of<decltype(&mir::DefaultServerConfiguration::the_##name)(mir::DefaultServerConfiguration*)>::type()> name##_builder; | ||
311 | 61 | |||
312 | 62 | #define MIR_SERVER_WRAPPER(name)\ | ||
313 | 63 | std::function<std::result_of<decltype(&mir::DefaultServerConfiguration::the_##name)(mir::DefaultServerConfiguration*)>::type\ | ||
314 | 64 | (std::result_of<decltype(&mir::DefaultServerConfiguration::the_##name)(mir::DefaultServerConfiguration*)>::type const&)> name##_wrapper; | ||
315 | 65 | |||
316 | 66 | struct mir::Server::Self | ||
317 | 67 | { | ||
318 | 68 | bool exit_status{false}; | ||
319 | 69 | std::weak_ptr<options::Option> options; | ||
320 | 70 | ServerConfiguration* server_config{nullptr}; | ||
321 | 71 | |||
322 | 72 | std::function<void()> init_callback{[]{}}; | ||
323 | 73 | int argc{0}; | ||
324 | 74 | char const** argv{nullptr}; | ||
325 | 75 | std::function<void()> exception_handler{}; | ||
326 | 76 | |||
327 | 77 | std::function<void(int argc, char const* const* argv)> command_line_hander{}; | ||
328 | 78 | |||
329 | 79 | /// set a callback to introduce additional configuration options. | ||
330 | 80 | /// this will be invoked by run() before server initialisation starts | ||
331 | 81 | void set_add_configuration_options( | ||
332 | 82 | std::function<void(options::DefaultConfiguration& config)> const& add_configuration_options); | ||
333 | 83 | |||
334 | 84 | std::function<void(options::DefaultConfiguration& config)> add_configuration_options{ | ||
335 | 85 | [](options::DefaultConfiguration&){}}; | ||
336 | 86 | |||
337 | 87 | FOREACH_OVERRIDE(MIR_SERVER_BUILDER) | ||
338 | 88 | |||
339 | 89 | FOREACH_WRAPPER(MIR_SERVER_WRAPPER) | ||
340 | 90 | }; | ||
341 | 91 | |||
342 | 92 | #undef MIR_SERVER_BUILDER | ||
343 | 93 | #undef MIR_SERVER_WRAPPER | ||
344 | 94 | |||
345 | 95 | #define MIR_SERVER_CONFIG_OVERRIDE(name)\ | ||
346 | 96 | auto the_##name()\ | ||
347 | 97 | -> decltype(mir::DefaultServerConfiguration::the_##name()) override\ | ||
348 | 98 | {\ | ||
349 | 99 | if (self->name##_builder)\ | ||
350 | 100 | return name(\ | ||
351 | 101 | [this] { return self->name##_builder(); });\ | ||
352 | 102 | \ | ||
353 | 103 | return mir::DefaultServerConfiguration::the_##name();\ | ||
354 | 104 | } | ||
355 | 105 | |||
356 | 106 | #define MIR_SERVER_CONFIG_WRAP(name)\ | ||
357 | 107 | auto wrap_##name(decltype(Self::name##_wrapper)::result_type const& wrapped)\ | ||
358 | 108 | -> decltype(mir::DefaultServerConfiguration::wrap_##name({})) override\ | ||
359 | 109 | {\ | ||
360 | 110 | if (self->name##_wrapper)\ | ||
361 | 111 | return name(\ | ||
362 | 112 | [&] { return self->name##_wrapper(wrapped); });\ | ||
363 | 113 | \ | ||
364 | 114 | return mir::DefaultServerConfiguration::wrap_##name(wrapped);\ | ||
365 | 115 | } | ||
366 | 116 | |||
367 | 117 | struct mir::Server::ServerConfiguration : mir::DefaultServerConfiguration | ||
368 | 118 | { | ||
369 | 119 | ServerConfiguration( | ||
370 | 120 | std::shared_ptr<options::Configuration> const& configuration_options, | ||
371 | 121 | std::shared_ptr<Self> const self) : | ||
372 | 122 | DefaultServerConfiguration(configuration_options), | ||
373 | 123 | self(self) | ||
374 | 124 | { | ||
375 | 125 | } | ||
376 | 126 | |||
377 | 127 | using mir::DefaultServerConfiguration::the_options; | ||
378 | 128 | |||
379 | 129 | // TODO the MIR_SERVER_CONFIG_OVERRIDE macro expects a CachePtr named | ||
380 | 130 | // TODO "placement_strategy" not "shell_placement_strategy". | ||
381 | 131 | // Unfortunately, "shell_placement_strategy" is currently part of our | ||
382 | 132 | // published API and used by qtmir: we cannot just rename it to remove | ||
383 | 133 | // this ugliness. (Yet.) | ||
384 | 134 | decltype(shell_placement_strategy)& placement_strategy = shell_placement_strategy; | ||
385 | 135 | |||
386 | 136 | FOREACH_OVERRIDE(MIR_SERVER_CONFIG_OVERRIDE) | ||
387 | 137 | |||
388 | 138 | FOREACH_WRAPPER(MIR_SERVER_CONFIG_WRAP) | ||
389 | 139 | |||
390 | 140 | std::shared_ptr<Self> const self; | ||
391 | 141 | }; | ||
392 | 142 | |||
393 | 143 | #undef MIR_SERVER_CONFIG_OVERRIDE | ||
394 | 144 | #undef MIR_SERVER_CONFIG_WRAP | ||
395 | 145 | |||
396 | 146 | namespace | ||
397 | 147 | { | ||
398 | 148 | std::shared_ptr<mo::DefaultConfiguration> configuration_options( | ||
399 | 149 | int argc, | ||
400 | 150 | char const** argv, | ||
401 | 151 | std::function<void(int argc, char const* const* argv)> const& command_line_hander) | ||
402 | 152 | { | ||
403 | 153 | if (command_line_hander) | ||
404 | 154 | return std::make_shared<mo::DefaultConfiguration>(argc, argv, command_line_hander); | ||
405 | 155 | else | ||
406 | 156 | return std::make_shared<mo::DefaultConfiguration>(argc, argv); | ||
407 | 157 | |||
408 | 158 | } | ||
409 | 159 | } | ||
410 | 160 | |||
411 | 161 | mir::Server::Server() : | ||
412 | 162 | self(std::make_shared<Self>()) | ||
413 | 163 | { | ||
414 | 164 | } | ||
415 | 165 | |||
416 | 166 | void mir::Server::Self::set_add_configuration_options( | ||
417 | 167 | std::function<void(mo::DefaultConfiguration& config)> const& add_configuration_options) | ||
418 | 168 | { | ||
419 | 169 | this->add_configuration_options = add_configuration_options; | ||
420 | 170 | } | ||
421 | 171 | |||
422 | 172 | |||
423 | 173 | void mir::Server::set_command_line(int argc, char const* argv[]) | ||
424 | 174 | { | ||
425 | 175 | self->argc = argc; | ||
426 | 176 | self->argv = argv; | ||
427 | 177 | } | ||
428 | 178 | |||
429 | 179 | void mir::Server::add_init_callback(std::function<void()> const& init_callback) | ||
430 | 180 | { | ||
431 | 181 | auto const& existing = self->init_callback; | ||
432 | 182 | |||
433 | 183 | auto const updated = [=] | ||
434 | 184 | { | ||
435 | 185 | existing(); | ||
436 | 186 | init_callback(); | ||
437 | 187 | }; | ||
438 | 188 | |||
439 | 189 | self->init_callback = updated; | ||
440 | 190 | } | ||
441 | 191 | |||
442 | 192 | auto mir::Server::get_options() const -> std::shared_ptr<options::Option> | ||
443 | 193 | { | ||
444 | 194 | return self->options.lock(); | ||
445 | 195 | } | ||
446 | 196 | |||
447 | 197 | void mir::Server::set_exception_handler(std::function<void()> const& exception_handler) | ||
448 | 198 | { | ||
449 | 199 | self->exception_handler = exception_handler; | ||
450 | 200 | } | ||
451 | 201 | |||
452 | 202 | void mir::Server::run() | ||
453 | 203 | try | ||
454 | 204 | { | ||
455 | 205 | auto const options = configuration_options(self->argc, self->argv, self->command_line_hander); | ||
456 | 206 | |||
457 | 207 | self->add_configuration_options(*options); | ||
458 | 208 | |||
459 | 209 | ServerConfiguration config{options, self}; | ||
460 | 210 | |||
461 | 211 | self->server_config = &config; | ||
462 | 212 | |||
463 | 213 | self->options = config.the_options(); | ||
464 | 214 | |||
465 | 215 | run_mir(config, [&](DisplayServer&) | ||
466 | 216 | { | ||
467 | 217 | self->init_callback(); | ||
468 | 218 | }); | ||
469 | 219 | |||
470 | 220 | self->exit_status = true; | ||
471 | 221 | self->server_config = nullptr; | ||
472 | 222 | } | ||
473 | 223 | catch (...) | ||
474 | 224 | { | ||
475 | 225 | self->server_config = nullptr; | ||
476 | 226 | |||
477 | 227 | if (self->exception_handler) | ||
478 | 228 | self->exception_handler(); | ||
479 | 229 | else | ||
480 | 230 | mir::report_exception(std::cerr); | ||
481 | 231 | } | ||
482 | 232 | |||
483 | 233 | void mir::Server::stop() | ||
484 | 234 | { | ||
485 | 235 | if (auto const main_loop = the_main_loop()) | ||
486 | 236 | main_loop->stop(); | ||
487 | 237 | } | ||
488 | 238 | |||
489 | 239 | bool mir::Server::exited_normally() | ||
490 | 240 | { | ||
491 | 241 | return self->exit_status; | ||
492 | 242 | } | ||
493 | 243 | |||
494 | 244 | namespace | ||
495 | 245 | { | ||
496 | 246 | auto const no_config_to_access = "Cannot access config when no config active."; | ||
497 | 247 | } | ||
498 | 248 | |||
499 | 249 | #define MIR_SERVER_ACCESSOR(name)\ | ||
500 | 250 | auto mir::Server::name() const -> decltype(self->server_config->name())\ | ||
501 | 251 | {\ | ||
502 | 252 | if (self->server_config) return self->server_config->name();\ | ||
503 | 253 | BOOST_THROW_EXCEPTION(std::logic_error(no_config_to_access));\ | ||
504 | 254 | } | ||
505 | 255 | |||
506 | 256 | FOREACH_ACCESSOR(MIR_SERVER_ACCESSOR) | ||
507 | 257 | |||
508 | 258 | #undef MIR_SERVER_ACCESSOR | ||
509 | 259 | |||
510 | 260 | #define MIR_SERVER_OVERRIDE(name)\ | ||
511 | 261 | void mir::Server::override_the_##name(decltype(Self::name##_builder) const& value)\ | ||
512 | 262 | {\ | ||
513 | 263 | self->name##_builder = value;\ | ||
514 | 264 | } | ||
515 | 265 | |||
516 | 266 | FOREACH_OVERRIDE(MIR_SERVER_OVERRIDE) | ||
517 | 267 | |||
518 | 268 | #undef MIR_SERVER_OVERRIDE | ||
519 | 269 | |||
520 | 270 | #define MIR_SERVER_WRAP(name)\ | ||
521 | 271 | void mir::Server::wrap_##name(decltype(Self::name##_wrapper) const& value)\ | ||
522 | 272 | {\ | ||
523 | 273 | self->name##_wrapper = value;\ | ||
524 | 274 | } | ||
525 | 275 | |||
526 | 276 | FOREACH_WRAPPER(MIR_SERVER_WRAP) | ||
527 | 277 | |||
528 | 278 | #undef MIR_SERVER_WRAP | ||
529 | 279 | |||
530 | 280 | void mir::Server::add_configuration_option( | ||
531 | 281 | std::string const& option, | ||
532 | 282 | std::string const& description, | ||
533 | 283 | int default_) | ||
534 | 284 | { | ||
535 | 285 | namespace po = boost::program_options; | ||
536 | 286 | |||
537 | 287 | auto const& existing = self->add_configuration_options; | ||
538 | 288 | |||
539 | 289 | auto const option_adder = [=](options::DefaultConfiguration& config) | ||
540 | 290 | { | ||
541 | 291 | existing(config); | ||
542 | 292 | |||
543 | 293 | config.add_options() | ||
544 | 294 | (option.c_str(), po::value<int>()->default_value(default_), description.c_str()); | ||
545 | 295 | }; | ||
546 | 296 | |||
547 | 297 | self->set_add_configuration_options(option_adder); | ||
548 | 298 | } | ||
549 | 299 | |||
550 | 300 | void mir::Server::add_configuration_option( | ||
551 | 301 | std::string const& option, | ||
552 | 302 | std::string const& description, | ||
553 | 303 | std::string const& default_) | ||
554 | 304 | { | ||
555 | 305 | namespace po = boost::program_options; | ||
556 | 306 | |||
557 | 307 | auto const& existing = self->add_configuration_options; | ||
558 | 308 | |||
559 | 309 | auto const option_adder = [=](options::DefaultConfiguration& config) | ||
560 | 310 | { | ||
561 | 311 | existing(config); | ||
562 | 312 | |||
563 | 313 | config.add_options() | ||
564 | 314 | (option.c_str(), po::value<std::string>()->default_value(default_), description.c_str()); | ||
565 | 315 | }; | ||
566 | 316 | |||
567 | 317 | self->set_add_configuration_options(option_adder); | ||
568 | 318 | } | ||
569 | 319 | |||
570 | 320 | void mir::Server::add_configuration_option( | ||
571 | 321 | std::string const& option, | ||
572 | 322 | std::string const& description, | ||
573 | 323 | OptionType type) | ||
574 | 324 | { | ||
575 | 325 | namespace po = boost::program_options; | ||
576 | 326 | |||
577 | 327 | auto const& existing = self->add_configuration_options; | ||
578 | 328 | |||
579 | 329 | switch (type) | ||
580 | 330 | { | ||
581 | 331 | case OptionType::null: | ||
582 | 332 | { | ||
583 | 333 | auto const option_adder = [=](options::DefaultConfiguration& config) | ||
584 | 334 | { | ||
585 | 335 | existing(config); | ||
586 | 336 | |||
587 | 337 | config.add_options() | ||
588 | 338 | (option.c_str(), description.c_str()); | ||
589 | 339 | }; | ||
590 | 340 | |||
591 | 341 | self->set_add_configuration_options(option_adder); | ||
592 | 342 | } | ||
593 | 343 | break; | ||
594 | 344 | |||
595 | 345 | case OptionType::integer: | ||
596 | 346 | { | ||
597 | 347 | auto const option_adder = [=](options::DefaultConfiguration& config) | ||
598 | 348 | { | ||
599 | 349 | existing(config); | ||
600 | 350 | |||
601 | 351 | config.add_options() | ||
602 | 352 | (option.c_str(), po::value<int>(), description.c_str()); | ||
603 | 353 | }; | ||
604 | 354 | |||
605 | 355 | self->set_add_configuration_options(option_adder); | ||
606 | 356 | } | ||
607 | 357 | break; | ||
608 | 358 | |||
609 | 359 | case OptionType::string: | ||
610 | 360 | { | ||
611 | 361 | auto const option_adder = [=](options::DefaultConfiguration& config) | ||
612 | 362 | { | ||
613 | 363 | existing(config); | ||
614 | 364 | |||
615 | 365 | config.add_options() | ||
616 | 366 | (option.c_str(), po::value<std::string>(), description.c_str()); | ||
617 | 367 | }; | ||
618 | 368 | |||
619 | 369 | self->set_add_configuration_options(option_adder); | ||
620 | 370 | } | ||
621 | 371 | break; | ||
622 | 372 | } | ||
623 | 373 | } | ||
624 | 0 | 374 | ||
625 | === modified file 'src/server/symbols.map' | |||
626 | --- src/server/symbols.map 2014-10-14 17:55:14 +0000 | |||
627 | +++ src/server/symbols.map 2014-10-15 09:19:21 +0000 | |||
628 | @@ -375,6 +375,7 @@ | |||
629 | 375 | mir::ServerActionQueue::resume_processing_for*; | 375 | mir::ServerActionQueue::resume_processing_for*; |
630 | 376 | mir::ServerActionQueue::?ServerActionQueue*; | 376 | mir::ServerActionQueue::?ServerActionQueue*; |
631 | 377 | mir::ServerActionQueue::ServerActionQueue*; | 377 | mir::ServerActionQueue::ServerActionQueue*; |
632 | 378 | mir::Server::add_configuration_option*; | ||
633 | 378 | mir::ServerConfiguration::operator*; | 379 | mir::ServerConfiguration::operator*; |
634 | 379 | mir::ServerConfiguration::?ServerConfiguration*; | 380 | mir::ServerConfiguration::?ServerConfiguration*; |
635 | 380 | mir::ServerConfiguration::ServerConfiguration*; | 381 | mir::ServerConfiguration::ServerConfiguration*; |
636 | @@ -390,12 +391,45 @@ | |||
637 | 390 | mir::ServerConfiguration::the_main_loop*; | 391 | mir::ServerConfiguration::the_main_loop*; |
638 | 391 | mir::ServerConfiguration::the_prompt_connector*; | 392 | mir::ServerConfiguration::the_prompt_connector*; |
639 | 392 | mir::ServerConfiguration::the_server_status_listener*; | 393 | mir::ServerConfiguration::the_server_status_listener*; |
640 | 394 | mir::Server::add_init_callback*; | ||
641 | 395 | mir::Server::exited_normally*; | ||
642 | 396 | mir::Server::get_options*; | ||
643 | 397 | mir::Server::override_the_compositor*; | ||
644 | 398 | mir::Server::override_the_cursor_listener*; | ||
645 | 399 | mir::Server::override_the_gl_config*; | ||
646 | 400 | mir::Server::override_the_input_dispatcher*; | ||
647 | 401 | mir::Server::override_the_placement_strategy*; | ||
648 | 402 | mir::Server::override_the_prompt_session_listener*; | ||
649 | 403 | mir::Server::override_the_server_status_listener*; | ||
650 | 404 | mir::Server::override_the_session_authorizer*; | ||
651 | 405 | mir::Server::override_the_session_listener*; | ||
652 | 406 | mir::Server::override_the_shell_focus_setter*; | ||
653 | 407 | mir::Server::override_the_surface_configurator*; | ||
654 | 408 | mir::Server::run*; | ||
655 | 409 | mir::Server::Server*; | ||
656 | 410 | mir::Server::set_command_line*; | ||
657 | 411 | mir::Server::set_command_line_hander*; | ||
658 | 412 | mir::Server::set_exception_handler*; | ||
659 | 393 | mir::ServerStatusListener::operator*; | 413 | mir::ServerStatusListener::operator*; |
660 | 394 | mir::ServerStatusListener::paused*; | 414 | mir::ServerStatusListener::paused*; |
661 | 395 | mir::ServerStatusListener::resumed*; | 415 | mir::ServerStatusListener::resumed*; |
662 | 396 | mir::ServerStatusListener::?ServerStatusListener*; | 416 | mir::ServerStatusListener::?ServerStatusListener*; |
663 | 397 | mir::ServerStatusListener::ServerStatusListener*; | 417 | mir::ServerStatusListener::ServerStatusListener*; |
664 | 398 | mir::ServerStatusListener::started*; | 418 | mir::ServerStatusListener::started*; |
665 | 419 | mir::Server::stop*; | ||
666 | 420 | mir::Server::the_composite_event_filter*; | ||
667 | 421 | mir::Server::the_cursor_listener*; | ||
668 | 422 | mir::Server::the_display*; | ||
669 | 423 | mir::Server::the_graphics_platform*; | ||
670 | 424 | mir::Server::the_main_loop*; | ||
671 | 425 | mir::Server::the_prompt_session_listener*; | ||
672 | 426 | mir::Server::the_server_status_listener*; | ||
673 | 427 | mir::Server::the_session_authorizer*; | ||
674 | 428 | mir::Server::the_session_listener*; | ||
675 | 429 | mir::Server::the_shell_display_layout*; | ||
676 | 430 | mir::Server::the_surface_configurator*; | ||
677 | 431 | mir::Server::wrap_session_coordinator*; | ||
678 | 432 | mir::Server::wrap_surface_coordinator*; | ||
679 | 399 | mir::shell::DisplayLayout::clip_to_output*; | 433 | mir::shell::DisplayLayout::clip_to_output*; |
680 | 400 | mir::shell::DisplayLayout::?DisplayLayout*; | 434 | mir::shell::DisplayLayout::?DisplayLayout*; |
681 | 401 | mir::shell::DisplayLayout::DisplayLayout*; | 435 | mir::shell::DisplayLayout::DisplayLayout*; |
682 | @@ -592,6 +626,7 @@ | |||
683 | 592 | typeinfo?for?mir::compositor::Scene; | 626 | typeinfo?for?mir::compositor::Scene; |
684 | 593 | typeinfo?for?mir::compositor::SceneElement; | 627 | typeinfo?for?mir::compositor::SceneElement; |
685 | 594 | typeinfo?for?mir::DefaultServerConfiguration; | 628 | typeinfo?for?mir::DefaultServerConfiguration; |
686 | 629 | typeinfo?for?mir::detail::ServerAddConfigurationOptions; | ||
687 | 595 | typeinfo?for?mir::DisplayServer; | 630 | typeinfo?for?mir::DisplayServer; |
688 | 596 | typeinfo?for?mir::EmergencyCleanup; | 631 | typeinfo?for?mir::EmergencyCleanup; |
689 | 597 | typeinfo?for?mir::frontend::DisplayChanger; | 632 | typeinfo?for?mir::frontend::DisplayChanger; |
690 | @@ -633,6 +668,7 @@ | |||
691 | 633 | typeinfo?for?mir::scene::SurfaceCoordinator; | 668 | typeinfo?for?mir::scene::SurfaceCoordinator; |
692 | 634 | typeinfo?for?mir::scene::SurfaceCreationParameters; | 669 | typeinfo?for?mir::scene::SurfaceCreationParameters; |
693 | 635 | typeinfo?for?mir::scene::SurfaceObserver; | 670 | typeinfo?for?mir::scene::SurfaceObserver; |
694 | 671 | typeinfo?for?mir::Server; | ||
695 | 636 | typeinfo?for?mir::ServerActionQueue; | 672 | typeinfo?for?mir::ServerActionQueue; |
696 | 637 | typeinfo?for?mir::ServerConfiguration; | 673 | typeinfo?for?mir::ServerConfiguration; |
697 | 638 | typeinfo?for?mir::ServerStatusListener; | 674 | typeinfo?for?mir::ServerStatusListener; |
698 | @@ -649,6 +685,7 @@ | |||
699 | 649 | vtable?for?mir::compositor::Scene; | 685 | vtable?for?mir::compositor::Scene; |
700 | 650 | vtable?for?mir::compositor::SceneElement; | 686 | vtable?for?mir::compositor::SceneElement; |
701 | 651 | vtable?for?mir::DefaultServerConfiguration; | 687 | vtable?for?mir::DefaultServerConfiguration; |
702 | 688 | vtable?for?mir::detail::ServerAddConfigurationOptions; | ||
703 | 652 | vtable?for?mir::DisplayServer; | 689 | vtable?for?mir::DisplayServer; |
704 | 653 | vtable?for?mir::EmergencyCleanup; | 690 | vtable?for?mir::EmergencyCleanup; |
705 | 654 | vtable?for?mir::frontend::DisplayChanger; | 691 | vtable?for?mir::frontend::DisplayChanger; |
706 | @@ -690,6 +727,7 @@ | |||
707 | 690 | vtable?for?mir::scene::SurfaceCoordinator; | 727 | vtable?for?mir::scene::SurfaceCoordinator; |
708 | 691 | vtable?for?mir::scene::SurfaceCreationParameters; | 728 | vtable?for?mir::scene::SurfaceCreationParameters; |
709 | 692 | vtable?for?mir::scene::SurfaceObserver; | 729 | vtable?for?mir::scene::SurfaceObserver; |
710 | 730 | vtable?for?mir::Server; | ||
711 | 693 | vtable?for?mir::ServerActionQueue; | 731 | vtable?for?mir::ServerActionQueue; |
712 | 694 | vtable?for?mir::ServerConfiguration; | 732 | vtable?for?mir::ServerConfiguration; |
713 | 695 | vtable?for?mir::ServerStatusListener; | 733 | vtable?for?mir::ServerStatusListener; |
PASSED: Continuous integration, rev:1972 jenkins. qa.ubuntu. com/job/ mir-ci/ 1788/ jenkins. qa.ubuntu. com/job/ mir-android- utopic- i386-build/ 2089 jenkins. qa.ubuntu. com/job/ mir-clang- utopic- amd64-build/ 2096 jenkins. qa.ubuntu. com/job/ mir-mediumtests -utopic- touch/2025 jenkins. qa.ubuntu. com/job/ mir-utopic- amd64-ci/ 126 jenkins. qa.ubuntu. com/job/ mir-utopic- amd64-ci/ 126/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- utopic- armhf/962 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- utopic- armhf/962/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -runner- mako/3033 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 14538
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/1788/ rebuild
http://