Merge lp:~mir-team/mir/cursor-spike-phase-1-resubmit-resubmit-resubmit-hello-out-there into lp:mir
- cursor-spike-phase-1-resubmit-resubmit-resubmit-hello-out-there
- Merge into development-branch
Status: | Merged |
---|---|
Approved by: | Robert Carr |
Approved revision: | no longer in the source branch. |
Merged at revision: | 1584 |
Proposed branch: | lp:~mir-team/mir/cursor-spike-phase-1-resubmit-resubmit-resubmit-hello-out-there |
Merge into: | lp:mir |
Diff against target: |
944 lines (+348/-130) 24 files modified
examples/render_surfaces.cpp (+2/-78) include/platform/mir/graphics/cursor.h (+4/-1) include/platform/mir/graphics/cursor_image.h (+46/-0) include/platform/mir/graphics/display.h (+3/-2) include/server/mir/default_server_configuration.h (+10/-0) include/server/mir/graphics/cursor_images.h (+53/-0) include/test/mir_test_doubles/mock_display.h (+1/-1) include/test/mir_test_doubles/null_display.h (+4/-1) src/platform/graphics/android/android_display.cpp (+2/-2) src/platform/graphics/android/android_display.h (+1/-1) src/platform/graphics/mesa/cursor.cpp (+12/-8) src/platform/graphics/mesa/cursor.h (+5/-2) src/platform/graphics/mesa/display.cpp (+13/-8) src/platform/graphics/mesa/display.h (+3/-2) src/server/default_server_configuration.cpp (+4/-7) src/server/graphics/CMakeLists.txt (+1/-0) src/server/graphics/builtin_cursor_images.cpp (+52/-0) src/server/graphics/builtin_cursor_images.h (+51/-0) src/server/graphics/default_configuration.cpp (+35/-0) src/server/graphics/nested/nested_display.cpp (+2/-2) src/server/graphics/nested/nested_display.h (+1/-1) src/server/graphics/offscreen/display.cpp (+1/-1) src/server/graphics/offscreen/display.h (+1/-1) tests/unit-tests/graphics/mesa/test_cursor.cpp (+41/-12) |
To merge this branch: | bzr merge lp:~mir-team/mir/cursor-spike-phase-1-resubmit-resubmit-resubmit-hello-out-there |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Alan Griffiths | Abstain | ||
Daniel van Vugt | Abstain | ||
Kevin DuBois (community) | Abstain | ||
Alberto Aguirre (community) | Approve | ||
Chris Halse Rogers | Approve | ||
Review via email: mp+216961@code.launchpad.net |
This proposal supersedes a proposal from 2014-03-18.
Commit message
Extract cursor image from the builtin cursor in preparation for client cursor API.
Description of the change
This is phase 1 of a spike I am doing on the cursor code.
My goal is to enable a client cursor API, that is enable clients to request cursors and enable/disable the cursor.
This branch just contains some first steps:
1. Normalize the treatment of the Cursor object, that is to say deal with it like other objects on the server configuration. Display::the_cursor is moved to DefaultServerCo
2. Introduce CursorImage and CursorRepository. Port the builtin cursor image to this interface and port the mesa hardware cursor to use CursorImage.
Next steps planned:
1. Build XCursor theme based CursorRepository for loading themed cursors.
2. Enable client API for setting cursor (using a similar style to display mediator, focused client can set the cursor, including disabling it)
Thanks!
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Please resubmit and move black_arrow.c using "bzr mv" so it's not bloating the diff.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1473
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : Posted in a previous version of this proposal | # |
black_arrow.c isn't an important file to track the history of, I admit. But in general we should "bzr mv" to ensure files don't lose history when they move. And doing a move would omit its contents from the diff too, halving the size of the merge proposal.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> black_arrow.c isn't an important file to track the history of, I admit. But in
> general we should "bzr mv" to ensure files don't lose history when they move.
> And doing a move would omit its contents from the diff too, halving the size
> of the merge proposal.
+1
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
16 +#include <assert.h>
17 +
1551 +#include <assert.h>
1552 +
needed?
CursorImage might better be a mir::scene:
1568 + const int cursor_width = 64;
1569 + const int cursor_height = 64;
const ordering and magic numbers, maybe black_arrow.
1665 + static const geometry::Size default_cursor_size = {geometry:
1666 + geometry:
const ordering and why static
mg::BuiltinCurs
I'd expect a repository to be something more like a std::map, this seems to allocate a new object during every lookup.
1652 +mir::DefaultSe
can we assume we only have one cursor? The nexus 4 could potentially have 4 cursors that are hardware accelerated.
+ return the_display(
This is a pre-existing issue, but it strikes me that its very strange that the display interface allocates the hardware cursor, when the display interface does not even allocate the framebuffers. A hardware cursor is a special buffer, it should be allocated from mg::GraphicBuff
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Also remember to move black_arrow.xcf to wherever black_arrow.c goes.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Fixed assert and constant stuff.
>> mg::BuiltinCurs
>> I'd expect a repository to be something more like a std::map, this seems to allocate a new object during
>> every lookup.
Probably for the themed cursors, it didnt seem worth defining the ctor in this case since its only called once, but I decided there is no harm and changed it to define a ctor so we can just return the same instance.
Strictly this code is probably less performant ;) as there is no runtime difference (only called once) and the non defaulted ctor increases binary size. Still I dont think there is any harm anyway.
>> CursorImage might better be a mir::scene:
Ive changed raw_argb to use as_argb_8888 as in the style of PixelBuffer.
For now the PixelBuffer interface is obviously a bit specific:
/*
* Interface for extracting the pixels from a graphics::Buffer.
*/
Conceptually they both implement some sort of mir::graphics:
>> can we assume we only have one cursor? The nexus 4 could potentially have 4 cursors that are hardware
>> accelerated.
No we cant assume this forever. For now though I have a pretty simple target, mostly for the desktop preview/xmir:
A single themeable cursor controllable by client API (controllable, as in: theme, enable/disable).
I dont think we have any requirements for any multi cursor stuff now.
>> + return the_display(
>> This is a pre-existing issue, but it strikes me that its very strange that the display interface
>> allocates the hardware cursor, when the display interface does not even allocate the framebuffers. A
>> hardware cursor is a special buffer, it should be allocated from mg::GraphicBuff
I agree its weird. Ill fix up this in one of the next branches as I clean up the GBM cursor a little more. This branch is mostly about encapsulating the cursor image and cursor in the server configuration so that work on cursor implementation independent code can continue (cursor theme loader, client API for cursor image control) in parallel to the cursor backend work.
Thanks!
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Tried to revert black_arrow.c and then move it but bzr doesnt like that...ust a sec
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Fixed black_arrow.c...was there a better way to do that than recreate the entire branch?
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1480
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
No diff, no code?!
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
Apart from the lack of code… assuming the diff is roughly equivalent to the previous submission:
I'd prefer create_
----
2. Enable client API for setting cursor (using a similar style to display mediator, focused client can set the cursor, including disabling it)
This is the wrong way approach, I think. The focused client should not be able to set the cursor; a client should be able to set how the cursor appears over their surface.
Yes, that requires work down the input mines...
While I'm on the subject of cursor handling, I think in the post-HWC-enablement world we should be leaving it to the compositor. I'll catch you on IRC perhaps.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Not sure what the missing diff was about...
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1481
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
#1
> Probably for the themed cursors, it didnt seem worth defining the ctor in this case since its only called
> once, but I decided there is no harm and changed it to define a ctor so we can just return the same instance.
>
> Strictly this code is probably less performant ;) as there is no runtime difference (only called once) and the
> non defaulted ctor increases binary size. Still I dont think there is any harm anyway.
I'm not so concerned about the performance either here. It seems in the superseded review the make_shared() was in lookup_cursor, and in this one its in the constructor of BuiltinCursorRe
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
#2
I guess my main point I have to make is that a hardware cursor, should be modelled just like a buffer in the parts of the system that don't care about hardware bits. (much like mg::Buffer could have any sort of buffer backing it, with different flags and use cases)
On mesa, mg::BufferAlloc
With the ms::PixelBuffer point, it seems funny to have:
class CursorImage
{
virtual void const* as_argb_8888() = 0;
virtual geometry::Size size() = 0;
};
and
class PixelBuffer
{
virtual void fill_from(
virtual void const* as_argb_8888() = 0;
virtual geometry::Size size() const = 0;
virtual geometry::Stride stride() const = 0;
}
which both model software access to a buffer.
Maybe this means:
mg::SoftwareBuffer
{
virtual void const* as_argb_8888() = 0;
virtual geometry::Size size() const = 0;
virtual geometry::Stride stride() const = 0;
};
ms::PixelBuffer : public mg::SoftwareBuffer
{
virtual void fill_from(
}
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
+1 on Kevin's point #2, with the additional point that there isn't any special region reserved for the hardware cursor; AFAIK the only restriction is that the buffer must be 64x64 (on most cards, 128x128 is an option on newer radeons, for example).
The cursor image really is just a buffer.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1482
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
I am not sure sure about the cursor image/pixel buffer stuff, the cursor image is something that you will upload to a buffer (a buffer which while not being a special buffer in the buffer sense is given special status in the server), pixel buffer instead models something which you read OUT of a buffer. Of course it seems there is some sort of mg::Pixels base.
RAOF and I had a discussion on the Cursor is just a buffer thread:
22:42 < RAOF> racarr_: You're thinking cursors?
22:43 -!- FunnyLookinHat [~funnylook@
22:44 < racarr_> RAOF: Yes. and wondering wwhat you were thinking
22:45 < RAOF> Cool.
22:45 < racarr_> as to the small bits that were on launchpad...uh
22:45 < racarr_> it was a mild hallucination that doing it per connection was going to be easier and also a useful step towards per surface so I ust imagined doing that first
22:45 < RAOF> Hah!
22:45 < racarr_> but have now decided it was silly and am on to mir_surface_
22:45 < racarr_> and um...
22:45 < RAOF> It probably _would_ be easier to do per-connection :)
22:46 < racarr_> well but you have to write code that ends up not being useful
22:46 < racarr_> so its pretty pointless
22:46 < RAOF> Yeah.
22:46 < RAOF> It's not a step towards per-surface cursors, which is what you need.
22:46 < racarr_> Also re:create_
22:46 < racarr_> and unique/shared here it actually is shared
22:46 < racarr_> with the GBM::Display which manipulates it in case of pause/stop, etc.
22:47 < racarr_> which is mostly why it hasnt been moved to some more appropriate place of allocation yet
22:47 < RAOF> Urgh.
22:47 < racarr_> err pause/resume
22:47 < racarr_> to restore the position iirc
22:48 < RAOF> Yeah, because it's all wrong! :)
22:48 < racarr_> lol
22:48 < racarr_> what are your thoughts :D
22:49 < RAOF> So, what I think should be the final state is: The cursor is a renderable in the scene, and the compositor is responsible for getting it on the screen.
22:50 < RAOF> Under GBM the compositor will check if the topmost renderable in the scene is (a) the existing hardware cursor or (b) usable as a HW cursor, and do the API
22:50 < racarr_> ok
22:51 < RAOF> Under Android the HWC machinery will translate into basically a HW cursor anyway
22:51 < racarr_> Yes
22:51 < RAOF> So I think all the Cursor API wants to be is basically a pointer at a specific renderable.
22:52 < racarr_> hmm well I mean
22:52 < RAOF> If we want a server cursor API at all, I guess?
22:52 < racarr_> it seems like it still needs to be promoted to the server configuration and
22:52 < racarr_> from the perspective of mg::Cursor
22:52 < racarr_> RAOF: Well we are baking window management in to mir
22:53 < racarr_> so the surface cursor selection has to work by default
22:53 < racarr_> and input should be hooked up to the cursor, etc
22:53 < RAOF> Oh, yeah.
22:53 < RAOF> That was just rambling as to what extent we need a Mir-private Cursor API.
22:53 < RAOF> Or whether the various bits could just prod the relevant Renderable.
22:55 < RAOF> It's probably cleaner to have an actual interface to prod, though.
22:55 < racarr_> hmm
22:55...
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
(3) render_surfaces now segfaults on the first movement of the cursor:
(gdb) bt
#0 0x00007f0a4d0703de in mir::DefaultSer
at /home/dan/
#1 0x00007f0a4d117292 in mir::input:
at /home/dan/
#2 0x00007f0a4d117597 in mir::input:
this=0x11a3150, new_x=6, new_y=-5)
at /home/dan/
(4) I agree mir::graphics:
(5) CursorRepository is a bad abstraction and the confusing word "Repository" is the reason. A repository of cursors is not a familiar concept even to a graphics programmer. I think the cursor theme should be the main object there. So instead of:
img = repository-
a better design would be:
img = theme->
Remember to link the relevant bugs when ready:
https:/
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
+1 for RAOF's thoughts at 22:49-22:51 and for Daniel's points.
As for the cursor always being on top of everything, it seems a bit more flexible not to bake that into mir and have that be a decision of the shell stuff. (I could see someone wanting a cursor to go under a pop-up notification maybe)
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Another issue:
(6) I think it would scale/port better to more toolkits for us to choose the cursor type using an enum. Otherwise we will find ourselves having to translate toolkit requirements into strings on the client side, which is less efficient and not strongly typed like an enum is.
251 + std::string const& cursor_name,
Something like this would be good:
img = cursor_
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
3. Fixed. Whoops! Lost track during refactoring and was returning a nullptr rather than a null cursor instance.
4. Im still not sure what we mean here. mir::graphics:
5. What loads the Cursor theme then?
6. I chose string/string on the suggestion of RAOF...and that afaik it is what toolkits will be best prepared to deal with (working like other cursor APIs).
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1483
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : Posted in a previous version of this proposal | # |
(3) render_surfaces: Confirmed it no longer crashes. I think this is a bad example though. Setting a NullCursor is not how anyone will hide the cursor in reality. That should be a separate show/hide function. Maybe as an example you could just change NullCursor to some kind of SimpleCursor (but visible).
(4) Yes, Buffer is presently a GPU-side buffer. My suggestion describes how it might be generalized to represent any type of buffer though. Not yet useful, but plausibly in future. Not a blocker.
(5) Good point. But "Repository" still feels very counter-intuitive. Perhaps it's the graphics platform which determines and constructs available themes. Or maybe it's the Display. Or to just be generic, let it be a CursorThemeFactory which produces CursorTheme's, from which you can load a known cursor image.
(6) Converting between strings and enums is not a big deal. However I think there is sufficient evidence that enums are a better fit for plenty of toolkits:
https:/
http://
http://
And I think enums are a better fit for apps too, which simply want to say "give me an arrow/crosshair
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
P.S. Cursor themes don't have to be complicated or even depend on X libraries. We could for example say that a cursor theme is a single image (dimensions WxH) loaded any way you like. And cursor type N can be found at square x=N*H,y=0,w=H,h=H. In that case all you need to produce a cursor theme is an image editor. And no dependencies on legacy X code.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
>> That should be a separate show/hide function. Maybe as an example you could just change NullCursor to some >> kind of SimpleCursor (but visible).
What do you mean by SimpleCursor. Not sure what render_surfaces cursor stuff is intended to be an example of really. A later branch in this spike introduces cursor show/hide as part of the general control API. Maybe change it then?
>> (5) Good point. But "Repository" still feels very counter-intuitive. Perhaps it's the graphics platform
>> which determines and constructs available themes. Or maybe it's the Display. Or to just be generic, let it >> be a CursorThemeFactory which produces CursorTheme's, from which you can load a known cursor image.
Its certainly not the display or graphics platform. In an upcoming branch there is a component which changes the cursor image based on entering/leaving surfaces (and what these surfaces have requested for their cursor). Certainly this component should not depend on the entire Display/Graphics platform interface. Plus the cursor theme loader doesnt vary with graphics platform.
In this case Repository is a little more honest than Factory because ownership of the images is shared with the creator which acts as a cache (or generically: repository) of the loaded images.
>> (6) Converting between strings and enums is not a big deal. However I think there is sufficient evidence >> that enums are a better fit for plenty of toolkits:
Maybe RAOF will have some insight?
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
1) I don't think there's any value in not using existing XCursor themes. There's nothing wrong with them, and it's one less point of friction.
2) I think strings for the cursor-lookup API are going to be a better idea than enums. While toolkits generally provide a set of enums for common cursors, they *also* provide the ability to look up arbitrary cursors. This also lets clients load their own themes with semantically useful identifiers.
Overall, I think this is a step in the right direction, and will approve as such.
Review nits:
185 + virtual std::shared_
Should take a std::shared_
Relatedly, all the public members of CursorImage and CursorRepository want to be const.
I'd really like it if create_
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
(3) NullCursor/
(5) "Repository" is still a very ambiguous word. As such, people (including myself) can't figure out what it is or where such a thing would or should be instantiated. If your class design necessitates ambiguous words then that's a sign you need a different class design.
(6) XCursor themes are a stopgap. They shouldn't drive future architecture. The above links all show toolkits and apps fit better with enums. And we can still translate them so XCursors can be used in the mean time.
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
I think we disagree about (6) - the toolkits all _support_ the use of enums for common cursors, but they also support the use of strings (and, indeed, arbitrary images). I'm perfectly happy for the client API for this to have two entry points - mir_surface_
Going further, I'd like clients to be able to load cursor themes and index into them; in this case, string indices are mandatory (or, at least, really useful).
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
>>Review nits:
>>185 + virtual std::shared_
>>Should take a std::shared_
>> Relatedly, all the public members of CursorImage and CursorRepository want to be const.
Fixed
>>1) I don't think there's any value in not using existing XCursor themes. There's nothing wrong with them, and it's one less >>point of friction.
I agree.
-------
>> (3) NullCursor/
There is also a simple visible cursor, however the example previously came with an option to totally disable the cursor so I preserve that.
>> (5) "Repository" is still a very ambiguous word. As such, people (including myself) can't figure out what it is or where >> >> such a thing would or should be instantiated. If your class design necessitates ambiguous words then that's a sign you need >> a different class design.
Are you being serious about the word repository or just trying to prove a point re: your opinion on object architecture? I am only aware of two main definitions of repository: 1. A location where things are stored and offered. 2. A burial place. Mulled it over the weekend and do not see the confusion.
Still I am not particular attached to the word. How about CursorLoader as in the most recent revision. This fails to capture the aspect that you share ownership with the loader, but that information is also in the shared_ptr signature so I do not think it is a big loss.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1485
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
(3) ExampleCursorImage doesn't seem to do anything(?). I can just get none (default) or the standard black arrow with --display-cursor=1. Looks like the bug pre-dates this proposal, but it makes the proposed changes untestable.
(5) Yes I am serious about "Repository". Names are important because a well chosen one leads to universal understanding, high productivity and avoids refactoring. Poorly chosen names lead to confusion and thus slow development or even bugs. The word "Repository" I know means where you put or get something. So is the cursor coming or going from a "repository"? It's not clear from the name. A realistic mental model for cursors is that you put it in on the screen, but you get it from a theme. Those are more concrete nouns that will lead to wider understanding and better code reuse/utilization. "CursorLoader" is mildly better, but it makes the mistake of using a verb in the noun, which tends to limit how well multiple people can agree on what it represents. If there is a more concrete noun available like Theme or Factory then I'd prefer we used it.
(6) Per these links:
https:/
http://
http://
you can see there's going to be a fair amount of mapping between enums and/or strings. While strings are completely flexible, it's more efficient and simpler to map between enum values. That said, I'm not sure that's a performance/
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1486
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
CursorLoader-
The code in render surfaces was only triggered when input was disabled (to provide...some sort of cursor animation when running examples as non root?!), it seems bad to start mir with input disabled (you cant quit), and this didnt seem to be a particularly important example so Ive removed it.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1488
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1489
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : Posted in a previous version of this proposal | # |
(3) NullCursor is not a realistic way to hide the cursor. We should either display a simple custom cursor or not modify render_surfaces at all in this proposal. NullCursor is not a useful example or manual test at all. Because showing nothing means you can't really tell it's working properly. And in reality when you do want "no cursor" you will probably toggle a flag, but not set a NullCursor.
(7) "CursorImages" vs "theme": In my mind cursor images come from a theme, but you're selecting a theme from CursorImages. That sounds backwards and will be hard to understand/
304 +class CursorImages
305 +{
306 +public:
307 + /// Looks up the image for a named cursor in a given cursor theme. Cursor names
308 + /// follow the XCursor naming conventions.
309 + virtual std::shared_
310 + std::string const& cursor_name,
311 + geometry::Size const& size) = 0;
312 +
The most realistic (IMHO) interpretation of "cursor images" is a set of cursor images provided by a theme. In that way the cursor images concept is a subset of the theme, not the superset. Maybe there does exist a class name where this design makes sense, but not "CursorImages".
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
This suggests:
class CursorTheme
{
public:
virtual std::unique_
}
Plus
class XCursorTheme : public CursorTheme
{
public:
XCursorTheme(
}
?
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Chris: Yeah I suggested CursorTheme above on 2014-03-21. And Robert rightfully pointed out you still need a factory to abstract the construction of a CursorTheme. But I think that's probably OK. And it has the added benefit of not implying that all your themes are loaded and available simultaneously, because they probably shouldn't be.
On the other hand, I'm not 100% against them being a single class as it is designed right now. But the proposed names of "CursorRepository" and "CursorImages" don't describe the design clearly and unambiguously enough.
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
CursorImageLoader?
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
875 +void const* StubCursorImage
It is non-portable to reinterpret 0x1729 as a pointer? Can't we use a sensible value. E.g.
void const* StubCursorImage
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
reading through the comments there seem to be three issues in play:
1. How to model not having a cursor.
2. The interface name for sourcing images ("CursorImages" in the current revision)
3. Whether cursor themes are textual labels or objects in their own right.
1. How to model not having a cursor.
=======
I like NullObject pattern for a lot of things but in this case something is wrong about it.
Looking at the mg::Cursor interface it isn't a cursor, it is a sink for cursor updates (motion and image changes). Having a Null version of an event sink makes more sense than a null cursor.
Maybe mg::Cursor has the wrong name and should be mg::CursorModifier. NullCursorModifier doesn't seem strange.
2. The interface name for sourcing images
=======
I'm not entirely convinced by "Loader" as that loading is an implementation detail. In fact, the "Loader" implementations in the MP don't load anything.
The current name "CursorImages" doesn't seem too bad in itself, but this doesn't read well:
"the_cursor_
How about something like:
"the_
3. Whether cursor themes are textual labels or objects
=======
I don't know enough about cursors to have an opinion.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
But 1729 was a perfectly reasonable choice, its the smallest number expressible as the sum of 2 cubes in 2 ways...ok but it's gone.
Renamed lookup cursor:
the_cursor_
im pretty happy with this one.
DO you think cursor store is better? Is it better than the original repository? (Repository sounds slightly better to me than store...not sure why...use of store like that isnt so common in american english I guess).
I am trying not to deal with the mg::Cursor (I think you are on to something with a different name, but modifier doesnt strike me) until I establish the cursor API and can think about it a little more clearly.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1491
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
I know you are dying to hear more naming suggestions so here's mine :) - given the current CursorImages interface it leads itself to CursorImageProv
which leads to
the_cursor_
Repository for me implies having size/add/remove methods, store - yeah not a fan, I suppose it's the US context - why am I buying cursors? :)
Cursor and NullCursor make sense to me - I think the definition of cursor here makes sense - a movable image. A NullCursor then makes sense - an empty image that doesn't move.
CursorModifier would not make sense to me, as then I would have the following questions - what "cursor" is it modifying? Who implements cursor?
I'm not hung up on the names though functionally it looks fine to me.
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
+1 that the existing mir::graphics:
At the highest level I think the shell will have a current active (perhaps fixed) cursor theme. So that's something you should be able to query to get an image:
shell-
or
config-
And an app/surface could have its own too:
img = surface-
Who or what changes the theme is an exercise for later. But first we need to define (like in the above examples) where/what the theme exists. If you change the theme, who do you change it for? I think you change it for:
(a) the whole shell; or
(b) a specific surface/app.
Also, once you set a theme, how do you refer to it? In the current design that would be a string. I think that's inefficient. It's a set of images with metadata like hotspot coordinates. The theme sounds like an object to me.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
Well if themes are meaningful as objects why don't we want code like:
auto const new_theme = ???.cursor_
cursor-
...
cursor-
...
cursor-
or
cursor-
I.e. I don't get why the client code is messing with getting and setting CursorImages instead of asking the cursor to talk to its current theme.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
I don't think a cursor theme is particularly useful as an object. I dont see cursor theme changes being handled by the shell swapping out cursor theme objects, rather I would say when the system is reconfigured the default cursor theme changes.
As far as I can see the main point for selecting alternative cursor themes, is for example a game may install an alternate cursor theme, and refer to it by name, as a more convenient form of uploading custom cursors.
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
This looks to me like a step in the right direction.
Random nit:
309 + virtual std::shared_
→ virtual std::shared_
☺
Re: cursor themes as objects. The bare minimum required is the ability to associate a CursorImage with a surface, and this CursorImage is going to come from the client - either by reference “give me MIR_CURSOR_
Whether or not we want to *have* a global default cursor theme - so that clients which have specified MIR_CURSOR_
I would be quite happy with Mir not providing any means to create CursorImages *at all*. It's something that all desktop shells are going to need to do, so I don't think it's out of scope for Mir, but equally it's not something that needs to interact with the rest of Mir at all. We could perfectly happily have a purely client-side library that handles the cursor loading/
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
Alan's concern concerned me too when I read it:
"I.e. I don't get why the client code is messing with getting and setting CursorImages instead of asking the cursor to talk to its current theme."
But I don't see where client code is messing with CursorImages. Unless you mistake the render_surfaces demo for a client? It's not a client... or a server :)
(7) I'm trying to not be the blocker here and responding to all new comments every day. But I still can't get past the repository/
std::string const& theme_name,
and worry about the "theme" question later. Then it matters much less what "CursorImages" is called.
(3) NullCursor still needs fixing IMHO per comments on 2014-04-02.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
> Alan's concern concerned me too when I read it:
> "I.e. I don't get why the client code is messing with getting and setting
> CursorImages instead of asking the cursor to talk to its current theme."
> But I don't see where client code is messing with CursorImages. Unless you
> mistake the render_surfaces demo for a client? It's not a client... or a
> server :)
The phrase "client code" shouldn't be misinterpreted like this. We're discussing interface design and in that context it means code that is a client of that interface.
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
So, given that ‘cursor-
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
The blockers are:
(7) Remove the "theme_name" parameter to eliminate all confusion and debate over theming. If no one mentions the word "theme" for now then there's less to argue about.
(3) NullCursor still needs fixing per comments on 2014-04-02.
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
If we're not messing with the abstraction that mg::Cursor represents then NullCursor makes sense. (I'm unconvinced by the naming as discussed above, but that isn't a blocker for this MP.)
I tend to agree with Daniel about "theme_name" - we don't need any representation of themes (yet).
Is there anything cursor specific about CursorImage? Or is it just a holder for any ARGB image?
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
As it stands, CursorImage is just a holder for any ARGB image, in the future it could grow a hotspot, or come to understand animated cursors, etc....
>> (7) Remove the "theme_name" parameter to eliminate all confusion and debate over theming.
>> If no one mentions the word "theme" for now then there's less to argue about.
----
>>I tend to agree with Daniel about "theme_name" - we don't need any representation of themes (yet).
I think the game cursor theme example is a good use case for themes, we can support it easily. If the only reason is so there "is less" to argue about why waste the time to remove it now and then add it later?
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal | # |
The use of arbitrary cursor_name strings eliminates the need for any theme right now, even in the game case. Because your game can just:
load_
I'd rather not take the approach of land it now and fix it later. It's not clear any theme specification will be required at all in the foreseeable future. And it just creates design disagreements over what a theme represents.
Robert Carr (robertcarr) wrote : | # |
Le cursor themes are gone.
Chris Halse Rogers (raof) wrote : | # |
I think that's the prudent course.
We probably _will_ want some sort of cursor theme object, but let's defer that until the rest is sorted out; we don't have a consensus for how it should look, and it'll probably be clearer when the rest of the infrastructure is in place.
Still a couple of places where std::shared_
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1492
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: 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:1493
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : | # |
(3) render_
Other than that I'm not going to look too hard or else run the risk of spotting new issues.
Alberto Aguirre (albaguirre) wrote : | # |
> (3) render_
> anything and should either be removed or turned into a real cursor, per
> comments on 2014-03-25.
>
+1 but not a blocker for me.
> Other than that I'm not going to look too hard or else run the risk of
> spotting new issues.
Uh, isn't that contrary to the purpose of code review?
Anyway, the code looks simple enough, LGTM.
Robert Carr (robertcarr) wrote : | # |
In death may null cursor find the peace it never found in life.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1495
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : | # |
I'll abstain, until I know more of the future plan in the area of cursors.
Some of the things are pre-existing.
I still think CursorImage is close to:
http://
and that there's the pre-existing issue that android has no good way to implement
auto mga::AndroidDis
It makes more sense to me for a cursor buffer to be generated from the_buffer_
shouldn't the destructor for CursorImage{,s} be public?
Daniel van Vugt (vanvugt) wrote : | # |
I'm not sure you need to change render_surfaces.cpp at all in this proposal any more.
/me shuts eyes
Alan Griffiths (alan-griffiths) wrote : | # |
466 + void set_image(
Are we really sharing ownership of CursorImage? Wouldn't CursorImage const& be enough?
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1496
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: 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 : | # |
Alan makes a good point about set_image. That shared_ptr parameter isn't shared at all. It should just be a reference parameter. But that's a minor non-blocker. I'm sure we make the same mistake elsewhere and haven't fixed it yet.
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'examples/render_surfaces.cpp' |
2 | --- examples/render_surfaces.cpp 2014-04-15 10:19:19 +0000 |
3 | +++ examples/render_surfaces.cpp 2014-04-28 23:16:18 +0000 |
4 | @@ -26,7 +26,6 @@ |
5 | #include "mir/geometry/size.h" |
6 | #include "mir/geometry/rectangles.h" |
7 | #include "mir/graphics/buffer_initializer.h" |
8 | -#include "mir/graphics/cursor.h" |
9 | #include "mir/graphics/display.h" |
10 | #include "mir/graphics/display_buffer.h" |
11 | #include "mir/graphics/gl_context.h" |
12 | @@ -89,62 +88,10 @@ |
13 | namespace |
14 | { |
15 | std::atomic<bool> created{false}; |
16 | -bool input_is_on = false; |
17 | -std::weak_ptr<mg::Cursor> cursor; |
18 | -static const uint32_t bg_color = 0x00000000; |
19 | -static const uint32_t fg_color = 0xffdd4814; |
20 | + |
21 | static const float min_alpha = 0.3f; |
22 | |
23 | -void update_cursor(uint32_t bg_color, uint32_t fg_color) |
24 | -{ |
25 | - if (auto cursor = ::cursor.lock()) |
26 | - { |
27 | - static const int width = 64; |
28 | - static const int height = 64; |
29 | - std::vector<uint32_t> image(height * width, bg_color); |
30 | - for (int i = 0; i != width-1; ++i) |
31 | - { |
32 | - if (i < 16) |
33 | - { |
34 | - image[0 * height + i] = fg_color; |
35 | - image[1 * height + i] = fg_color; |
36 | - image[i * height + 0] = fg_color; |
37 | - image[i * height + 1] = fg_color; |
38 | - } |
39 | - image[i * height + i] = fg_color; |
40 | - image[(i+1) * height + i] = fg_color; |
41 | - image[i * height + i + 1] = fg_color; |
42 | - } |
43 | - cursor->set_image(image.data(), geom::Size{width, height}); |
44 | - } |
45 | -} |
46 | - |
47 | -void animate_cursor() |
48 | -{ |
49 | - if (!input_is_on) |
50 | - { |
51 | - if (auto cursor = ::cursor.lock()) |
52 | - { |
53 | - static int cursor_pos = 0; |
54 | - if (++cursor_pos == 300) |
55 | - { |
56 | - cursor_pos = 0; |
57 | - |
58 | - static const uint32_t fg_colors[3] = { fg_color, 0xffffffff, 0x3f000000 }; |
59 | - static int fg_color = 0; |
60 | - |
61 | - if (++fg_color == 3) fg_color = 0; |
62 | - |
63 | - update_cursor(bg_color, fg_colors[fg_color]); |
64 | - } |
65 | - |
66 | - cursor->move_to(geom::Point{cursor_pos, cursor_pos}); |
67 | - } |
68 | - } |
69 | -} |
70 | - |
71 | char const* const surfaces_to_render = "surfaces-to-render"; |
72 | -char const* const display_cursor = "display-cursor"; |
73 | |
74 | ///\internal [StopWatch_tag] |
75 | // tracks elapsed time - for animation. |
76 | @@ -278,9 +225,7 @@ |
77 | |
78 | result->add_options() |
79 | (surfaces_to_render, po::value<int>()->default_value(5), |
80 | - "Number of surfaces to render") |
81 | - (display_cursor, po::value<bool>()->default_value(false), |
82 | - "Display test cursor. (If input is disabled it gets animated.)"); |
83 | + "Number of surfaces to render"); |
84 | |
85 | return result; |
86 | }()) |
87 | @@ -382,7 +327,6 @@ |
88 | bool composite() |
89 | { |
90 | while (!created) std::this_thread::yield(); |
91 | - animate_cursor(); |
92 | stop_watch.stop(); |
93 | if (stop_watch.elapsed_seconds_since_last_restart() >= 1) |
94 | { |
95 | @@ -501,23 +445,6 @@ |
96 | created = true; |
97 | } |
98 | |
99 | - bool input_is_on() |
100 | - { |
101 | - return the_options()->get<bool>(mo::enable_input_opt); |
102 | - } |
103 | - |
104 | - std::weak_ptr<mg::Cursor> the_cursor() |
105 | - { |
106 | - if (the_options()->get<bool>(display_cursor)) |
107 | - { |
108 | - return the_display()->the_cursor(); |
109 | - } |
110 | - else |
111 | - { |
112 | - return {}; |
113 | - } |
114 | - } |
115 | - |
116 | private: |
117 | std::vector<Moveable> moveables; |
118 | }; |
119 | @@ -532,9 +459,6 @@ |
120 | |
121 | mir::run_mir(conf, [&](mir::DisplayServer&) |
122 | { |
123 | - cursor = conf.the_cursor(); |
124 | - |
125 | - input_is_on = conf.input_is_on(); |
126 | }); |
127 | ///\internal [main_tag] |
128 | |
129 | |
130 | === modified file 'include/platform/mir/graphics/cursor.h' |
131 | --- include/platform/mir/graphics/cursor.h 2013-08-28 03:41:48 +0000 |
132 | +++ include/platform/mir/graphics/cursor.h 2014-04-28 23:16:18 +0000 |
133 | @@ -23,14 +23,17 @@ |
134 | #include "mir/geometry/size.h" |
135 | #include "mir/geometry/point.h" |
136 | |
137 | +#include <memory> |
138 | + |
139 | namespace mir |
140 | { |
141 | namespace graphics |
142 | { |
143 | +class CursorImage; |
144 | class Cursor |
145 | { |
146 | public: |
147 | - virtual void set_image(void const* raw_argb, geometry::Size size) = 0; |
148 | + virtual void set_image(std::shared_ptr<CursorImage const> const& cursor_image) = 0; |
149 | virtual void move_to(geometry::Point position) = 0; |
150 | |
151 | protected: |
152 | |
153 | === added file 'include/platform/mir/graphics/cursor_image.h' |
154 | --- include/platform/mir/graphics/cursor_image.h 1970-01-01 00:00:00 +0000 |
155 | +++ include/platform/mir/graphics/cursor_image.h 2014-04-28 23:16:18 +0000 |
156 | @@ -0,0 +1,46 @@ |
157 | +/* |
158 | + * Copyright © 2014 Canonical Ltd. |
159 | + * |
160 | + * This program is free software: you can redistribute it and/or modify it |
161 | + * under the terms of the GNU Lesser General Public License version 3, |
162 | + * as published by the Free Software Foundation. |
163 | + * |
164 | + * This program is distributed in the hope that it will be useful, |
165 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
166 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
167 | + * GNU Lesser General Public License for more details. |
168 | + * |
169 | + * You should have received a copy of the GNU Lesser General Public License |
170 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
171 | + * |
172 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
173 | + */ |
174 | + |
175 | + |
176 | +#ifndef MIR_GRAPHICS_CURSOR_IMAGE_H_ |
177 | +#define MIR_GRAPHICS_CURSOR_IMAGE_H_ |
178 | + |
179 | +#include "mir/geometry/size.h" |
180 | + |
181 | +namespace mir |
182 | +{ |
183 | +namespace graphics |
184 | +{ |
185 | +class CursorImage |
186 | +{ |
187 | +public: |
188 | + virtual ~CursorImage() = default; |
189 | + |
190 | + virtual void const* as_argb_8888() const = 0; |
191 | + virtual geometry::Size size() const = 0; |
192 | + |
193 | +protected: |
194 | + CursorImage() = default; |
195 | + CursorImage(CursorImage const&) = delete; |
196 | + CursorImage& operator=(CursorImage const&) = delete; |
197 | +}; |
198 | +} |
199 | +} |
200 | + |
201 | + |
202 | +#endif /* MIR_GRAPHICS_CURSOR_IMAGE_H_ */ |
203 | |
204 | === modified file 'include/platform/mir/graphics/display.h' |
205 | --- include/platform/mir/graphics/display.h 2014-01-31 07:48:24 +0000 |
206 | +++ include/platform/mir/graphics/display.h 2014-04-28 23:16:18 +0000 |
207 | @@ -31,6 +31,7 @@ |
208 | class DisplayBuffer; |
209 | class DisplayConfiguration; |
210 | class Cursor; |
211 | +class CursorImage; |
212 | class GLContext; |
213 | class EventHandlerRegister; |
214 | |
215 | @@ -97,9 +98,9 @@ |
216 | virtual void resume() = 0; |
217 | |
218 | /** |
219 | - * Gets the hardware cursor object. |
220 | + * Create a hardware cursor object. |
221 | */ |
222 | - virtual std::weak_ptr<Cursor> the_cursor() = 0; |
223 | + virtual std::shared_ptr<Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image) = 0; |
224 | |
225 | /** |
226 | * Creates a GLContext object that shares resources with the Display's GL context. |
227 | |
228 | === modified file 'include/server/mir/default_server_configuration.h' |
229 | --- include/server/mir/default_server_configuration.h 2014-04-25 14:38:31 +0000 |
230 | +++ include/server/mir/default_server_configuration.h 2014-04-28 23:16:18 +0000 |
231 | @@ -91,6 +91,9 @@ |
232 | class BufferInitializer; |
233 | class DisplayReport; |
234 | class GraphicBufferAllocator; |
235 | +class Cursor; |
236 | +class CursorImage; |
237 | +class CursorImages; |
238 | class GLConfig; |
239 | class GLProgramFactory; |
240 | namespace nested { class HostConnection; } |
241 | @@ -159,6 +162,10 @@ |
242 | * dependencies of graphics on the rest of the Mir |
243 | * @{ */ |
244 | virtual std::shared_ptr<graphics::DisplayReport> the_display_report(); |
245 | + virtual std::shared_ptr<graphics::Cursor> the_cursor(); |
246 | + virtual std::shared_ptr<graphics::CursorImage> the_default_cursor_image(); |
247 | + virtual std::shared_ptr<graphics::CursorImages> the_cursor_images(); |
248 | + |
249 | /** @} */ |
250 | |
251 | /** @name compositor configuration - customization |
252 | @@ -270,6 +277,9 @@ |
253 | CachedPtr<graphics::BufferInitializer> buffer_initializer; |
254 | CachedPtr<graphics::GraphicBufferAllocator> buffer_allocator; |
255 | CachedPtr<graphics::Display> display; |
256 | + CachedPtr<graphics::Cursor> cursor; |
257 | + CachedPtr<graphics::CursorImage> default_cursor_image; |
258 | + CachedPtr<graphics::CursorImages> cursor_images; |
259 | |
260 | CachedPtr<frontend::ConnectorReport> connector_report; |
261 | CachedPtr<frontend::ProtobufIpcFactory> ipc_factory; |
262 | |
263 | === added file 'include/server/mir/graphics/cursor_images.h' |
264 | --- include/server/mir/graphics/cursor_images.h 1970-01-01 00:00:00 +0000 |
265 | +++ include/server/mir/graphics/cursor_images.h 2014-04-28 23:16:18 +0000 |
266 | @@ -0,0 +1,53 @@ |
267 | +/* |
268 | + * Copyright © 2014 Canonical Ltd. |
269 | + * |
270 | + * This program is free software: you can redistribute it and/or modify it |
271 | + * under the terms of the GNU General Public License version 3, |
272 | + * as published by the Free Software Foundation. |
273 | + * |
274 | + * This program is distributed in the hope that it will be useful, |
275 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
276 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
277 | + * GNU General Public License for more details. |
278 | + * |
279 | + * You should have received a copy of the GNU General Public License |
280 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
281 | + * |
282 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
283 | + */ |
284 | + |
285 | + |
286 | +#ifndef MIR_GRAPHICS_CURSOR_LOADER_H_ |
287 | +#define MIR_GRAPHICS_CURSOR_LOADER_H_ |
288 | + |
289 | +#include "mir/geometry/size.h" |
290 | + |
291 | +#include <memory> |
292 | +#include <string> |
293 | + |
294 | +namespace mir |
295 | +{ |
296 | +namespace graphics |
297 | +{ |
298 | +class CursorImage; |
299 | + |
300 | +/// CursorImages is used to lookup cursor images. |
301 | +class CursorImages |
302 | +{ |
303 | +public: |
304 | + virtual ~CursorImages() = default; |
305 | + |
306 | + /// Looks up the image for a named cursor. Cursor names |
307 | + /// follow the XCursor naming conventions. |
308 | + virtual std::shared_ptr<CursorImage> image(std::string const& cursor_name, |
309 | + geometry::Size const& size) = 0; |
310 | + |
311 | +protected: |
312 | + CursorImages() = default; |
313 | + CursorImages(CursorImages const&) = delete; |
314 | + CursorImages& operator=(CursorImages const&) = delete; |
315 | +}; |
316 | +} |
317 | +} |
318 | + |
319 | +#endif /* MIR_GRAPHICS_CURSOR_LOADER_H_ */ |
320 | |
321 | === modified file 'include/test/mir_test_doubles/mock_display.h' |
322 | --- include/test/mir_test_doubles/mock_display.h 2014-01-31 07:48:24 +0000 |
323 | +++ include/test/mir_test_doubles/mock_display.h 2014-04-28 23:16:18 +0000 |
324 | @@ -46,7 +46,7 @@ |
325 | graphics::DisplayResumeHandler const&)); |
326 | MOCK_METHOD0(pause, void()); |
327 | MOCK_METHOD0(resume, void()); |
328 | - MOCK_METHOD0(the_cursor, std::weak_ptr<graphics::Cursor>()); |
329 | + MOCK_METHOD1(create_hardware_cursor, std::shared_ptr<graphics::Cursor>(std::shared_ptr<graphics::CursorImage> const&)); |
330 | MOCK_METHOD0(create_gl_context, std::unique_ptr<graphics::GLContext>()); |
331 | }; |
332 | |
333 | |
334 | === modified file 'include/test/mir_test_doubles/null_display.h' |
335 | --- include/test/mir_test_doubles/null_display.h 2014-01-31 07:48:24 +0000 |
336 | +++ include/test/mir_test_doubles/null_display.h 2014-04-28 23:16:18 +0000 |
337 | @@ -58,7 +58,10 @@ |
338 | } |
339 | void pause() {} |
340 | void resume() {} |
341 | - std::weak_ptr<graphics::Cursor> the_cursor() { return {}; } |
342 | + std::shared_ptr<graphics::Cursor> create_hardware_cursor(std::shared_ptr<graphics::CursorImage> const& /* initial_image */) |
343 | + { |
344 | + return {}; |
345 | + } |
346 | std::unique_ptr<graphics::GLContext> create_gl_context() |
347 | { |
348 | return std::unique_ptr<NullGLContext>{new NullGLContext()}; |
349 | |
350 | === modified file 'src/platform/graphics/android/android_display.cpp' |
351 | --- src/platform/graphics/android/android_display.cpp 2014-04-16 17:07:02 +0000 |
352 | +++ src/platform/graphics/android/android_display.cpp 2014-04-28 23:16:18 +0000 |
353 | @@ -101,9 +101,9 @@ |
354 | { |
355 | } |
356 | |
357 | -auto mga::AndroidDisplay::the_cursor() -> std::weak_ptr<Cursor> |
358 | +auto mga::AndroidDisplay::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial_image */) -> std::shared_ptr<Cursor> |
359 | { |
360 | - return std::weak_ptr<Cursor>(); |
361 | + return std::shared_ptr<Cursor>(); |
362 | } |
363 | |
364 | std::unique_ptr<mg::GLContext> mga::AndroidDisplay::create_gl_context() |
365 | |
366 | === modified file 'src/platform/graphics/android/android_display.h' |
367 | --- src/platform/graphics/android/android_display.h 2014-04-16 17:07:02 +0000 |
368 | +++ src/platform/graphics/android/android_display.h 2014-04-28 23:16:18 +0000 |
369 | @@ -65,7 +65,7 @@ |
370 | void pause(); |
371 | void resume(); |
372 | |
373 | - std::weak_ptr<Cursor> the_cursor(); |
374 | + std::shared_ptr<Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image); |
375 | std::unique_ptr<graphics::GLContext> create_gl_context(); |
376 | |
377 | private: |
378 | |
379 | === modified file 'src/platform/graphics/mesa/cursor.cpp' |
380 | --- src/platform/graphics/mesa/cursor.cpp 2014-03-06 06:05:17 +0000 |
381 | +++ src/platform/graphics/mesa/cursor.cpp 2014-04-28 23:16:18 +0000 |
382 | @@ -22,20 +22,21 @@ |
383 | #include "kms_output_container.h" |
384 | #include "kms_display_configuration.h" |
385 | #include "mir/geometry/rectangle.h" |
386 | +#include "mir/graphics/cursor_image.h" |
387 | |
388 | #include <boost/exception/errinfo_errno.hpp> |
389 | |
390 | #include <stdexcept> |
391 | #include <vector> |
392 | |
393 | -namespace mgm = mir::graphics::mesa; |
394 | +namespace mg = mir::graphics; |
395 | +namespace mgm = mg::mesa; |
396 | namespace geom = mir::geometry; |
397 | |
398 | namespace |
399 | { |
400 | -#include "black_arrow.c" |
401 | -int const width = black_arrow.width; |
402 | -int const height = black_arrow.height; |
403 | +int const width = 64; |
404 | +int const height = 64; |
405 | |
406 | // Transforms a relative position within the display bounds described by \a rect which is rotated with \a orientation |
407 | geom::Displacement transform(geom::Rectangle const& rect, geom::Displacement const& vector, MirOrientation orientation) |
408 | @@ -72,13 +73,14 @@ |
409 | mgm::Cursor::Cursor( |
410 | gbm_device* gbm, |
411 | KMSOutputContainer& output_container, |
412 | - std::shared_ptr<CurrentConfiguration> const& current_configuration) : |
413 | + std::shared_ptr<CurrentConfiguration> const& current_configuration, |
414 | + std::shared_ptr<mg::CursorImage> const& initial_image) : |
415 | output_container(output_container), |
416 | current_position(), |
417 | buffer(gbm), |
418 | current_configuration(current_configuration) |
419 | { |
420 | - set_image(black_arrow.pixel_data, geometry::Size{width, height}); |
421 | + set_image(initial_image); |
422 | |
423 | show_at_last_known_position(); |
424 | } |
425 | @@ -88,14 +90,16 @@ |
426 | hide(); |
427 | } |
428 | |
429 | -void mgm::Cursor::set_image(const void* raw_argb, geometry::Size size) |
430 | +void mgm::Cursor::set_image(std::shared_ptr<CursorImage const> const& cursor_image) |
431 | { |
432 | + auto const& size = cursor_image->size(); |
433 | + |
434 | if (size != geometry::Size{width, height}) |
435 | BOOST_THROW_EXCEPTION(std::logic_error("No support for cursors that aren't 64x64")); |
436 | |
437 | auto const count = size.width.as_uint32_t() * size.height.as_uint32_t() * sizeof(uint32_t); |
438 | |
439 | - if (auto result = gbm_bo_write(buffer, raw_argb, count)) |
440 | + if (auto result = gbm_bo_write(buffer, cursor_image->as_argb_8888(), count)) |
441 | { |
442 | BOOST_THROW_EXCEPTION( |
443 | ::boost::enable_error_info(std::runtime_error("failed to initialize gbm buffer")) |
444 | |
445 | === modified file 'src/platform/graphics/mesa/cursor.h' |
446 | --- src/platform/graphics/mesa/cursor.h 2014-03-06 06:05:17 +0000 |
447 | +++ src/platform/graphics/mesa/cursor.h 2014-04-28 23:16:18 +0000 |
448 | @@ -34,6 +34,8 @@ |
449 | } |
450 | namespace graphics |
451 | { |
452 | +class CursorImage; |
453 | + |
454 | namespace mesa |
455 | { |
456 | class KMSOutputContainer; |
457 | @@ -61,11 +63,12 @@ |
458 | Cursor( |
459 | gbm_device* device, |
460 | KMSOutputContainer& output_container, |
461 | - std::shared_ptr<CurrentConfiguration> const& current_configuration); |
462 | + std::shared_ptr<CurrentConfiguration> const& current_configuration, |
463 | + std::shared_ptr<CursorImage> const& cursor_image); |
464 | |
465 | ~Cursor() noexcept; |
466 | |
467 | - void set_image(const void* raw_argb, geometry::Size size); |
468 | + void set_image(std::shared_ptr<CursorImage const> const& cursor_image); |
469 | |
470 | void move_to(geometry::Point position); |
471 | |
472 | |
473 | === modified file 'src/platform/graphics/mesa/display.cpp' |
474 | --- src/platform/graphics/mesa/display.cpp 2014-04-15 05:31:19 +0000 |
475 | +++ src/platform/graphics/mesa/display.cpp 2014-04-28 23:16:18 +0000 |
476 | @@ -224,7 +224,7 @@ |
477 | clear_connected_unused_outputs(); |
478 | } |
479 | |
480 | - if (cursor) cursor->show_at_last_known_position(); |
481 | + if (auto c = cursor.lock()) c->show_at_last_known_position(); |
482 | } |
483 | |
484 | void mgm::Display::register_configuration_change_handler( |
485 | @@ -255,7 +255,7 @@ |
486 | { |
487 | try |
488 | { |
489 | - if (cursor) cursor->hide(); |
490 | + if (auto c = cursor.lock()) c->hide(); |
491 | platform->drm.drop_master(); |
492 | } |
493 | catch(std::runtime_error const& e) |
494 | @@ -291,12 +291,16 @@ |
495 | clear_connected_unused_outputs(); |
496 | } |
497 | |
498 | - if (cursor) cursor->show_at_last_known_position(); |
499 | + if (auto c = cursor.lock()) c->show_at_last_known_position(); |
500 | } |
501 | |
502 | -auto mgm::Display::the_cursor() -> std::weak_ptr<graphics::Cursor> |
503 | +auto mgm::Display::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& initial_image) -> std::shared_ptr<graphics::Cursor> |
504 | { |
505 | - if (!cursor) |
506 | + // There is only one hardware cursor. We do not keep a strong reference to it in the display though, |
507 | + // if no other component of Mir is interested (i.e. the input stack does not keep a reference to send |
508 | + // position updates) we must be configured not to use a cursor and thusly let it deallocate. |
509 | + std::shared_ptr<mgm::Cursor> locked_cursor = cursor.lock(); |
510 | + if (!locked_cursor) |
511 | { |
512 | class KMSCurrentConfiguration : public CurrentConfiguration |
513 | { |
514 | @@ -317,11 +321,12 @@ |
515 | Display& display; |
516 | }; |
517 | |
518 | - cursor = std::make_shared<Cursor>(platform->gbm.device, output_container, |
519 | - std::make_shared<KMSCurrentConfiguration>(*this)); |
520 | + cursor = locked_cursor = std::make_shared<Cursor>(platform->gbm.device, output_container, |
521 | + std::make_shared<KMSCurrentConfiguration>(*this), |
522 | + initial_image); |
523 | } |
524 | |
525 | - return cursor; |
526 | + return locked_cursor; |
527 | } |
528 | |
529 | std::unique_ptr<mg::GLContext> mgm::Display::create_gl_context() |
530 | |
531 | === modified file 'src/platform/graphics/mesa/display.h' |
532 | --- src/platform/graphics/mesa/display.h 2014-03-27 09:46:09 +0000 |
533 | +++ src/platform/graphics/mesa/display.h 2014-04-28 23:16:18 +0000 |
534 | @@ -79,7 +79,7 @@ |
535 | void pause(); |
536 | void resume(); |
537 | |
538 | - std::weak_ptr<graphics::Cursor> the_cursor(); |
539 | + std::shared_ptr<graphics::Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image); |
540 | std::unique_ptr<GLContext> create_gl_context(); |
541 | |
542 | private: |
543 | @@ -93,7 +93,8 @@ |
544 | std::vector<std::unique_ptr<DisplayBuffer>> display_buffers; |
545 | RealKMSOutputContainer output_container; |
546 | mutable RealKMSDisplayConfiguration current_display_configuration; |
547 | - std::shared_ptr<Cursor> cursor; |
548 | + |
549 | + std::weak_ptr<Cursor> cursor; |
550 | std::shared_ptr<GLConfig> const gl_config; |
551 | }; |
552 | |
553 | |
554 | === modified file 'src/server/default_server_configuration.cpp' |
555 | --- src/server/default_server_configuration.cpp 2014-04-28 12:55:28 +0000 |
556 | +++ src/server/default_server_configuration.cpp 2014-04-28 23:16:18 +0000 |
557 | @@ -92,25 +92,22 @@ |
558 | { |
559 | struct DefaultCursorListener : mi::CursorListener |
560 | { |
561 | - DefaultCursorListener(std::weak_ptr<mg::Cursor> const& cursor) : |
562 | + DefaultCursorListener(std::shared_ptr<mg::Cursor> const& cursor) : |
563 | cursor(cursor) |
564 | { |
565 | } |
566 | |
567 | void cursor_moved_to(float abs_x, float abs_y) |
568 | { |
569 | - if (auto c = cursor.lock()) |
570 | - { |
571 | - c->move_to(geom::Point{abs_x, abs_y}); |
572 | - } |
573 | + cursor->move_to(geom::Point{abs_x, abs_y}); |
574 | } |
575 | |
576 | - std::weak_ptr<mg::Cursor> const cursor; |
577 | + std::shared_ptr<mg::Cursor> const cursor; |
578 | }; |
579 | return cursor_listener( |
580 | [this]() -> std::shared_ptr<mi::CursorListener> |
581 | { |
582 | - return std::make_shared<DefaultCursorListener>(the_display()->the_cursor()); |
583 | + return std::make_shared<DefaultCursorListener>(the_cursor()); |
584 | }); |
585 | } |
586 | |
587 | |
588 | === modified file 'src/server/graphics/CMakeLists.txt' |
589 | --- src/server/graphics/CMakeLists.txt 2014-04-24 08:42:12 +0000 |
590 | +++ src/server/graphics/CMakeLists.txt 2014-04-28 23:16:18 +0000 |
591 | @@ -9,6 +9,7 @@ |
592 | gl_program.cpp |
593 | program_factory.cpp |
594 | surfaceless_egl_context.cpp |
595 | + builtin_cursor_images.cpp |
596 | ) |
597 | |
598 | add_subdirectory(nested/) |
599 | |
600 | === renamed file 'src/platform/graphics/mesa/black_arrow.c' => 'src/server/graphics/black_arrow.c' |
601 | === renamed file 'src/platform/graphics/mesa/black_arrow.xcf' => 'src/server/graphics/black_arrow.xcf' |
602 | === added file 'src/server/graphics/builtin_cursor_images.cpp' |
603 | --- src/server/graphics/builtin_cursor_images.cpp 1970-01-01 00:00:00 +0000 |
604 | +++ src/server/graphics/builtin_cursor_images.cpp 2014-04-28 23:16:18 +0000 |
605 | @@ -0,0 +1,52 @@ |
606 | +/* |
607 | + * Copyright © 2014 Canonical Ltd. |
608 | + * |
609 | + * This program is free software: you can redistribute it and/or modify it |
610 | + * under the terms of the GNU General Public License version 3, |
611 | + * as published by the Free Software Foundation. |
612 | + * |
613 | + * This program is distributed in the hope that it will be useful, |
614 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
615 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
616 | + * GNU General Public License for more details. |
617 | + * |
618 | + * You should have received a copy of the GNU General Public License |
619 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
620 | + * |
621 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
622 | + */ |
623 | + |
624 | +#include "black_arrow.c" |
625 | +#include "builtin_cursor_images.h" |
626 | + |
627 | +#include "mir/graphics/cursor_image.h" |
628 | + |
629 | +namespace mg = mir::graphics; |
630 | +namespace geom = mir::geometry; |
631 | + |
632 | +namespace |
633 | +{ |
634 | +struct BlackArrowCursorImage : public mg::CursorImage |
635 | +{ |
636 | + void const* as_argb_8888() const |
637 | + { |
638 | + return black_arrow.pixel_data; |
639 | + } |
640 | + geom::Size size() const |
641 | + { |
642 | + return { black_arrow.width, black_arrow.height }; |
643 | + } |
644 | +}; |
645 | +} |
646 | + |
647 | +mg::BuiltinCursorImages::BuiltinCursorImages() |
648 | + : builtin_image(std::make_shared<BlackArrowCursorImage>()) |
649 | +{ |
650 | +} |
651 | + |
652 | +std::shared_ptr<mg::CursorImage> mg::BuiltinCursorImages::image(std::string const& /* cursor_name */, |
653 | + geom::Size const& /* size */) |
654 | +{ |
655 | + // Builtin repository only has one cursor at a single size. |
656 | + return builtin_image; |
657 | +} |
658 | |
659 | === added file 'src/server/graphics/builtin_cursor_images.h' |
660 | --- src/server/graphics/builtin_cursor_images.h 1970-01-01 00:00:00 +0000 |
661 | +++ src/server/graphics/builtin_cursor_images.h 2014-04-28 23:16:18 +0000 |
662 | @@ -0,0 +1,51 @@ |
663 | +/* |
664 | + * Copyright © 2014 Canonical Ltd. |
665 | + * |
666 | + * This program is free software: you can redistribute it and/or modify it |
667 | + * under the terms of the GNU General Public License version 3, |
668 | + * as published by the Free Software Foundation. |
669 | + * |
670 | + * This program is distributed in the hope that it will be useful, |
671 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
672 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
673 | + * GNU General Public License for more details. |
674 | + * |
675 | + * You should have received a copy of the GNU General Public License |
676 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
677 | + * |
678 | + * Authored by: Robert Carr <robert.carr@canonical.com> |
679 | + */ |
680 | + |
681 | + |
682 | +#ifndef MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ |
683 | +#define MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ |
684 | + |
685 | +#include "mir/graphics/cursor_images.h" |
686 | + |
687 | +namespace mir |
688 | +{ |
689 | +namespace graphics |
690 | +{ |
691 | +class CursorImage; |
692 | + |
693 | +class BuiltinCursorImages : public CursorImages |
694 | +{ |
695 | +public: |
696 | + BuiltinCursorImages(); |
697 | + virtual ~BuiltinCursorImages() = default; |
698 | + |
699 | + std::shared_ptr<CursorImage> image(std::string const& cursor_name, |
700 | + geometry::Size const& size); |
701 | + |
702 | +protected: |
703 | + BuiltinCursorImages(BuiltinCursorImages const&) = delete; |
704 | + BuiltinCursorImages& operator=(BuiltinCursorImages const&) = delete; |
705 | + |
706 | +private: |
707 | + std::shared_ptr<CursorImage> const builtin_image; |
708 | +}; |
709 | +} |
710 | +} |
711 | + |
712 | + |
713 | +#endif /* MIR_GRAPHICS_BUILTIN_CURSOR_LOADER_H_ */ |
714 | |
715 | === modified file 'src/server/graphics/default_configuration.cpp' |
716 | --- src/server/graphics/default_configuration.cpp 2014-04-25 12:35:50 +0000 |
717 | +++ src/server/graphics/default_configuration.cpp 2014-04-28 23:16:18 +0000 |
718 | @@ -35,6 +35,8 @@ |
719 | |
720 | #include <boost/throw_exception.hpp> |
721 | |
722 | +#include "builtin_cursor_images.h" |
723 | + |
724 | #include <map> |
725 | |
726 | namespace mg = mir::graphics; |
727 | @@ -116,6 +118,39 @@ |
728 | }); |
729 | } |
730 | |
731 | +std::shared_ptr<mg::Cursor> |
732 | +mir::DefaultServerConfiguration::the_cursor() |
733 | +{ |
734 | + return cursor( |
735 | + [this]() -> std::shared_ptr<mg::Cursor> |
736 | + { |
737 | + // For now we only support a hardware cursor. |
738 | + return the_display()->create_hardware_cursor(the_default_cursor_image()); |
739 | + }); |
740 | +} |
741 | + |
742 | +std::shared_ptr<mg::CursorImage> |
743 | +mir::DefaultServerConfiguration::the_default_cursor_image() |
744 | +{ |
745 | + static geometry::Size const default_cursor_size = {geometry::Width{64}, |
746 | + geometry::Height{64}}; |
747 | + return default_cursor_image( |
748 | + [this]() |
749 | + { |
750 | + return the_cursor_images()->image("arrow", default_cursor_size); |
751 | + }); |
752 | +} |
753 | + |
754 | +std::shared_ptr<mg::CursorImages> |
755 | +mir::DefaultServerConfiguration::the_cursor_images() |
756 | +{ |
757 | + return cursor_images( |
758 | + [this]() |
759 | + { |
760 | + return std::make_shared<mg::BuiltinCursorImages>(); |
761 | + }); |
762 | +} |
763 | + |
764 | auto mir::DefaultServerConfiguration::the_host_connection() |
765 | -> std::shared_ptr<graphics::nested::HostConnection> |
766 | { |
767 | |
768 | === modified file 'src/server/graphics/nested/nested_display.cpp' |
769 | --- src/server/graphics/nested/nested_display.cpp 2014-04-24 08:42:12 +0000 |
770 | +++ src/server/graphics/nested/nested_display.cpp 2014-04-28 23:16:18 +0000 |
771 | @@ -259,10 +259,10 @@ |
772 | // TODO If we "own" the cursor then we need to restore it |
773 | } |
774 | |
775 | -auto mgn::NestedDisplay::the_cursor()->std::weak_ptr<Cursor> |
776 | +auto mgn::NestedDisplay::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial image */)->std::shared_ptr<Cursor> |
777 | { |
778 | // TODO Do we "own" the cursor or does the host mir? |
779 | - return std::weak_ptr<Cursor>(); |
780 | + return std::shared_ptr<Cursor>(); |
781 | } |
782 | |
783 | std::unique_ptr<mg::GLContext> mgn::NestedDisplay::create_gl_context() |
784 | |
785 | === modified file 'src/server/graphics/nested/nested_display.h' |
786 | --- src/server/graphics/nested/nested_display.h 2014-04-24 08:42:12 +0000 |
787 | +++ src/server/graphics/nested/nested_display.h 2014-04-28 23:16:18 +0000 |
788 | @@ -120,7 +120,7 @@ |
789 | void pause() override; |
790 | void resume() override; |
791 | |
792 | - std::weak_ptr<Cursor> the_cursor() override; |
793 | + std::shared_ptr<Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image) override; |
794 | std::unique_ptr<graphics::GLContext> create_gl_context() override; |
795 | |
796 | private: |
797 | |
798 | === modified file 'src/server/graphics/offscreen/display.cpp' |
799 | --- src/server/graphics/offscreen/display.cpp 2014-03-26 05:48:59 +0000 |
800 | +++ src/server/graphics/offscreen/display.cpp 2014-04-28 23:16:18 +0000 |
801 | @@ -163,7 +163,7 @@ |
802 | { |
803 | } |
804 | |
805 | -std::weak_ptr<mg::Cursor> mgo::Display::the_cursor() |
806 | +std::shared_ptr<mg::Cursor> mgo::Display::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial_image */) |
807 | { |
808 | return {}; |
809 | } |
810 | |
811 | === modified file 'src/server/graphics/offscreen/display.h' |
812 | --- src/server/graphics/offscreen/display.h 2014-01-31 07:48:24 +0000 |
813 | +++ src/server/graphics/offscreen/display.h 2014-04-28 23:16:18 +0000 |
814 | @@ -86,7 +86,7 @@ |
815 | void pause(); |
816 | void resume(); |
817 | |
818 | - std::weak_ptr<Cursor> the_cursor(); |
819 | + std::shared_ptr<Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image); |
820 | std::unique_ptr<GLContext> create_gl_context(); |
821 | |
822 | private: |
823 | |
824 | === modified file 'tests/unit-tests/graphics/mesa/test_cursor.cpp' |
825 | --- tests/unit-tests/graphics/mesa/test_cursor.cpp 2014-03-26 05:48:59 +0000 |
826 | +++ tests/unit-tests/graphics/mesa/test_cursor.cpp 2014-04-28 23:16:18 +0000 |
827 | @@ -21,6 +21,8 @@ |
828 | #include "src/platform/graphics/mesa/kms_output_container.h" |
829 | #include "src/platform/graphics/mesa/kms_display_configuration.h" |
830 | |
831 | +#include "mir/graphics/cursor_image.h" |
832 | + |
833 | #include "mir_test_doubles/mock_gbm.h" |
834 | #include "mir_test/fake_shared.h" |
835 | #include "mock_kms_output.h" |
836 | @@ -31,11 +33,14 @@ |
837 | #include <unordered_map> |
838 | #include <algorithm> |
839 | |
840 | +#include <string.h> |
841 | + |
842 | namespace mg = mir::graphics; |
843 | namespace mgm = mir::graphics::mesa; |
844 | namespace geom = mir::geometry; |
845 | -namespace mtd = mir::test::doubles; |
846 | -using mir::test::MockKMSOutput; |
847 | +namespace mt = mir::test; |
848 | +namespace mtd = mt::doubles; |
849 | +using mt::MockKMSOutput; |
850 | |
851 | namespace |
852 | { |
853 | @@ -196,15 +201,31 @@ |
854 | StubKMSDisplayConfiguration conf; |
855 | }; |
856 | |
857 | +struct StubCursorImage : public mg::CursorImage |
858 | +{ |
859 | + void const* as_argb_8888() const |
860 | + { |
861 | + return image_data; |
862 | + } |
863 | + geom::Size size() const |
864 | + { |
865 | + return geom::Size{geom::Width{64}, geom::Height{64}}; |
866 | + } |
867 | + static void const* image_data; |
868 | +}; |
869 | +void const* StubCursorImage::image_data = reinterpret_cast<void*>(&StubCursorImage::image_data); |
870 | + |
871 | struct MesaCursorTest : public ::testing::Test |
872 | { |
873 | MesaCursorTest() |
874 | : cursor{mock_gbm.fake_gbm.device, output_container, |
875 | - mir::test::fake_shared(current_configuration)} |
876 | + mt::fake_shared(current_configuration), |
877 | + mt::fake_shared(stub_image)} |
878 | { |
879 | } |
880 | |
881 | StubCurrentConfiguration current_configuration; |
882 | + StubCursorImage stub_image; |
883 | testing::NiceMock<mtd::MockGBM> mock_gbm; |
884 | StubKMSOutputContainer output_container; |
885 | mgm::Cursor cursor; |
886 | @@ -221,33 +242,40 @@ |
887 | GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE)); |
888 | |
889 | mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container, |
890 | - std::make_shared<StubCurrentConfiguration>()}; |
891 | + std::make_shared<StubCurrentConfiguration>(), |
892 | + std::make_shared<StubCursorImage>()}; |
893 | } |
894 | |
895 | TEST_F(MesaCursorTest, set_cursor_writes_to_bo) |
896 | { |
897 | using namespace testing; |
898 | |
899 | - void* const image{reinterpret_cast<void*>(0x5678)}; |
900 | + StubCursorImage image; |
901 | size_t const cursor_side{64}; |
902 | geom::Size const cursor_size{cursor_side, cursor_side}; |
903 | size_t const cursor_size_bytes{cursor_side * cursor_side * sizeof(uint32_t)}; |
904 | |
905 | - EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, image, cursor_size_bytes)); |
906 | + EXPECT_CALL(mock_gbm, gbm_bo_write(mock_gbm.fake_gbm.bo, StubCursorImage::image_data, cursor_size_bytes)); |
907 | |
908 | - cursor.set_image(image, cursor_size); |
909 | + cursor.set_image(mt::fake_shared(image)); |
910 | } |
911 | |
912 | TEST_F(MesaCursorTest, set_cursor_throws_on_incorrect_size) |
913 | { |
914 | using namespace testing; |
915 | |
916 | - void* const image{reinterpret_cast<void*>(0x5678)}; |
917 | - size_t const cursor_side{48}; |
918 | - geom::Size const cursor_size{cursor_side, cursor_side}; |
919 | + struct InvalidlySizedCursorImage : public StubCursorImage |
920 | + { |
921 | + geom::Size size() const |
922 | + { |
923 | + return invalid_cursor_size; |
924 | + } |
925 | + size_t const cursor_side{48}; |
926 | + geom::Size const invalid_cursor_size{cursor_side, cursor_side}; |
927 | + }; |
928 | |
929 | EXPECT_THROW( |
930 | - cursor.set_image(image, cursor_size); |
931 | + cursor.set_image(std::make_shared<InvalidlySizedCursorImage>()); |
932 | , std::logic_error); |
933 | } |
934 | |
935 | @@ -266,7 +294,8 @@ |
936 | EXPECT_CALL(*output_container.outputs[12], has_cursor()).Times(0); |
937 | |
938 | mgm::Cursor cursor_tmp{mock_gbm.fake_gbm.device, output_container, |
939 | - std::make_shared<StubCurrentConfiguration>()}; |
940 | + std::make_shared<StubCurrentConfiguration>(), |
941 | + std::make_shared<StubCursorImage>()}; |
942 | |
943 | output_container.verify_and_clear_expectations(); |
944 | } |
FAILED: Continuous integration, rev:1472 jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- ci/1055/ jenkins. qa.ubuntu. com/job/ mir-android- trusty- i386-build/ 1217 jenkins. qa.ubuntu. com/job/ mir-clang- trusty- amd64-build/ 1215/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -trusty- touch/799/ console jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- trusty- amd64-ci/ 787/console jenkins. qa.ubuntu. com/job/ mir-team- mir-development -branch- trusty- armhf-ci/ 792/console jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- trusty- armhf/800/ console
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- team-mir- development- branch- ci/1055/ rebuild
http://