genode/repos/os/src/server/nitpicker/session_component.h

406 lines
11 KiB
C
Raw Normal View History

/*
* \brief Nitpicker session component
* \author Norman Feske
* \date 2017-11-16
*/
/*
* Copyright (C) 2006-2017 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _SESSION_COMPONENT_H_
#define _SESSION_COMPONENT_H_
/* Genode includes */
#include <util/list.h>
#include <base/session_object.h>
#include <base/heap.h>
#include <os/session_policy.h>
#include <os/reporter.h>
#include <os/pixel_rgb565.h>
#include <nitpicker_session/nitpicker_session.h>
/* local includes */
#include "canvas.h"
#include "domain_registry.h"
#include "framebuffer_session.h"
#include "input_session.h"
#include "focus.h"
#include "chunky_texture.h"
#include "view_component.h"
namespace Nitpicker {
class Visibility_controller;
class Session_component;
class View_component;
typedef List<Session_component> Session_list;
}
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
struct Nitpicker::Visibility_controller : Interface
{
typedef Session::Label Suffix;
virtual void hide_matching_sessions(Session_label const &, Suffix const &) = 0;
virtual void show_matching_sessions(Session_label const &, Suffix const &) = 0;
};
class Nitpicker::Session_component : public Session_object<Nitpicker::Session>,
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
public View_owner,
public Buffer_provider,
private Session_list::Element
{
private:
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
friend class List<Session_component>;
using Nitpicker::Session::Label;
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
/*
* Noncopyable
*/
Session_component(Session_component const &);
Session_component &operator = (Session_component const &);
Env &_env;
Constrained_ram_allocator _ram;
Domain_registry::Entry const *_domain = nullptr;
Texture_base const *_texture = nullptr;
View_component *_background = nullptr;
/*
* The input mask buffer containing a byte value per texture pixel,
* which describes the policy of handling user input referring to the
* pixel. If set to zero, the input is passed through the view such
* that it can be handled by one of the subsequent views in the view
* stack. If set to one, the input is consumed by the view. If
* 'input_mask' is a null pointer, user input is unconditionally
* consumed by the view.
*/
unsigned char const *_input_mask = nullptr;
bool _uses_alpha = false;
bool _visible = true;
Sliced_heap _session_alloc;
Framebuffer::Session &_framebuffer;
Framebuffer::Session_component _framebuffer_session_component;
bool const _input_session_accounted = (
withdraw(Ram_quota{Input::Session_component::ev_ds_size()}), true );
Input::Session_component _input_session_component { _env };
View_stack &_view_stack;
Font const &_font;
Focus_updater &_focus_updater;
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
Signal_context_capability _mode_sigh { };
View_component &_pointer_origin;
View_component &_builtin_background;
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
List<Session_view_list_elem> _view_list { };
Tslab<View_component, 4000> _view_alloc { &_session_alloc };
/* capabilities for sub sessions */
Framebuffer::Session_capability _framebuffer_session_cap;
Input::Session_capability _input_session_cap;
bool const _provides_default_bg;
/* size of currently allocated virtual framebuffer, in bytes */
size_t _buffer_size = 0;
Attached_ram_dataspace _command_ds { _env.ram(), _env.rm(),
sizeof(Command_buffer) };
bool const _command_buffer_accounted = (
withdraw(Ram_quota{align_addr(sizeof(Session::Command_buffer), 12)}), true );
Command_buffer &_command_buffer = *_command_ds.local_addr<Command_buffer>();
typedef Handle_registry<View_handle, View_component> View_handle_registry;
View_handle_registry _view_handle_registry;
Reporter &_focus_reporter;
Visibility_controller &_visibility_controller;
Session_component *_forwarded_focus = nullptr;
/**
* Calculate session-local coordinate to physical screen position
*
* \param pos coordinate in session-local coordinate system
* \param screen_area session-local screen size
*/
Point _phys_pos(Point pos, Area screen_area) const
{
return _domain ? _domain->phys_pos(pos, screen_area) : Point(0, 0);
}
void _release_buffer();
/**
* Helper for performing sanity checks in OP_TO_FRONT and OP_TO_BACK
*
* We have to check for the equality of both the specified view and
* neighbor. If both arguments refer to the same view, the creation of
* locked pointers for both views would result in a deadlock.
*/
bool _views_are_equal(View_handle, View_handle);
void _execute_command(Command const &);
void _destroy_view(View_component &);
public:
Session_component(Env &env,
Resources const &resources,
Label const &label,
Diag const &diag,
View_stack &view_stack,
Font const &font,
Focus_updater &focus_updater,
View_component &pointer_origin,
View_component &builtin_background,
Framebuffer::Session &framebuffer,
bool provides_default_bg,
Reporter &focus_reporter,
Visibility_controller &visibility_controller)
:
Session_object(env.ep(), resources, label, diag),
_env(env),
_ram(env.ram(), _ram_quota_guard(), _cap_quota_guard()),
_session_alloc(_ram, env.rm()),
_framebuffer(framebuffer),
_framebuffer_session_component(view_stack, *this, framebuffer, *this),
_view_stack(view_stack), _font(font), _focus_updater(focus_updater),
_pointer_origin(pointer_origin),
_builtin_background(builtin_background),
_framebuffer_session_cap(_env.ep().manage(_framebuffer_session_component)),
_input_session_cap(_env.ep().manage(_input_session_component)),
_provides_default_bg(provides_default_bg),
_view_handle_registry(_session_alloc),
_focus_reporter(focus_reporter),
_visibility_controller(visibility_controller)
{ }
~Session_component()
{
_env.ep().dissolve(_framebuffer_session_component);
_env.ep().dissolve(_input_session_component);
destroy_all_views();
_release_buffer();
}
Follow practices suggested by "Effective C++" The patch adjust the code of the base, base-<kernel>, and os repository. To adapt existing components to fix violations of the best practices suggested by "Effective C++" as reported by the -Weffc++ compiler argument. The changes follow the patterns outlined below: * A class with virtual functions can no longer publicly inherit base classed without a vtable. The inherited object may either be moved to a member variable, or inherited privately. The latter would be used for classes that inherit 'List::Element' or 'Avl_node'. In order to enable the 'List' and 'Avl_tree' to access the meta data, the 'List' must become a friend. * Instead of adding a virtual destructor to abstract base classes, we inherit the new 'Interface' class, which contains a virtual destructor. This way, single-line abstract base classes can stay as compact as they are now. The 'Interface' utility resides in base/include/util/interface.h. * With the new warnings enabled, all member variables must be explicitly initialized. Basic types may be initialized with '='. All other types are initialized with braces '{ ... }' or as class initializers. If basic types and non-basic types appear in a row, it is nice to only use the brace syntax (also for basic types) and align the braces. * If a class contains pointers as members, it must now also provide a copy constructor and assignment operator. In the most cases, one would make them private, effectively disallowing the objects to be copied. Unfortunately, this warning cannot be fixed be inheriting our existing 'Noncopyable' class (the compiler fails to detect that the inheriting class cannot be copied and still gives the error). For now, we have to manually add declarations for both the copy constructor and assignment operator as private class members. Those declarations should be prepended with a comment like this: /* * Noncopyable */ Thread(Thread const &); Thread &operator = (Thread const &); In the future, we should revisit these places and try to replace the pointers with references. In the presence of at least one reference member, the compiler would no longer implicitly generate a copy constructor. So we could remove the manual declaration. Issue #465
2017-12-21 15:42:15 +01:00
using Session_list::Element::next;
/**************************
** View_owner interface **
**************************/
Session::Label label() const override { return _label; }
/**
* Return true if session label starts with specified 'selector'
*/
bool matches_session_label(Session::Label const &selector) const override
{
/*
* Append label separator to match selectors with a trailing
* separator.
*/
String<Session_label::capacity() + 4> const label(_label, " ->");
return strcmp(label.string(), selector.string(),
strlen(selector.string())) == 0;
}
bool visible() const override { return _visible; }
bool label_visible() const override
{
return !_domain || _domain->label_visible();
}
bool has_same_domain(View_owner const *owner) const override
{
if (!owner) return false;
return static_cast<Session_component const &>(*owner)._domain == _domain;
}
bool has_focusable_domain() const override
{
return _domain && (_domain->focus_click() || _domain->focus_transient());
}
bool has_transient_focusable_domain() const override
{
return _domain && _domain->focus_transient();
}
Color color() const override { return _domain ? _domain->color() : white(); }
bool content_client() const override { return _domain && _domain->content_client(); }
bool hover_always() const override { return _domain && _domain->hover_always(); }
View const *background() const override { return _background; }
Texture_base const *texture() const override { return _texture; }
bool uses_alpha() const override { return _texture && _uses_alpha; }
unsigned layer() const override { return _domain ? _domain->layer() : ~0UL; }
bool origin_pointer() const override { return _domain && _domain->origin_pointer(); }
/**
* Return input mask value at specified buffer position
*/
unsigned char input_mask_at(Point p) const override
{
if (!_input_mask || !_texture) return 0;
/* check boundaries */
if ((unsigned)p.x() >= _texture->size().w()
|| (unsigned)p.y() >= _texture->size().h())
return 0;
return _input_mask[p.y()*_texture->size().w() + p.x()];
}
void submit_input_event(Input::Event e) override;
void report(Xml_generator &xml) const override
{
xml.attribute("label", _label);
xml.attribute("color", String<32>(color()));
if (_domain)
xml.attribute("domain", _domain->name());
}
View_owner &forwarded_focus() override;
/****************************************
** Interface used by the main program **
****************************************/
/**
* Set the visibility of the views owned by the session
*/
void visible(bool visible) { _visible = visible; }
/**
* Return session-local screen area
*
* \param phys_pos size of physical screen
*/
Area screen_area(Area phys_area) const
{
return _domain ? _domain->screen_area(phys_area) : Area(0, 0);
}
void reset_domain() { _domain = nullptr; }
/**
* Set session domain according to the list of configured policies
*
* Select the policy that matches the label. If multiple policies
* match, select the one with the largest number of characters.
*/
void apply_session_policy(Xml_node config, Domain_registry const &);
void destroy_all_views();
/**
* Deliver mode-change signal to client
*/
void notify_mode_change()
{
if (_mode_sigh.valid())
Signal_transmitter(_mode_sigh).submit();
}
/**
* Deliver sync signal to the client's virtual frame buffer
*/
void submit_sync()
{
_framebuffer_session_component.submit_sync();
}
void forget(Session_component &session)
{
if (_forwarded_focus == &session)
_forwarded_focus = nullptr;
}
/*********************************
** Nitpicker session interface **
*********************************/
Framebuffer::Session_capability framebuffer_session() override {
return _framebuffer_session_cap; }
Input::Session_capability input_session() override {
return _input_session_cap; }
View_handle create_view(View_handle parent_handle) override;
void destroy_view(View_handle handle) override;
View_handle view_handle(View_capability view_cap, View_handle handle) override;
View_capability view_capability(View_handle handle) override;
void release_view_handle(View_handle handle) override;
Dataspace_capability command_dataspace() override { return _command_ds.cap(); }
void execute() override;
Framebuffer::Mode mode() override;
void mode_sigh(Signal_context_capability sigh) override { _mode_sigh = sigh; }
void buffer(Framebuffer::Mode mode, bool use_alpha) override;
void focus(Capability<Nitpicker::Session> session_cap) override;
void session_control(Label suffix, Session_control control) override;
/*******************************
** Buffer_provider interface **
*******************************/
Buffer *realloc_buffer(Framebuffer::Mode mode, bool use_alpha) override;
};
#endif /* _SESSION_COMPONENT_H_ */