diff --git a/demo/src/server/liquid_framebuffer/services.cc b/demo/src/server/liquid_framebuffer/services.cc index 0c797450d..aea1565f8 100644 --- a/demo/src/server/liquid_framebuffer/services.cc +++ b/demo/src/server/liquid_framebuffer/services.cc @@ -196,7 +196,10 @@ namespace Framebuffer { public: - Genode::Dataspace_capability dataspace() { return _window_content->fb_ds_cap(); } + Genode::Dataspace_capability dataspace() { + return _window_content->fb_ds_cap(); } + + void release() { } Mode mode() { @@ -204,6 +207,8 @@ namespace Framebuffer Mode::RGB565); } + void mode_sigh(Genode::Signal_context_capability) { } + void refresh(int x, int y, int w, int h) { window_content()->redraw_area(x, y, w, h); } }; diff --git a/os/include/framebuffer_session/client.h b/os/include/framebuffer_session/client.h index 1d147cc83..8dac8092c 100644 --- a/os/include/framebuffer_session/client.h +++ b/os/include/framebuffer_session/client.h @@ -27,8 +27,12 @@ namespace Framebuffer { Genode::Dataspace_capability dataspace() { return call(); } - Mode mode() { - return call(); } + void release() { call(); } + + Mode mode() { return call(); } + + void mode_sigh(Genode::Signal_context_capability sigh) { + call(sigh); } void refresh(int x, int y, int w, int h) { call(x, y, w, h); } diff --git a/os/include/framebuffer_session/framebuffer_session.h b/os/include/framebuffer_session/framebuffer_session.h index 07803fbff..f19948a88 100644 --- a/os/include/framebuffer_session/framebuffer_session.h +++ b/os/include/framebuffer_session/framebuffer_session.h @@ -14,11 +14,15 @@ #ifndef _INCLUDE__FRAMEBUFFER_SESSION__FRAMEBUFFER_SESSION_H_ #define _INCLUDE__FRAMEBUFFER_SESSION__FRAMEBUFFER_SESSION_H_ +#include #include #include namespace Framebuffer { + /** + * Framebuffer mode info as returned by 'Framebuffer::Session::mode()' + */ struct Mode { public: @@ -57,6 +61,7 @@ namespace Framebuffer { return bytes_per_pixel(_format); } }; + struct Session : Genode::Session { static const char *service_name() { return "Framebuffer"; } @@ -69,10 +74,35 @@ namespace Framebuffer { virtual Genode::Dataspace_capability dataspace() = 0; /** - * Request current screen mode properties + * Release framebuffer, free dataspace + * + * By calling this function, the framebuffer client enables the server + * to reallocate the framebuffer dataspace on mode changes. Prior + * calling this function, the client should have detached the dataspace + * from its local address space. + */ + virtual void release() = 0; + + /** + * Request current display-mode properties */ virtual Mode mode() = 0; + /** + * Register signal handler to be notified on mode changes + * + * The framebuffer server may support changing the display mode on the + * fly. For example, a virtual framebuffer presented in a window may + * get resized according to the window dimensions. By installing a + * signal handler for mode changes, the framebuffer client can respond + * to such changes. From the client's perspective, the original mode + * stays in effect until the client calls 'release()'. After having + * released the framebuffer, the new mode can be obtained using the + * 'mode()' function and a new framebuffer dataspace can be requested + * by calling 'dataspace()'. + */ + virtual void mode_sigh(Genode::Signal_context_capability sigh) = 0; + /** * Flush specified pixel region * @@ -86,10 +116,13 @@ namespace Framebuffer { *********************/ GENODE_RPC(Rpc_dataspace, Genode::Dataspace_capability, dataspace); + GENODE_RPC(Rpc_release, void, release); GENODE_RPC(Rpc_mode, Mode, mode); GENODE_RPC(Rpc_refresh, void, refresh, int, int, int, int); + GENODE_RPC(Rpc_mode_sigh, void, mode_sigh, Genode::Signal_context_capability); - GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_mode, Rpc_refresh); + GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_release, Rpc_mode, + Rpc_mode_sigh, Rpc_refresh); }; } diff --git a/os/src/drivers/framebuffer/fiasco_ux/main.cc b/os/src/drivers/framebuffer/fiasco_ux/main.cc index 354f2e343..1fd51945b 100644 --- a/os/src/drivers/framebuffer/fiasco_ux/main.cc +++ b/os/src/drivers/framebuffer/fiasco_ux/main.cc @@ -45,17 +45,18 @@ namespace Framebuffer { Dataspace_capability dataspace() { return Framebuffer_drv::hw_framebuffer(); } - void info(int *out_w, int *out_h, Mode *out_mode) - { - *out_w = scr_width; - *out_h = scr_height; + void release() { } - switch (scr_mode) { - case 16: *out_mode = RGB565; break; - default: *out_mode = INVALID; - } + Mode mode() + { + if (scr_mode != 16) + return Mode(); /* invalid mode */ + + return Mode(scr_width, scr_height, Mode::RGB565); } + void mode_sigh(Genode::Signal_context_capability sigh) { } + void refresh(int x, int y, int w, int h) { #if 0 diff --git a/os/src/drivers/framebuffer/pl11x/main.cc b/os/src/drivers/framebuffer/pl11x/main.cc index 224d369e7..ecabd96ef 100644 --- a/os/src/drivers/framebuffer/pl11x/main.cc +++ b/os/src/drivers/framebuffer/pl11x/main.cc @@ -165,8 +165,12 @@ namespace Framebuffer Genode::Dataspace_capability dataspace() { return _fb_ds_cap; } + void release() { } + Mode mode() { return Mode(SCR_WIDTH, SCR_HEIGHT, Mode::RGB565); } + void mode_sigh(Genode::Signal_context_capability) { } + void refresh(int x, int y, int w, int h) { } }; diff --git a/os/src/drivers/framebuffer/sdl/fb_sdl.cc b/os/src/drivers/framebuffer/sdl/fb_sdl.cc index a450b73c3..6eb8a42b5 100644 --- a/os/src/drivers/framebuffer/sdl/fb_sdl.cc +++ b/os/src/drivers/framebuffer/sdl/fb_sdl.cc @@ -61,8 +61,12 @@ namespace Framebuffer { Genode::Dataspace_capability dataspace() { return fb_ds_cap; } + void release() { } + Mode mode() { return _mode; } + void mode_sigh(Genode::Signal_context_capability) { } + void refresh(int x, int y, int w, int h) { /* clip refresh area to screen boundaries */ diff --git a/os/src/drivers/framebuffer/vesa/main.cc b/os/src/drivers/framebuffer/vesa/main.cc index 9deea9b26..34392ef64 100644 --- a/os/src/drivers/framebuffer/vesa/main.cc +++ b/os/src/drivers/framebuffer/vesa/main.cc @@ -150,12 +150,16 @@ namespace Framebuffer { return _buffered ? Dataspace_capability(_bb_ds) : Dataspace_capability(_fb_ds); } + void release() { } + Mode mode() { return Mode(_scr_width, _scr_height, _scr_mode == 16 ? Mode::RGB565 : Mode::INVALID); } + void mode_sigh(Genode::Signal_context_capability) { } + /* not implemented */ void refresh(int x, int y, int w, int h) { diff --git a/os/src/server/nitpicker/genode/main.cc b/os/src/server/nitpicker/genode/main.cc index f20447093..df0a6d2bd 100644 --- a/os/src/server/nitpicker/genode/main.cc +++ b/os/src/server/nitpicker/genode/main.cc @@ -341,12 +341,16 @@ namespace Framebuffer { Genode::Dataspace_capability dataspace() { return _buffer->ds_cap(); } + void release() { } + Mode mode() { return Mode(_buffer->size().w(), _buffer->size().h(), _buffer->format()); } + void mode_sigh(Genode::Signal_context_capability) { } + void refresh(int x, int y, int w, int h) { _view_stack->update_session_views(_session,