Merge lp:~vanvugt/mir/surface-types into lp:~mir-team/mir/trunk
- surface-types
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Daniel van Vugt |
Approved revision: | no longer in the source branch. |
Merged at revision: | 526 |
Proposed branch: | lp:~vanvugt/mir/surface-types |
Merge into: | lp:~mir-team/mir/trunk |
Diff against target: |
854 lines (+460/-1) 30 files modified
debian/control (+12/-0) debian/mircommon-dev.install (+1/-0) include/client/mir_toolkit/mir_client_library.h (+19/-0) include/server/mir/frontend/session.h (+3/-0) include/server/mir/frontend/session_mediator.h (+5/-0) include/server/mir/frontend/session_mediator_report.h (+4/-0) include/server/mir/frontend/surface.h (+3/-0) include/server/mir/logging/session_mediator_report.h (+2/-0) include/server/mir/shell/application_session.h (+2/-0) include/shared/mir_toolkit/common.h (+49/-0) include/test/mir_test_doubles/mock_session.h (+2/-0) include/test/mir_test_doubles/mock_surface.h (+2/-0) include/test/mir_test_doubles/stub_session.h (+4/-0) include/test/mir_test_doubles/stub_surface.h (+5/-0) src/client/mir_client_library.cpp (+22/-0) src/client/mir_surface.cpp (+47/-0) src/client/mir_surface.h (+11/-0) src/server/frontend/null_session_mediator_report.cpp (+4/-0) src/server/frontend/protobuf_message_processor.cpp (+4/-0) src/server/frontend/session_mediator.cpp (+27/-0) src/server/logging/session_mediator_report.cpp (+5/-0) src/server/shell/application_session.cpp (+10/-0) src/server/shell/surface.cpp (+45/-1) src/server/shell/surface.h (+8/-0) src/shared/CMakeLists.txt (+10/-0) src/shared/protobuf/mir_protobuf.proto (+10/-0) tests/acceptance-tests/test_client_library.cpp (+74/-0) tests/integration-tests/cucumber/test_session_management_context.cpp (+2/-0) tests/unit-tests/client/test_client_mir_surface.cpp (+20/-0) tests/unit-tests/shell/test_surface.cpp (+48/-0) |
To merge this branch: | bzr merge lp:~vanvugt/mir/surface-types |
Related bugs: | |
Related blueprints: |
Mir on the Phone (iteration 0)
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Robert Carr (community) | Needs Fixing | ||
Alan Griffiths | Approve | ||
Robert Ancell | Approve | ||
Review via email: mp+154261@code.launchpad.net |
This proposal supersedes a proposal from 2013-03-15.
Commit message
Add support for surface types (client API, protocol and server).
This work will also form the foundation of supporting surface states.
Description of the change
Fixed conflicts from nightly upstream landings. Also moved type out of surfaces::Surface and into shell::Surface.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
I don't think that surfaces::Surface needs configure(
~~~~
90 +
Trailing whitespace.
~~~~
216 === added file 'include/
This is not the place for parts of the toolkit API - this is for namespace mir
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
Is there a clear distinction between SurfaceSetting and SurfaceParameters? (And is it worth supplying SurfaceSetting to create_surface and avoiding a round-trip?)
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
the new surface type get/set for client api looks ok to me
The acceptance test takes quite a while on the galaxy nexus, perhaps it can be shortened by using less iterations in line 757?
[ RUN ] DefaultDisplayS
[ OK ] DefaultDisplayS
(i see about 180ms on my desktop)
small nit but with
615 +int ms::Surface:
the name 'configure' didn't make it obvious what is going on in the function.
Also with this function, (related to the comment in it) is the surface type something that mir cares about, or the shell? This is tricky to talk about without a 'shell api', but its still a bit hazy to me what our requirements for tracking the data that the shell cares about.
although the tests look good, they do have multiple testing expectations in them because they are long.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Alan,
Extraneous "configure" methods:
I only added methods where I absolutely needed to, to make the code compile and run. However that was many revisions ago so I'll check to see if it's still required...
Trailing whitespace at line 90:
Will fix now.
216 === added file 'include/
"common.h" is not part of the "toolkit". It is used by the client toolkit and in the server.
SurfaceSetting vs SurfaceParameters
Yes they will always be different. SurfaceParameters are required information to create a surface. SurfaceSetting is something you might optionally change later; like type, state, hidden, width, height (most of which are not implemented yet but require this branch to land first).
Kevin,
Stress test takes too long:
I think 1.3 seconds is OK for a stress test, but I can shorten it if you really want.
"configure" is not self explanatory:
I kind of agree but have not yet thought of a better method name other than "set_attribute" (making the protocol call something like "set_surface_
Who cares about surface type?...
You're absolutely right that surface type is something only the shell will care about and act upon. However for consistency between different shells and avoiding duplication, it is reasonable for the server to store the type value in each server surface instance. Even though it will only be used by the shell. This will change as new attributes are added like "state" which will potentially be used by the server directly.
Test length:
Yes, I will always make code as concise as possible without hurting readability.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:557
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Minor fixes done.
Alan -
I can put "common.h" anywhere of course. Just remember:
1. It's not part of the "toolkit". "toolkit" means client-only but "common.h" is also used in the server and shell.
2. common.h has to be installed under "include/mir/..." to make it clear to external users that it's part of mir. And it is implicitly in the "mir" namespace by virtue of the "Mir" type prefixes. We can't use "namespace mir" however because it is C code, not C++.
Alan & Kevin -
I agree that "type" is not a deep server-level attribute. It only makes sense at the shell level. I could move it out of surfaces::Surface now, and into a proxy class. However I think that should be done later because the "Proxy" classes clearly need some refactoring, everyone seems to agree. I'd rather not make assumptions about what form that will take and move any members into *ProxySurface until that's done.
Also keep in mind that _most_ future configurable attributes (state, hidden, width, height etc) will be low-level and live in the server surfaces::Surface rather than the shell.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:558
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> Minor fixes done.
>
> Alan -
> I can put "common.h" anywhere of course. Just remember:
> 1. It's not part of the "toolkit". "toolkit" means client-only but
> "common.h" is also used in the server and shell.
> 2. common.h has to be installed under "include/mir/..." to make it clear to
> external users that it's part of mir. And it is implicitly in the "mir"
> namespace by virtue of the "Mir" type prefixes. We can't use "namespace mir"
> however because it is C code, not C++.
As it is included by toolkit I think it is part of toolkit. If it were really "part of mir", then there would be no reason for it to be C code. (Is it part of some hypothetical "common" that we've just identified - if so, is "common.h" isn't a good name.)
> Alan & Kevin -
> I agree that "type" is not a deep server-level attribute. It only makes sense
> at the shell level. I could move it out of surfaces::Surface now, and into a
> proxy class. However I think that should be done later because the "Proxy"
> classes clearly need some refactoring, everyone seems to agree. I'd rather not
> make assumptions about what form that will take and move any members into
> *ProxySurface until that's done.
Perhaps it is best to wait on that refactoring and reassess after that?
> Also keep in mind that _most_ future configurable attributes (state, hidden,
> width, height etc) will be low-level and live in the server surfaces::Surface
> rather than the shell.
Are you envisaging using the same mechanism?
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Absolutely, all attributes that can be changed after construction will use configure() eventually.
Please consider landing this branch before any ProxySurface refactoring. I am tired of fixing conflicts and refactoring it every day.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Also, these arguments are blocking me from starting on two other deliverables which will depend on this work.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> Absolutely, all attributes that can be changed after construction will use
> configure() eventually.
Does that imply that e.g. you see resizing happening by setting the width and height in two configure calls? I'm not sure that is a good plan.
Why wouldn't there be a single resize(
> Please consider landing this branch before any ProxySurface refactoring. I am
> tired of fixing conflicts and refactoring it every day.
I'm equally tired of reviewing it every day - there has to be a better way to communicate.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Good point. Width/height are bad examples. But I will reuse configure() for surface states soon.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I tried moving common.h to: include/
But that fails for reasons alluded to earlier. That is such common headers need to have the same relative path in the source tree as in the install tree. Because mir_client_
Any suggestions?
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> I tried moving common.h to: include/
> But that fails for reasons alluded to earlier. That is such common headers
> need to have the same relative path in the source tree as in the install tree.
> Because mir_client_
> situations.
>
> Any suggestions?
I guess this comes as part of the various problems with directory names.
IMO include/
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
>
> I guess this comes as part of the various problems with directory names.
>
> IMO include/
> installed to <target>
> <mir_toolkit/
+1
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal | # |
== include/shared/mir vs include/
The concept is that whatever is under */mir_toolkit (and only that) will be part of the toolkit interface. Since a toolkit/client needs this, mir_toolkit is the way to go. Keep in mind that this is still under shared/.
So, this is how I see things currently:
1. server/*, client/*, shared/* => which mir components need to access the definitions in the file
2. */mir, */mir_toolkit => whether the definitions are internal to mir, or (also) exposed to the toolkit API
== surfaces:
I agree that this doesn't belong there. I don't have a problem putting it there *temporarily* to unblock work, if the related surface refactorings aren't expected to be done soon.
== configure() ==
At the Surface level, and for the limited number of attributes I am aware of, I would prefer to have explicit calls : app_session-
At the RPC level: one approach is to use configure(attrib, value), another is to have <attrib>(value) calls. A third approach (not neccessarily preferable for this use case, just mentioning it for completeness) is to have, e.g.:
message SurfaceSettings {
optional SurfaceId surfaceid = 1;
optional int32 type = 2;
optional int32 state = 3;
optional bool visible = 4;
...
}
The frontend could then act depending on which values are actually included in the message. This method allows the client to set and retrieve all of the settings in one go.
For the number of attributes and the use cases I am aware of, my preference would be once again to be explicit, and have separate calls <attrib>().
Marking as "Needs information" => "Needs discussion"
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I thought it was implicit that having two different top-level include directories:
<mir/foo>
<mir_toolkit/bar>
was obviously a bad idea. I thought that was obvious but clearly it's just my opinion now. I think eventually everything should be under "mir/" for consistency:
<mir/foo>
<mir/toolkit/bar>
But that's a cleanup for a another day and a different proposal.
Alexandros:
configure() needs to be generic because there are so many layers of classes in the Mir code, it does not scale to add a new function for every attribute at every layer. When I added configure() I was surprised at how many classes I had to modify. It becomes unmaintainable and excessively over-complicated if you have to do that again and again for each new attribute. Consider also reporting -- we don't want to change every type of report to add new methods to those every time a new attribute is added.
Also, we should not assume to have designed all the required attributes any time soon. New attributes will be added and some even removed over time. We don't want to go changing the protocol and half a dozen foundational classes each time.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I've now been working on this branch for a month and it's been under review for two weeks. It has worked perfectly without bugs for the entire duration. Remember we're only arguing about style issues that can be fixed later.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:563
http://
Executed test runs:
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
8 +Package: mircommon-dev
I don't think this is right as it stands - but that is probably part of a pre-existing problem with the install packages and directory structure.
We need to be able to install the client process toolkit headers. (shared/
We need to be able to install the server process toolkit headers. (shared/
We need to be able to install for building against the library headers. (shared/mir/* + server/mir/* + shared/
I don't have a better proposal to hand, but something needs fixing.
~~~~
As I've said before I don't think that surfaces::Surface needs configure(
But I guess we can delete it a few minutes after it lands.
Robert Ancell (robert-ancell) wrote : Posted in a previous version of this proposal | # |
I'm unsure about why we have mircommon, but that can be solved outside of this.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
I might be able to install "common.h" twice; for client and server. Thus eliminating the mircommon-dev package. If you want me to give it a go?.. But there's obviously redundancy doing that.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:565
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
I think we need a discussion about the different user code targets we want to support and organizing headers to support them. But this MP isn't the place for it.
I'd still prefer not putting attributes that belong on shell::Surface onto surface::Surface.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Work in progress again. As happens every day, there are conflicts from upstream I need to resolve.
I will also re-visit the shell::Surface discussion now that shell::Surface actually exists.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:573
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
I'm not sure if these are consistent:
316 + // I assume the type can only change from the client side. Otherwise
317 + // we would have to send off a message to retrieve the latest...
...
619 + bool set_type(
This is a public member function - that suggest that it could, potentially, be called other than as the result of a call from a client process.
Also, given the expectation of using a graphics toolkit within the server process is "client side" the right terminology?
Alan Griffiths (alan-griffiths) wrote : | # |
820 + EXPECT_
821 + mir_surface_
822 + mir_surface_
Expected and actual reversed
Daniel van Vugt (vanvugt) wrote : | # |
Alan's concerns addressed.
And if you want to be that pedantic about gtest syntax, see bug 1149157.
Robert Ancell (robert-ancell) : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:578
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
> Alan's concerns addressed.
>
> And if you want to be that pedantic about gtest syntax, see bug 1149157.
My "concern" is about getting clear output from a test failure.
If I wanted to be pedantic I'd "Need Fixing" the tests that don't test a single thing described by the test name.
Robert Carr (robertcarr) wrote : | # |
Looks good! excited to get surface attributes in.
Some minor style nits:
>>+/**
>>+ * Set the type (purpose) of a surface. This is not guaranteed to always work
>>+ * with some shell types (e.g. phone/tablet UIs). As such, you may have to
>>+ * wait on the function and check the result using mir_surface_
>>+ * \param [in] surface The surface to operate on
>>+ * \param [in] type The new type of the surface
>>+ * \return A wait handle that can be passed to mir_wait_for
>>+ */
Only nitting here because it's public header. I found this a little confusing to read (i.e. mention of phone/tablet is a little distracting). I would write it like this:
"Set the type (role) of a surface. Success of this operation is dependent on server policy. As such, you may have to wait on the function and check the result using mir_suface_
>>+ mir_surface_
Do we do this elsewhere (trailing underscore), should we?
>> 427:
I find the continuous mention in comments and the variable attrib_cache of "cache" confusing. In this sense of the word cache, mir_toolkit:
Robert Carr (robertcarr) wrote : | # |
>> 477:
I can't find the test for this
Robert Carr (robertcarr) wrote : | # |
>> 305:
Whitespace
>> 821:
This would be more in line with the rest of the code style if there were a few tests:
TEST_F(
TEST_F(
TEST_F(
This would improve the failure output significantly I think
Daniel van Vugt (vanvugt) wrote : | # |
racarr,
comment confusion: Yeah easy to fix, later.
mir_surface_
427: Comments can be clarified. But not worth a reproposal.
477: The test for the whole configure_surface stack is covered by:
TEST_F(
305: That indentation is no mistake. I moved it to stay within 80 columns.
821: I am adjusting my style to suit you guys. It won't happen over night but it is happening. I don't think this is a blocker.
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2013-03-12 03:50:42 +0000 |
3 | +++ debian/control 2013-03-21 04:05:24 +0000 |
4 | @@ -58,11 +58,22 @@ |
5 | . |
6 | Contains the shared library needed by server applications for Mir. |
7 | |
8 | +Package: mircommon-dev |
9 | +Section: libdevel |
10 | +Architecture: any |
11 | +Depends: ${misc:Depends}, |
12 | +Description: Display server for Ubuntu - development headers |
13 | + Mir is a display server running on linux systems, with a focus on efficiency, |
14 | + robust operation and a well-defined driver model. |
15 | + . |
16 | + Contains header files required for server and/or client development. |
17 | + |
18 | Package: libmirserver-dev |
19 | Section: libdevel |
20 | Architecture: any |
21 | Depends: libmirserver0 (= ${binary:Version}), |
22 | libmirprotobuf-dev (= ${source:Version}), |
23 | + mircommon-dev (= ${source:Version}), |
24 | ${misc:Depends}, |
25 | Description: Display server for Ubuntu - development headers |
26 | Mir is a display server running on linux systems, with a focus on efficiency, |
27 | @@ -86,6 +97,7 @@ |
28 | Architecture: any |
29 | Depends: libmirclient0 (= ${binary:Version}), |
30 | libmirprotobuf-dev (= ${source:Version}), |
31 | + mircommon-dev (= ${source:Version}), |
32 | ${misc:Depends}, |
33 | Description: Display server for Ubuntu - development headers |
34 | Mir is a display server running on linux systems, with a focus on efficiency, |
35 | |
36 | === added file 'debian/mircommon-dev.install' |
37 | --- debian/mircommon-dev.install 1970-01-01 00:00:00 +0000 |
38 | +++ debian/mircommon-dev.install 2013-03-21 04:05:24 +0000 |
39 | @@ -0,0 +1,1 @@ |
40 | +usr/include/mir_toolkit/*.h |
41 | |
42 | === modified file 'include/client/mir_toolkit/mir_client_library.h' |
43 | --- include/client/mir_toolkit/mir_client_library.h 2013-03-20 10:26:48 +0000 |
44 | +++ include/client/mir_toolkit/mir_client_library.h 2013-03-21 04:05:24 +0000 |
45 | @@ -18,6 +18,8 @@ |
46 | #ifndef MIR_CLIENT_LIBRARY_H |
47 | #define MIR_CLIENT_LIBRARY_H |
48 | |
49 | +#include <mir_toolkit/common.h> |
50 | + |
51 | #ifdef __cplusplus |
52 | /** The C client API |
53 | */ |
54 | @@ -358,6 +360,23 @@ |
55 | */ |
56 | int mir_debug_surface_id(MirSurface *surface); |
57 | |
58 | +/** |
59 | + * Set the type (purpose) of a surface. This is not guaranteed to always work |
60 | + * with some shell types (e.g. phone/tablet UIs). As such, you may have to |
61 | + * wait on the function and check the result using mir_surface_get_type. |
62 | + * \param [in] surface The surface to operate on |
63 | + * \param [in] type The new type of the surface |
64 | + * \return A wait handle that can be passed to mir_wait_for |
65 | + */ |
66 | +MirWaitHandle* mir_surface_set_type(MirSurface *surface, MirSurfaceType type); |
67 | + |
68 | +/** |
69 | + * Get the type (purpose) of a surface. |
70 | + * \param [in] surface The surface to query |
71 | + * \return The type of the surface |
72 | + */ |
73 | +MirSurfaceType mir_surface_get_type(MirSurface *surface); |
74 | + |
75 | #ifdef __cplusplus |
76 | } |
77 | } |
78 | |
79 | === modified file 'include/server/mir/frontend/session.h' |
80 | --- include/server/mir/frontend/session.h 2013-03-19 03:05:30 +0000 |
81 | +++ include/server/mir/frontend/session.h 2013-03-21 04:05:24 +0000 |
82 | @@ -19,6 +19,7 @@ |
83 | #ifndef MIR_FRONTEND_SESSION_H_ |
84 | #define MIR_FRONTEND_SESSION_H_ |
85 | |
86 | +#include "mir_toolkit/common.h" |
87 | #include "mir/frontend/surface_id.h" |
88 | |
89 | #include <mutex> |
90 | @@ -49,6 +50,8 @@ |
91 | virtual void hide() = 0; |
92 | virtual void show() = 0; |
93 | |
94 | + virtual int configure_surface(SurfaceId id, MirSurfaceAttrib attrib, int value) = 0; |
95 | + |
96 | protected: |
97 | Session() = default; |
98 | Session(Session const&) = delete; |
99 | |
100 | === modified file 'include/server/mir/frontend/session_mediator.h' |
101 | --- include/server/mir/frontend/session_mediator.h 2013-03-19 03:05:30 +0000 |
102 | +++ include/server/mir/frontend/session_mediator.h 2013-03-21 04:05:24 +0000 |
103 | @@ -100,6 +100,11 @@ |
104 | mir::protobuf::DRMAuthMagicStatus* response, |
105 | google::protobuf::Closure* done); |
106 | |
107 | + void configure_surface(google::protobuf::RpcController* controller, |
108 | + const mir::protobuf::SurfaceSetting*, |
109 | + mir::protobuf::SurfaceSetting*, |
110 | + google::protobuf::Closure* done); |
111 | + |
112 | private: |
113 | std::shared_ptr<Shell> const shell; |
114 | std::shared_ptr<graphics::Platform> const graphics_platform; |
115 | |
116 | === modified file 'include/server/mir/frontend/session_mediator_report.h' |
117 | --- include/server/mir/frontend/session_mediator_report.h 2013-03-19 03:05:30 +0000 |
118 | +++ include/server/mir/frontend/session_mediator_report.h 2013-03-21 04:05:24 +0000 |
119 | @@ -42,6 +42,8 @@ |
120 | |
121 | virtual void session_drm_auth_magic_called(std::string const& app_name) = 0; |
122 | |
123 | + virtual void session_configure_surface_called(std::string const& app_name) = 0; |
124 | + |
125 | virtual void session_error( |
126 | std::string const& app_name, |
127 | char const* method, |
128 | @@ -63,6 +65,8 @@ |
129 | |
130 | virtual void session_drm_auth_magic_called(std::string const& app_name); |
131 | |
132 | + virtual void session_configure_surface_called(std::string const& app_name); |
133 | + |
134 | virtual void session_error( |
135 | std::string const& app_name, |
136 | char const* method, |
137 | |
138 | === modified file 'include/server/mir/frontend/surface.h' |
139 | --- include/server/mir/frontend/surface.h 2013-03-20 10:56:07 +0000 |
140 | +++ include/server/mir/frontend/surface.h 2013-03-21 04:05:24 +0000 |
141 | @@ -23,6 +23,7 @@ |
142 | #include "mir/geometry/pixel_format.h" |
143 | #include "mir/geometry/point.h" |
144 | #include "mir/geometry/size.h" |
145 | +#include "mir_toolkit/common.h" |
146 | |
147 | #include <memory> |
148 | |
149 | @@ -60,6 +61,8 @@ |
150 | virtual bool supports_input() const = 0; |
151 | virtual int client_input_fd() const = 0; |
152 | |
153 | + virtual int configure(MirSurfaceAttrib attrib, int value) = 0; |
154 | + |
155 | protected: |
156 | Surface() = default; |
157 | Surface(Surface const&) = delete; |
158 | |
159 | === modified file 'include/server/mir/logging/session_mediator_report.h' |
160 | --- include/server/mir/logging/session_mediator_report.h 2013-03-19 03:05:30 +0000 |
161 | +++ include/server/mir/logging/session_mediator_report.h 2013-03-21 04:05:24 +0000 |
162 | @@ -47,6 +47,8 @@ |
163 | |
164 | virtual void session_drm_auth_magic_called(std::string const& app_name); |
165 | |
166 | + virtual void session_configure_surface_called(std::string const& app_name); |
167 | + |
168 | virtual void session_error( |
169 | std::string const& app_name, |
170 | char const* method, |
171 | |
172 | === modified file 'include/server/mir/shell/application_session.h' |
173 | --- include/server/mir/shell/application_session.h 2013-03-20 10:56:07 +0000 |
174 | +++ include/server/mir/shell/application_session.h 2013-03-21 04:05:24 +0000 |
175 | @@ -47,6 +47,8 @@ |
176 | void hide(); |
177 | void show(); |
178 | |
179 | + int configure_surface(frontend::SurfaceId id, MirSurfaceAttrib attrib, int value); |
180 | + |
181 | protected: |
182 | ApplicationSession(ApplicationSession const&) = delete; |
183 | ApplicationSession& operator=(ApplicationSession const&) = delete; |
184 | |
185 | === added file 'include/shared/mir_toolkit/common.h' |
186 | --- include/shared/mir_toolkit/common.h 1970-01-01 00:00:00 +0000 |
187 | +++ include/shared/mir_toolkit/common.h 2013-03-21 04:05:24 +0000 |
188 | @@ -0,0 +1,49 @@ |
189 | +/* |
190 | + * Simple definitions common to client and server. |
191 | + * |
192 | + * Copyright © 2013 Canonical Ltd. |
193 | + * |
194 | + * This program is free software: you can redistribute it and/or modify |
195 | + * it under the terms of the GNU Lesser General Public License version 3 as |
196 | + * published by the Free Software Foundation. |
197 | + * |
198 | + * This program is distributed in the hope that it will be useful, |
199 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
200 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
201 | + * GNU Lesser General Public License for more details. |
202 | + * |
203 | + * You should have received a copy of the GNU Lesser General Public License |
204 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
205 | + * |
206 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
207 | + */ |
208 | + |
209 | +#ifndef MIR_COMMON_H_ |
210 | +#define MIR_COMMON_H_ |
211 | + |
212 | +/* This is C code. Not C++. */ |
213 | + |
214 | +/* |
215 | + * Attributes of a surface that the client and server/shell may wish to |
216 | + * get or set over the wire. |
217 | + */ |
218 | +typedef enum MirSurfaceAttrib |
219 | +{ |
220 | + mir_surface_attrib_type, |
221 | + mir_surface_attrib_arraysize_ |
222 | +} MirSurfaceAttrib; |
223 | + |
224 | +typedef enum MirSurfaceType |
225 | +{ |
226 | + mir_surface_type_normal, |
227 | + mir_surface_type_utility, |
228 | + mir_surface_type_dialog, |
229 | + mir_surface_type_overlay, |
230 | + mir_surface_type_freestyle, |
231 | + mir_surface_type_popover, |
232 | + mir_surface_type_arraysize_ |
233 | +} MirSurfaceType; |
234 | + |
235 | +/* TODO: Surface states here */ |
236 | + |
237 | +#endif |
238 | |
239 | === modified file 'include/test/mir_test_doubles/mock_session.h' |
240 | --- include/test/mir_test_doubles/mock_session.h 2013-03-19 03:05:30 +0000 |
241 | +++ include/test/mir_test_doubles/mock_session.h 2013-03-21 04:05:24 +0000 |
242 | @@ -41,6 +41,8 @@ |
243 | |
244 | MOCK_METHOD0(hide, void()); |
245 | MOCK_METHOD0(show, void()); |
246 | + |
247 | + MOCK_METHOD3(configure_surface, int(frontend::SurfaceId, MirSurfaceAttrib, int)); |
248 | }; |
249 | |
250 | } |
251 | |
252 | === modified file 'include/test/mir_test_doubles/mock_surface.h' |
253 | --- include/test/mir_test_doubles/mock_surface.h 2013-03-20 10:56:07 +0000 |
254 | +++ include/test/mir_test_doubles/mock_surface.h 2013-03-21 04:05:24 +0000 |
255 | @@ -49,6 +49,8 @@ |
256 | |
257 | MOCK_CONST_METHOD0(supports_input, bool()); |
258 | MOCK_CONST_METHOD0(client_input_fd, int()); |
259 | + |
260 | + MOCK_METHOD2(configure, int(MirSurfaceAttrib, int)); |
261 | }; |
262 | |
263 | } |
264 | |
265 | === modified file 'include/test/mir_test_doubles/stub_session.h' |
266 | --- include/test/mir_test_doubles/stub_session.h 2013-03-19 03:05:30 +0000 |
267 | +++ include/test/mir_test_doubles/stub_session.h 2013-03-21 04:05:24 +0000 |
268 | @@ -54,6 +54,10 @@ |
269 | void show() |
270 | { |
271 | } |
272 | + int configure_surface(frontend::SurfaceId, MirSurfaceAttrib, int) |
273 | + { |
274 | + return 0; |
275 | + } |
276 | }; |
277 | |
278 | } |
279 | |
280 | === modified file 'include/test/mir_test_doubles/stub_surface.h' |
281 | --- include/test/mir_test_doubles/stub_surface.h 2013-03-18 15:43:58 +0000 |
282 | +++ include/test/mir_test_doubles/stub_surface.h 2013-03-21 04:05:24 +0000 |
283 | @@ -53,6 +53,11 @@ |
284 | { |
285 | return std::shared_ptr<compositor::Buffer>(); |
286 | } |
287 | + |
288 | + virtual int configure(MirSurfaceAttrib, int) |
289 | + { |
290 | + return 0; |
291 | + } |
292 | |
293 | virtual bool supports_input() const |
294 | { |
295 | |
296 | === modified file 'src/client/mir_client_library.cpp' |
297 | --- src/client/mir_client_library.cpp 2013-03-20 05:11:57 +0000 |
298 | +++ src/client/mir_client_library.cpp 2013-03-21 04:05:24 +0000 |
299 | @@ -272,3 +272,25 @@ |
300 | { |
301 | // Ignore |
302 | } |
303 | + |
304 | +mir_toolkit::MirWaitHandle* mir_toolkit::mir_surface_set_type(MirSurface *surf, |
305 | + MirSurfaceType type) |
306 | +{ |
307 | + return surf ? surf->configure(mir_surface_attrib_type, type) : NULL; |
308 | +} |
309 | + |
310 | +MirSurfaceType mir_toolkit::mir_surface_get_type(MirSurface *surf) |
311 | +{ |
312 | + MirSurfaceType type = mir_surface_type_normal; |
313 | + |
314 | + if (surf) |
315 | + { |
316 | + // Only the client will ever change the type of a surface so it is |
317 | + // safe to get the type from a local cache surf->attrib(). |
318 | + |
319 | + int t = surf->attrib(mir_surface_attrib_type); |
320 | + type = static_cast<MirSurfaceType>(t); |
321 | + } |
322 | + |
323 | + return type; |
324 | +} |
325 | |
326 | === modified file 'src/client/mir_surface.cpp' |
327 | --- src/client/mir_surface.cpp 2013-03-07 08:04:05 +0000 |
328 | +++ src/client/mir_surface.cpp 2013-03-21 04:05:24 +0000 |
329 | @@ -50,6 +50,10 @@ |
330 | message.set_buffer_usage(params.buffer_usage); |
331 | |
332 | server.create_surface(0, &message, &surface, gp::NewCallback(this, &MirSurface::created, callback, context)); |
333 | + |
334 | + for (int i = 0; i < mir_surface_attrib_arraysize_; i++) |
335 | + attrib_cache[i] = -1; |
336 | + attrib_cache[mir_surface_attrib_type] = mir_surface_type_normal; |
337 | } |
338 | |
339 | mir_toolkit::MirSurface::~MirSurface() |
340 | @@ -226,3 +230,46 @@ |
341 | { |
342 | return *accelerated_window; |
343 | } |
344 | + |
345 | +MirWaitHandle* MirSurface::configure(MirSurfaceAttrib at, int value) |
346 | +{ |
347 | + mp::SurfaceSetting setting; |
348 | + setting.mutable_surfaceid()->CopyFrom(surface.id()); |
349 | + setting.set_attrib(at); |
350 | + setting.set_ivalue(value); |
351 | + |
352 | + configure_wait_handle.expect_result(); |
353 | + server.configure_surface(0, &setting, &configure_result, |
354 | + google::protobuf::NewCallback(this, &MirSurface::on_configured)); |
355 | + |
356 | + return &configure_wait_handle; |
357 | +} |
358 | + |
359 | +void MirSurface::on_configured() |
360 | +{ |
361 | + if (configure_result.has_surfaceid() && |
362 | + configure_result.surfaceid().value() == surface.id().value() && |
363 | + configure_result.has_attrib()) |
364 | + { |
365 | + switch (configure_result.attrib()) |
366 | + { |
367 | + case mir_surface_attrib_type: |
368 | + if (configure_result.has_ivalue()) |
369 | + { |
370 | + int t = configure_result.ivalue(); |
371 | + attrib_cache[mir_surface_attrib_type] = t; |
372 | + } // else error is probably set due to an unsupported attrib/value |
373 | + break; |
374 | + default: |
375 | + assert(false); |
376 | + break; |
377 | + } |
378 | + |
379 | + configure_wait_handle.result_received(); |
380 | + } |
381 | +} |
382 | + |
383 | +int MirSurface::attrib(MirSurfaceAttrib at) const |
384 | +{ |
385 | + return attrib_cache[at]; |
386 | +} |
387 | |
388 | === modified file 'src/client/mir_surface.h' |
389 | --- src/client/mir_surface.h 2013-03-15 07:40:59 +0000 |
390 | +++ src/client/mir_surface.h 2013-03-21 04:05:24 +0000 |
391 | @@ -23,6 +23,7 @@ |
392 | #include "mir/geometry/pixel_format.h" |
393 | #include "mir/geometry/dimensions.h" |
394 | #include "mir_toolkit/mir_client_library.h" |
395 | +#include "mir_toolkit/common.h" |
396 | #include "client_buffer_depository.h" |
397 | #include "mir_wait_handle.h" |
398 | #include "mir_client_surface.h" |
399 | @@ -72,7 +73,11 @@ |
400 | void release_cpu_region(); |
401 | EGLNativeWindowType generate_native_window(); |
402 | |
403 | + MirWaitHandle* configure(MirSurfaceAttrib a, int value); |
404 | + int attrib(MirSurfaceAttrib a) const; |
405 | + |
406 | private: |
407 | + void on_configured(); |
408 | void process_incoming_buffer(); |
409 | void populate(MirBufferPackage& buffer_package); |
410 | void created(mir_surface_lifecycle_callback callback, void * context); |
411 | @@ -88,6 +93,7 @@ |
412 | MirConnection *connection; |
413 | MirWaitHandle create_wait_handle; |
414 | MirWaitHandle next_buffer_wait_handle; |
415 | + MirWaitHandle configure_wait_handle; |
416 | |
417 | int last_buffer_id; |
418 | |
419 | @@ -96,6 +102,11 @@ |
420 | |
421 | std::shared_ptr<mir::client::Logger> logger; |
422 | std::shared_ptr<EGLNativeWindowType> accelerated_window; |
423 | + |
424 | + mir::protobuf::SurfaceSetting configure_result; |
425 | + |
426 | + // Cache of latest SurfaceSettings returned from the server |
427 | + int attrib_cache[mir_surface_attrib_arraysize_]; |
428 | }; |
429 | |
430 | #endif /* MIR_CLIENT_PRIVATE_MIR_WAIT_HANDLE_H_ */ |
431 | |
432 | === modified file 'src/server/frontend/null_session_mediator_report.cpp' |
433 | --- src/server/frontend/null_session_mediator_report.cpp 2013-03-19 03:05:30 +0000 |
434 | +++ src/server/frontend/null_session_mediator_report.cpp 2013-03-21 04:05:24 +0000 |
435 | @@ -42,6 +42,10 @@ |
436 | { |
437 | } |
438 | |
439 | +void mir::frontend::NullSessionMediatorReport::session_configure_surface_called(std::string const&) |
440 | +{ |
441 | +} |
442 | + |
443 | void mir::frontend::NullSessionMediatorReport::session_error( |
444 | std::string const&, |
445 | char const* , |
446 | |
447 | === modified file 'src/server/frontend/protobuf_message_processor.cpp' |
448 | --- src/server/frontend/protobuf_message_processor.cpp 2013-03-07 08:04:05 +0000 |
449 | +++ src/server/frontend/protobuf_message_processor.cpp 2013-03-21 04:05:24 +0000 |
450 | @@ -176,6 +176,10 @@ |
451 | { |
452 | invoke(&protobuf::DisplayServer::select_focus_by_lightdm_id, invocation); |
453 | } |
454 | + else if ("configure_surface" == invocation.method_name()) |
455 | + { |
456 | + invoke(&protobuf::DisplayServer::configure_surface, invocation); |
457 | + } |
458 | else if ("disconnect" == invocation.method_name()) |
459 | { |
460 | invoke(&protobuf::DisplayServer::disconnect, invocation); |
461 | |
462 | === modified file 'src/server/frontend/session_mediator.cpp' |
463 | --- src/server/frontend/session_mediator.cpp 2013-03-20 05:11:57 +0000 |
464 | +++ src/server/frontend/session_mediator.cpp 2013-03-21 04:05:24 +0000 |
465 | @@ -23,6 +23,7 @@ |
466 | #include "mir/frontend/surface.h" |
467 | #include "mir/frontend/surface_creation_parameters.h" |
468 | #include "mir/frontend/resource_cache.h" |
469 | +#include "mir_toolkit/common.h" |
470 | #include "mir/compositor/buffer_ipc_package.h" |
471 | #include "mir/compositor/buffer_id.h" |
472 | #include "mir/compositor/buffer.h" |
473 | @@ -220,3 +221,29 @@ |
474 | done->Run(); |
475 | } |
476 | |
477 | +void mir::frontend::SessionMediator::configure_surface( |
478 | + google::protobuf::RpcController*, // controller, |
479 | + const mir::protobuf::SurfaceSetting* request, |
480 | + mir::protobuf::SurfaceSetting* response, |
481 | + google::protobuf::Closure* done) |
482 | +{ |
483 | + MirSurfaceAttrib attrib = static_cast<MirSurfaceAttrib>(request->attrib()); |
484 | + |
485 | + // Required response fields: |
486 | + response->mutable_surfaceid()->CopyFrom(request->surfaceid()); |
487 | + response->set_attrib(attrib); |
488 | + |
489 | + if (session.get() == nullptr) |
490 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid application session")); |
491 | + |
492 | + report->session_configure_surface_called(session->name()); |
493 | + |
494 | + auto const id = frontend::SurfaceId(request->surfaceid().value()); |
495 | + int value = request->ivalue(); |
496 | + int newvalue = session->configure_surface(id, attrib, value); |
497 | + |
498 | + response->set_ivalue(newvalue); |
499 | + |
500 | + done->Run(); |
501 | +} |
502 | + |
503 | |
504 | === modified file 'src/server/logging/session_mediator_report.cpp' |
505 | --- src/server/logging/session_mediator_report.cpp 2013-03-19 03:05:30 +0000 |
506 | +++ src/server/logging/session_mediator_report.cpp 2013-03-21 04:05:24 +0000 |
507 | @@ -63,6 +63,11 @@ |
508 | log->log<Logger::informational>("session_drm_auth_magic_called(\"" + app_name + "\")", component); |
509 | } |
510 | |
511 | +void ml::SessionMediatorReport::session_configure_surface_called(std::string const& app_name) |
512 | +{ |
513 | + log->log<Logger::informational>("session_configure_surface_called(\"" + app_name + "\")", component); |
514 | +} |
515 | + |
516 | void ml::SessionMediatorReport::session_error( |
517 | std::string const& app_name, |
518 | char const* method, |
519 | |
520 | === modified file 'src/server/shell/application_session.cpp' |
521 | --- src/server/shell/application_session.cpp 2013-03-20 10:56:07 +0000 |
522 | +++ src/server/shell/application_session.cpp 2013-03-21 04:05:24 +0000 |
523 | @@ -122,3 +122,13 @@ |
524 | id_s.second->show(); |
525 | } |
526 | } |
527 | + |
528 | +int msh::ApplicationSession::configure_surface(mf::SurfaceId id, |
529 | + MirSurfaceAttrib attrib, |
530 | + int value) |
531 | +{ |
532 | + std::unique_lock<std::mutex> lock(surfaces_mutex); |
533 | + std::shared_ptr<mf::Surface> surf(checked_find(id)->second); |
534 | + |
535 | + return surf->configure(attrib, value); |
536 | +} |
537 | |
538 | === modified file 'src/server/shell/surface.cpp' |
539 | --- src/server/shell/surface.cpp 2013-03-19 03:05:30 +0000 |
540 | +++ src/server/shell/surface.cpp 2013-03-21 04:05:24 +0000 |
541 | @@ -35,7 +35,8 @@ |
542 | std::shared_ptr<input::InputChannel> const& input_channel) |
543 | : builder(builder), |
544 | input_channel(input_channel), |
545 | - surface(builder->create_surface(params)) |
546 | + surface(builder->create_surface(params)), |
547 | + type_value(mir_surface_type_normal) |
548 | { |
549 | } |
550 | |
551 | @@ -133,3 +134,46 @@ |
552 | BOOST_THROW_EXCEPTION(std::logic_error("Surface does not support input")); |
553 | return input_channel->client_fd(); |
554 | } |
555 | + |
556 | +int msh::Surface::configure(MirSurfaceAttrib attrib, int value) |
557 | +{ |
558 | + int result = 0; |
559 | + |
560 | + /* |
561 | + * TODO: In future, query the shell implementation for the subset of |
562 | + * attributes/types it implements. |
563 | + */ |
564 | + switch (attrib) |
565 | + { |
566 | + case mir_surface_attrib_type: |
567 | + if (!set_type(static_cast<MirSurfaceType>(value))) |
568 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface " |
569 | + "type.")); |
570 | + result = type(); |
571 | + break; |
572 | + default: |
573 | + BOOST_THROW_EXCEPTION(std::logic_error("Invalid surface " |
574 | + "attribute.")); |
575 | + break; |
576 | + } |
577 | + |
578 | + return result; |
579 | +} |
580 | + |
581 | +MirSurfaceType msh::Surface::type() const |
582 | +{ |
583 | + return type_value; |
584 | +} |
585 | + |
586 | +bool msh::Surface::set_type(MirSurfaceType t) |
587 | +{ |
588 | + bool valid = false; |
589 | + |
590 | + if (t >= 0 && t < mir_surface_type_arraysize_) |
591 | + { |
592 | + type_value = t; |
593 | + valid = true; |
594 | + } |
595 | + |
596 | + return valid; |
597 | +} |
598 | |
599 | === modified file 'src/server/shell/surface.h' |
600 | --- src/server/shell/surface.h 2013-03-20 10:56:07 +0000 |
601 | +++ src/server/shell/surface.h 2013-03-21 04:05:24 +0000 |
602 | @@ -22,6 +22,7 @@ |
603 | |
604 | #include "mir/frontend/surface.h" |
605 | #include "mir/surfaces/surface.h" |
606 | +#include "mir_toolkit/common.h" |
607 | |
608 | namespace mir |
609 | { |
610 | @@ -66,10 +67,17 @@ |
611 | virtual bool supports_input() const; |
612 | virtual int client_input_fd() const; |
613 | |
614 | + virtual int configure(MirSurfaceAttrib attrib, int value); |
615 | + virtual MirSurfaceType type() const; |
616 | + |
617 | private: |
618 | + bool set_type(MirSurfaceType t); // Use configure() to make public changes |
619 | + |
620 | std::shared_ptr<SurfaceBuilder> const builder; |
621 | std::shared_ptr<mir::input::InputChannel> const input_channel; |
622 | std::weak_ptr<mir::surfaces::Surface> const surface; |
623 | + |
624 | + MirSurfaceType type_value; |
625 | }; |
626 | } |
627 | } |
628 | |
629 | === modified file 'src/shared/CMakeLists.txt' |
630 | --- src/shared/CMakeLists.txt 2013-03-13 17:54:59 +0000 |
631 | +++ src/shared/CMakeLists.txt 2013-03-21 04:05:24 +0000 |
632 | @@ -5,3 +5,13 @@ |
633 | MIR_GENERATED_INCLUDE_DIRECTORIES |
634 | ${MIR_GENERATED_INCLUDE_DIRECTORIES} |
635 | PARENT_SCOPE) |
636 | + |
637 | +# Some headers contain common definitions required for both client and |
638 | +# server development... |
639 | +set (MIR_COMMON_HEADERS |
640 | + ${CMAKE_SOURCE_DIR}/include/shared/mir_toolkit/common.h |
641 | +) |
642 | + |
643 | +# TODO: Find a more elegant include/ structure. Ideally one in which everything |
644 | +# lives under "include/mir/". |
645 | +install (FILES ${MIR_COMMON_HEADERS} DESTINATION "include/mir_toolkit/") |
646 | |
647 | === modified file 'src/shared/protobuf/mir_protobuf.proto' |
648 | --- src/shared/protobuf/mir_protobuf.proto 2013-03-19 03:05:30 +0000 |
649 | +++ src/shared/protobuf/mir_protobuf.proto 2013-03-21 04:05:24 +0000 |
650 | @@ -114,6 +114,14 @@ |
651 | optional string error = 127; |
652 | } |
653 | |
654 | +message SurfaceSetting { |
655 | + optional SurfaceId surfaceid = 1; |
656 | + optional int32 attrib = 2; |
657 | + optional int32 ivalue = 3; |
658 | + // optional string svalue = 4; // Expected for future use |
659 | + optional string error = 127; |
660 | +} |
661 | + |
662 | service DisplayServer { |
663 | // Platform independent requests |
664 | rpc connect(ConnectParameters) returns (Connection); |
665 | @@ -127,5 +135,7 @@ |
666 | rpc drm_auth_magic(DRMMagic) returns (DRMAuthMagicStatus); |
667 | |
668 | rpc test_file_descriptors(Void) returns (Buffer); |
669 | + |
670 | + rpc configure_surface(SurfaceSetting) returns (SurfaceSetting); |
671 | } |
672 | |
673 | |
674 | === modified file 'tests/acceptance-tests/test_client_library.cpp' |
675 | --- tests/acceptance-tests/test_client_library.cpp 2013-03-20 05:11:57 +0000 |
676 | +++ tests/acceptance-tests/test_client_library.cpp 2013-03-21 04:05:24 +0000 |
677 | @@ -205,6 +205,80 @@ |
678 | launch_client_process(client_config); |
679 | } |
680 | |
681 | +TEST_F(DefaultDisplayServerTestFixture, surface_types) |
682 | +{ |
683 | + struct ClientConfig : ClientConfigCommon |
684 | + { |
685 | + void exec() |
686 | + { |
687 | + |
688 | + mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this)); |
689 | + |
690 | + ASSERT_TRUE(connection != NULL); |
691 | + EXPECT_TRUE(mir_connection_is_valid(connection)); |
692 | + EXPECT_STREQ(mir_connection_get_error_message(connection), ""); |
693 | + |
694 | + MirSurfaceParameters const request_params = |
695 | + { |
696 | + __PRETTY_FUNCTION__, |
697 | + 640, 480, |
698 | + mir_pixel_format_abgr_8888, |
699 | + mir_buffer_usage_hardware |
700 | + }; |
701 | + |
702 | + mir_wait_for(mir_surface_create(connection, &request_params, create_surface_callback, this)); |
703 | + |
704 | + ASSERT_TRUE(surface != NULL); |
705 | + EXPECT_TRUE(mir_surface_is_valid(surface)); |
706 | + EXPECT_STREQ(mir_surface_get_error_message(surface), ""); |
707 | + |
708 | + EXPECT_EQ(mir_surface_type_normal, |
709 | + mir_surface_get_type(surface)); |
710 | + |
711 | + mir_wait_for(mir_surface_set_type(surface, |
712 | + mir_surface_type_freestyle)); |
713 | + EXPECT_EQ(mir_surface_type_freestyle, |
714 | + mir_surface_get_type(surface)); |
715 | + |
716 | + mir_wait_for(mir_surface_set_type(surface, |
717 | + static_cast<MirSurfaceType>(999))); |
718 | + EXPECT_EQ(mir_surface_type_freestyle, |
719 | + mir_surface_get_type(surface)); |
720 | + |
721 | + mir_wait_for(mir_surface_set_type(surface, |
722 | + mir_surface_type_dialog)); |
723 | + EXPECT_EQ(mir_surface_type_dialog, |
724 | + mir_surface_get_type(surface)); |
725 | + |
726 | + mir_wait_for(mir_surface_set_type(surface, |
727 | + static_cast<MirSurfaceType>(888))); |
728 | + EXPECT_EQ(mir_surface_type_dialog, |
729 | + mir_surface_get_type(surface)); |
730 | + |
731 | + // Stress-test synchronization logic with some flooding |
732 | + for (int i = 0; i < 100; i++) |
733 | + { |
734 | + mir_surface_set_type(surface, mir_surface_type_normal); |
735 | + mir_surface_set_type(surface, mir_surface_type_utility); |
736 | + mir_surface_set_type(surface, mir_surface_type_dialog); |
737 | + mir_surface_set_type(surface, mir_surface_type_overlay); |
738 | + mir_surface_set_type(surface, mir_surface_type_freestyle); |
739 | + mir_wait_for(mir_surface_set_type(surface, |
740 | + mir_surface_type_popover)); |
741 | + ASSERT_EQ(mir_surface_type_popover, |
742 | + mir_surface_get_type(surface)); |
743 | + } |
744 | + |
745 | + mir_wait_for(mir_surface_release(surface, release_surface_callback, |
746 | + this)); |
747 | + |
748 | + mir_connection_release(connection); |
749 | + } |
750 | + } client_config; |
751 | + |
752 | + launch_client_process(client_config); |
753 | +} |
754 | + |
755 | TEST_F(DefaultDisplayServerTestFixture, client_library_creates_multiple_surfaces) |
756 | { |
757 | int const n_surfaces = 13; |
758 | |
759 | === modified file 'tests/integration-tests/cucumber/test_session_management_context.cpp' |
760 | --- tests/integration-tests/cucumber/test_session_management_context.cpp 2013-03-20 05:11:57 +0000 |
761 | +++ tests/integration-tests/cucumber/test_session_management_context.cpp 2013-03-21 04:05:24 +0000 |
762 | @@ -64,6 +64,8 @@ |
763 | MOCK_CONST_METHOD0(pixel_format, mir::geometry::PixelFormat ()); |
764 | MOCK_CONST_METHOD0(client_buffer, std::shared_ptr<mc::Buffer> ()); |
765 | |
766 | + MOCK_METHOD2(configure, int(MirSurfaceAttrib, int)); |
767 | + |
768 | MOCK_CONST_METHOD0(supports_input, bool()); |
769 | MOCK_CONST_METHOD0(client_input_fd, int()); |
770 | }; |
771 | |
772 | === modified file 'tests/unit-tests/client/test_client_mir_surface.cpp' |
773 | --- tests/unit-tests/client/test_client_mir_surface.cpp 2013-03-07 08:04:05 +0000 |
774 | +++ tests/unit-tests/client/test_client_mir_surface.cpp 2013-03-21 04:05:24 +0000 |
775 | @@ -376,3 +376,23 @@ |
776 | EXPECT_EQ(pf, geom::PixelFormat::abgr_8888); |
777 | } |
778 | |
779 | +TEST_F(MirClientSurfaceTest, default_surface_type) |
780 | +{ |
781 | + using namespace testing; |
782 | + using namespace mir::protobuf; |
783 | + |
784 | + EXPECT_CALL(*mock_depository, deposit_package_rv(_,_,_,_)) |
785 | + .Times(1); |
786 | + |
787 | + auto surface = std::make_shared<MirSurface> (connection.get(), |
788 | + *client_comm_channel, |
789 | + logger, |
790 | + mock_depository, |
791 | + params, |
792 | + &empty_callback, |
793 | + (void*) NULL); |
794 | + surface->get_create_wait_handle()->wait_for_result(); |
795 | + |
796 | + EXPECT_EQ(mir_surface_type_normal, |
797 | + surface->attrib(mir_surface_attrib_type)); |
798 | +} |
799 | |
800 | === modified file 'tests/unit-tests/shell/test_surface.cpp' |
801 | --- tests/unit-tests/shell/test_surface.cpp 2013-03-20 05:11:57 +0000 |
802 | +++ tests/unit-tests/shell/test_surface.cpp 2013-03-21 04:05:24 +0000 |
803 | @@ -307,3 +307,51 @@ |
804 | }, std::logic_error); |
805 | } |
806 | |
807 | +TEST_F(ShellSurface, attributes) |
808 | +{ |
809 | + using namespace testing; |
810 | + |
811 | + msh::Surface surf( |
812 | + mt::fake_shared(surface_builder), |
813 | + mf::a_surface(), |
814 | + null_input_channel); |
815 | + |
816 | + EXPECT_THROW({ |
817 | + surf.configure(static_cast<MirSurfaceAttrib>(111), 222); |
818 | + }, std::logic_error); |
819 | +} |
820 | + |
821 | +TEST_F(ShellSurface, types) |
822 | +{ |
823 | + using namespace testing; |
824 | + |
825 | + msh::Surface surf( |
826 | + mt::fake_shared(surface_builder), |
827 | + mf::a_surface(), |
828 | + null_input_channel); |
829 | + |
830 | + EXPECT_EQ(mir_surface_type_normal, surf.type()); |
831 | + |
832 | + EXPECT_EQ(mir_surface_type_utility, |
833 | + surf.configure(mir_surface_attrib_type, |
834 | + mir_surface_type_utility)); |
835 | + EXPECT_EQ(mir_surface_type_utility, surf.type()); |
836 | + |
837 | + EXPECT_THROW({ |
838 | + surf.configure(mir_surface_attrib_type, 999); |
839 | + }, std::logic_error); |
840 | + EXPECT_THROW({ |
841 | + surf.configure(mir_surface_attrib_type, -1); |
842 | + }, std::logic_error); |
843 | + EXPECT_EQ(mir_surface_type_utility, surf.type()); |
844 | + |
845 | + EXPECT_EQ(mir_surface_type_dialog, |
846 | + surf.configure(mir_surface_attrib_type, |
847 | + mir_surface_type_dialog)); |
848 | + EXPECT_EQ(mir_surface_type_dialog, surf.type()); |
849 | + |
850 | + EXPECT_EQ(mir_surface_type_freestyle, |
851 | + surf.configure(mir_surface_attrib_type, |
852 | + mir_surface_type_freestyle)); |
853 | + EXPECT_EQ(mir_surface_type_freestyle, surf.type()); |
854 | +} |
PASSED: Continuous integration, rev:554 jenkins. qa.ubuntu. com/job/ mir-ci/ 69/ jenkins. qa.ubuntu. com/job/ mir-quantal- amd64-ci/ 70//console
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ mir-ci/ 69//rebuild/?
http://