From dd98bd67a01eb37ad9da6c87383293fd1ac9da9e Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Fri, 24 Nov 2017 18:56:25 +0100 Subject: [PATCH] pointer: custom pointer shape support Make the revised 'vbox_pointer' component the new 'pointer' component. Fixes #2585 --- .../include/pointer}/dither_painter.h | 0 .../include/pointer}/shape_report.h | 10 +- repos/os/recipes/src/nitpicker/content.mk | 8 + .../vbox_pointer.run => os/run/pointer.run} | 18 +- repos/os/src/app/pointer/README | 39 ++ repos/os/src/app/pointer/main.cc | 354 +++++++++++++++- .../src/app/pointer}/rom_registry.h | 0 .../src/app/pointer}/util.h | 14 +- .../src/test/pointer}/main.cc | 8 +- .../src/test/pointer}/target.mk | 2 +- repos/ports/recipes/src/vbox5-nova/content.mk | 4 +- .../ports/recipes/src/vbox_pointer/content.mk | 7 - repos/ports/recipes/src/vbox_pointer/hash | 1 - .../ports/recipes/src/vbox_pointer/used_apis | 6 - repos/ports/run/vbox_win.inc | 14 +- repos/ports/run/virtualbox.run | 16 +- repos/ports/src/app/vbox_pointer/README | 26 -- repos/ports/src/app/vbox_pointer/big_mouse.h | 36 -- repos/ports/src/app/vbox_pointer/main.cc | 378 ------------------ repos/ports/src/app/vbox_pointer/target.mk | 3 - repos/ports/src/virtualbox/frontend/console.h | 12 +- .../ports/src/virtualbox5/frontend/console.h | 12 +- 22 files changed, 434 insertions(+), 534 deletions(-) rename repos/{ports/include/vbox_pointer => os/include/pointer}/dither_painter.h (100%) rename repos/{ports/include/vbox_pointer => os/include/pointer}/shape_report.h (72%) rename repos/{ports/run/vbox_pointer.run => os/run/pointer.run} (96%) create mode 100644 repos/os/src/app/pointer/README rename repos/{ports/src/app/vbox_pointer => os/src/app/pointer}/rom_registry.h (100%) rename repos/{ports/src/app/vbox_pointer => os/src/app/pointer}/util.h (67%) rename repos/{ports/src/test/vbox_pointer => os/src/test/pointer}/main.cc (95%) rename repos/{ports/src/test/vbox_pointer => os/src/test/pointer}/target.mk (53%) delete mode 100644 repos/ports/recipes/src/vbox_pointer/content.mk delete mode 100644 repos/ports/recipes/src/vbox_pointer/hash delete mode 100644 repos/ports/recipes/src/vbox_pointer/used_apis delete mode 100644 repos/ports/src/app/vbox_pointer/README delete mode 100644 repos/ports/src/app/vbox_pointer/big_mouse.h delete mode 100644 repos/ports/src/app/vbox_pointer/main.cc delete mode 100644 repos/ports/src/app/vbox_pointer/target.mk diff --git a/repos/ports/include/vbox_pointer/dither_painter.h b/repos/os/include/pointer/dither_painter.h similarity index 100% rename from repos/ports/include/vbox_pointer/dither_painter.h rename to repos/os/include/pointer/dither_painter.h diff --git a/repos/ports/include/vbox_pointer/shape_report.h b/repos/os/include/pointer/shape_report.h similarity index 72% rename from repos/ports/include/vbox_pointer/shape_report.h rename to repos/os/include/pointer/shape_report.h index a07ee02c3b..3fa1474bf3 100644 --- a/repos/ports/include/vbox_pointer/shape_report.h +++ b/repos/os/include/pointer/shape_report.h @@ -11,10 +11,10 @@ * under the terms of the GNU Affero General Public License version 3. */ -#ifndef _INCLUDE__VBOX_POINTER__SHAPE_REPORT_H_ -#define _INCLUDE__VBOX_POINTER__SHAPE_REPORT_H_ +#ifndef _INCLUDE__POINTER__SHAPE_REPORT_H_ +#define _INCLUDE__POINTER__SHAPE_REPORT_H_ -namespace Vbox_pointer { +namespace Pointer { enum { MAX_WIDTH = 100, @@ -25,7 +25,7 @@ namespace Vbox_pointer { struct Shape_report; } -struct Vbox_pointer::Shape_report +struct Pointer::Shape_report { bool visible; unsigned int x_hot; @@ -35,4 +35,4 @@ struct Vbox_pointer::Shape_report unsigned char shape[MAX_SHAPE_SIZE]; }; -#endif /* _INCLUDE__VBOX_POINTER__SHAPE_REPORT_H_ */ +#endif /* _INCLUDE__POINTER__SHAPE_REPORT_H_ */ diff --git a/repos/os/recipes/src/nitpicker/content.mk b/repos/os/recipes/src/nitpicker/content.mk index 5aae1bb71c..6ef2a32ace 100644 --- a/repos/os/recipes/src/nitpicker/content.mk +++ b/repos/os/recipes/src/nitpicker/content.mk @@ -1,2 +1,10 @@ SRC_DIR := src/server/nitpicker src/app/pointer include $(GENODE_DIR)/repos/base/recipes/src/content.inc + +content: include/pointer include/report_rom + +include/pointer: + $(mirror_from_rep_dir) + +include/report_rom: + $(mirror_from_rep_dir) diff --git a/repos/ports/run/vbox_pointer.run b/repos/os/run/pointer.run similarity index 96% rename from repos/ports/run/vbox_pointer.run rename to repos/os/run/pointer.run index 929ce43d26..517a90057d 100644 --- a/repos/ports/run/vbox_pointer.run +++ b/repos/os/run/pointer.run @@ -13,8 +13,8 @@ set build_components { server/report_rom server/dynamic_rom server/nitpicker - app/vbox_pointer - test/vbox_pointer + app/pointer + test/pointer test/nitpicker } @@ -57,7 +57,6 @@ set config { - @@ -111,7 +110,7 @@ set config { - + @@ -125,7 +124,7 @@ set config { - + @@ -139,7 +138,7 @@ set config { - + @@ -177,7 +176,7 @@ set config { - + @@ -194,7 +193,6 @@ set config { - @@ -283,8 +281,8 @@ set boot_modules { fb_sdl report_rom dynamic_rom nitpicker - vbox_pointer - test-vbox_pointer + pointer + test-pointer testnit } diff --git a/repos/os/src/app/pointer/README b/repos/os/src/app/pointer/README new file mode 100644 index 0000000000..34359f41e8 --- /dev/null +++ b/repos/os/src/app/pointer/README @@ -0,0 +1,39 @@ +Pointer for Nitpicker with optional hover-sensitive shape support + +Per default the standard "big mouse" pointer is rendered on screen. + +Additionally, 'pointer' supports to render "pointer shapes" when hovering +Nitpicker sessions for which a shape was reported. This feature must be +enabled with the '' option. When enabled, the +'pointer' component announces a 'Report' service for custom pointer shapes +and requests ROM sessions for Nitpicker's 'hover' and 'xray' reports. The +mapping between hovered Nitpicker sessions and applications can be achieved +with report session label rewriting: + +! +! +! +! +! +! +! +! +! +! +! +! +! +! + +In the example above, which is from 'pointer.run', the 'shape-arrow' component +reports an arrow shape with the label "shape". By rewriting the label of the +report, the shape will be drawn for the 'test-label-arrow' component, which +is reported by Nitpicker with the label 'test-label-arror -> testnit' when +hovered. + +When configured with '', the 'pointer' +component prints the labels of hovered Nitpicker sessions and received shape +reports to the 'LOG' service. + +The most common use cases for pointer shapes are VirtualBox, which reports +the guest-pointer shapes if Guest Additions are installed, and Qt applications. diff --git a/repos/os/src/app/pointer/main.cc b/repos/os/src/app/pointer/main.cc index af1fa1cf30..2868ec5db2 100644 --- a/repos/os/src/app/pointer/main.cc +++ b/repos/os/src/app/pointer/main.cc @@ -1,6 +1,8 @@ /* - * \brief Minimalistic nitpicker pointer + * \brief Nitpicker pointer with support for VirtualBox-defined shapes * \author Norman Feske + * \author Christian Helmuth + * \author Christian Prochaska * \date 2014-07-02 */ @@ -12,18 +14,29 @@ */ /* Genode includes */ -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* local includes */ +#include "util.h" +#include "rom_registry.h" #include "big_mouse.h" +namespace Pointer { class Main; } + template -void convert_cursor_data_to_pixels(PT *pixel, Nitpicker::Area size) +void convert_default_pointer_data_to_pixels(PT *pixel, Nitpicker::Area size) { unsigned char *alpha = (unsigned char *)(pixel + size.count()); @@ -42,25 +55,324 @@ void convert_cursor_data_to_pixels(PT *pixel, Nitpicker::Area size) } -void Component::construct(Genode::Env &env) +class Pointer::Main : public Rom::Reader { - static Nitpicker::Connection nitpicker { env, "cursor" }; + private: - Nitpicker::Area const cursor_size(big_mouse.w, big_mouse.h); + typedef Pointer::String String; - Framebuffer::Mode const mode(cursor_size.w(), cursor_size.h(), - Framebuffer::Mode::RGB565); - nitpicker.buffer(mode, true); + Genode::Env &_env; - Genode::Attached_dataspace ds( - env.rm(), nitpicker.framebuffer()->dataspace()); + Genode::Attached_rom_dataspace _config { _env, "config" }; - convert_cursor_data_to_pixels( - ds.local_addr(), cursor_size); + bool _verbose = _config.xml().attribute_value("verbose", false); - Nitpicker::Session::View_handle view = nitpicker.create_view(); - Nitpicker::Rect geometry(Nitpicker::Point(0, 0), cursor_size); - nitpicker.enqueue(view, geometry); - nitpicker.enqueue(view); - nitpicker.execute(); + Nitpicker::Connection _nitpicker { _env }; + + Nitpicker::Session::View_handle _view = _nitpicker.create_view(); + + bool _default_pointer_visible = false; + + Nitpicker::Area _current_pointer_size; + Genode::Dataspace_capability _pointer_ds; + + void _resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size); + void _show_default_pointer(); + void _update_pointer(); + + /* custom shape support */ + + bool _shapes_enabled = _config.xml().attribute_value("shapes", false); + + bool _xray = false; + + Genode::Constructible _hover_ds; + Genode::Constructible _xray_ds; + + Genode::Signal_handler
_hover_signal_handler { + _env.ep(), *this, &Main::_handle_hover }; + Genode::Signal_handler
_xray_signal_handler { + _env.ep(), *this, &Main::_handle_xray }; + + Genode::Sliced_heap _sliced_heap { _env.ram(), _env.rm() }; + + Rom::Registry _rom_registry { _sliced_heap, _env.ram(), _env.rm(), *this }; + + Report::Root _report_root { _env, _sliced_heap, _rom_registry, _verbose }; + + String _hovered_label; + + Genode::Attached_ram_dataspace _texture_pixel_ds { _env.ram(), _env.rm(), + Pointer::MAX_WIDTH * + Pointer::MAX_HEIGHT * + sizeof(Genode::Pixel_rgb888) }; + + Genode::Attached_ram_dataspace _texture_alpha_ds { _env.ram(), _env.rm(), + Pointer::MAX_WIDTH * + Pointer::MAX_HEIGHT }; + + void _show_shape_pointer(Shape_report &shape_report); + void _handle_hover(); + void _handle_xray(); + + public: + + /** + * Reader interface + */ + void notify_module_changed() override + { + _update_pointer(); + } + + void notify_module_invalidated() override + { + _update_pointer(); + } + + Main(Genode::Env &); +}; + + +void Pointer::Main::_resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size) +{ + if (pointer_size == _current_pointer_size) + return; + + Framebuffer::Mode const mode { (int)pointer_size.w(), + (int)pointer_size.h(), + Framebuffer::Mode::RGB565 }; + + _nitpicker.buffer(mode, true /* use alpha */); + + _pointer_ds = _nitpicker.framebuffer()->dataspace(); + + _current_pointer_size = pointer_size; } + + +void Pointer::Main::_show_default_pointer() +{ + /* only draw default pointer if not already drawn */ + if (_default_pointer_visible) + return; + + Nitpicker::Area const pointer_size { big_mouse.w, big_mouse.h }; + + try { + _resize_nitpicker_buffer_if_needed(pointer_size); + } catch (...) { + Genode::error(__func__, ": could not resize the pointer buffer " + "for ", pointer_size.w(), "x", pointer_size.h(), " pixels"); + return; + } + + Genode::Attached_dataspace ds { _env.rm(), _pointer_ds }; + + convert_default_pointer_data_to_pixels(ds.local_addr(), + pointer_size); + _nitpicker.framebuffer()->refresh(0, 0, pointer_size.w(), pointer_size.h()); + + Nitpicker::Rect geometry(Nitpicker::Point(0, 0), pointer_size); + _nitpicker.enqueue(_view, geometry); + _nitpicker.execute(); + + _default_pointer_visible = true; +} + + +void Pointer::Main::_show_shape_pointer(Shape_report &shape_report) +{ + Nitpicker::Area shape_size { shape_report.width, shape_report.height }; + Nitpicker::Point shape_hot { (int)-shape_report.x_hot, (int)-shape_report.y_hot }; + + try { + _resize_nitpicker_buffer_if_needed(shape_size); + } catch (...) { + error(__func__, ": could not resize the pointer buffer " + "for ", shape_size, " pixels"); + throw; + } + + if (shape_report.visible) { + + using namespace Genode; + + /* import shape into texture */ + + Texture + texture(_texture_pixel_ds.local_addr(), + _texture_alpha_ds.local_addr(), + shape_size); + + for (unsigned int y = 0; y < shape_size.h(); y++) { + + /* import the RGBA-encoded line into the texture */ + unsigned char *shape = shape_report.shape; + unsigned char *line = &shape[y * shape_size.w() * 4]; + texture.rgba(line, shape_size.w(), y); + } + + /* draw texture */ + + Attached_dataspace ds { _env.rm(), _pointer_ds }; + + Pixel_rgb565 *pixel = ds.local_addr(); + + Pixel_alpha8 *alpha = + reinterpret_cast(pixel + shape_size.count()); + + Surface pixel_surface(pixel, shape_size); + Surface alpha_surface(alpha, shape_size); + + Dither_painter::paint(pixel_surface, texture); + Dither_painter::paint(alpha_surface, texture); + } + + _nitpicker.framebuffer()->refresh(0, 0, shape_size.w(), shape_size.h()); + + Nitpicker::Rect geometry(shape_hot, shape_size); + _nitpicker.enqueue(_view, geometry); + _nitpicker.execute(); + + _default_pointer_visible = false; +} + + +void Pointer::Main::_update_pointer() +{ + if (!_shapes_enabled || _xray) { + _show_default_pointer(); + return; + } + + try { + + Rom::Readable_module &shape_module = + _rom_registry.lookup(*this, _hovered_label); + + try { + Shape_report shape_report; + + shape_module.read_content(*this, (char*)&shape_report, sizeof(shape_report)); + + if (shape_report.visible) { + + if ((shape_report.width == 0) || + (shape_report.height == 0) || + (shape_report.width > MAX_WIDTH) || + (shape_report.height > MAX_HEIGHT)) + throw Genode::Exception(); + + _show_shape_pointer(shape_report); + } + + } catch (...) { + _rom_registry.release(*this, shape_module); + throw; + } + + _rom_registry.release(*this, shape_module); + + } catch (...) { + _show_default_pointer(); + } +} + + +void Pointer::Main::_handle_hover() +{ + using Pointer::read_string_attribute; + + _hover_ds->update(); + if (!_hover_ds->valid()) + return; + + /* read new hover information from nitpicker's hover report */ + try { + Genode::Xml_node node(_hover_ds->local_addr()); + + String hovered_label = read_string_attribute(node, "label", String()); + + if (_verbose) + Genode::log("hovered_label: ", hovered_label); + + /* update pointer if hovered label changed */ + if (hovered_label != _hovered_label) { + _hovered_label = hovered_label; + _update_pointer(); + } + } + catch (...) { + Genode::warning("could not parse hover report"); + } +} + + +void Pointer::Main::_handle_xray() +{ + _xray_ds->update(); + if (!_xray_ds->valid()) + return; + + try { + Genode::Xml_node node(_xray_ds->local_addr()); + + bool xray = node.attribute_value("enabled", false); + + /* update pointer if xray status changed */ + if (xray != _xray) { + _xray = xray; + _update_pointer(); + } + } + catch (...) { + Genode::warning("could not parse xray report"); + } +} + +Pointer::Main::Main(Genode::Env &env) : _env(env) +{ + /* + * Try to allocate the Nitpicker buffer for the maximum supported + * pointer size to let the user know right from the start if the + * RAM quota is too low. + */ + Framebuffer::Mode const mode { Pointer::MAX_WIDTH, Pointer::MAX_HEIGHT, + Framebuffer::Mode::RGB565 }; + + _nitpicker.buffer(mode, true /* use alpha */); + + if (_shapes_enabled) { + try { + _hover_ds.construct(_env, "hover"); + _hover_ds->sigh(_hover_signal_handler); + _handle_hover(); + } catch (Genode::Rom_connection::Rom_connection_failed) { + Genode::warning("Could not open ROM session for \"hover\".", + " This ROM is used for custom pointer shape support."); + } + + try { + _xray_ds.construct(_env, "xray"); + _xray_ds->sigh(_xray_signal_handler); + _handle_xray(); + } catch (Genode::Rom_connection::Rom_connection_failed) { + Genode::warning("Could not open ROM session for \"xray\".", + " This ROM is used for custom pointer shape support."); + } + } + + _nitpicker.enqueue(_view); + _nitpicker.execute(); + + _update_pointer(); + + if (_shapes_enabled) { + /* announce 'Report' service */ + env.parent().announce(env.ep().manage(_report_root)); + } +} + + +void Component::construct(Genode::Env &env) { static Pointer::Main main(env); } diff --git a/repos/ports/src/app/vbox_pointer/rom_registry.h b/repos/os/src/app/pointer/rom_registry.h similarity index 100% rename from repos/ports/src/app/vbox_pointer/rom_registry.h rename to repos/os/src/app/pointer/rom_registry.h diff --git a/repos/ports/src/app/vbox_pointer/util.h b/repos/os/src/app/pointer/util.h similarity index 67% rename from repos/ports/src/app/vbox_pointer/util.h rename to repos/os/src/app/pointer/util.h index ba3918570c..b7f4a4ce94 100644 --- a/repos/ports/src/app/vbox_pointer/util.h +++ b/repos/os/src/app/pointer/util.h @@ -11,15 +11,15 @@ * under the terms of the GNU Affero General Public License version 3. */ -#ifndef _VBOX_POINTER_UTIL_H_ -#define _VBOX_POINTER_UTIL_H_ +#ifndef _POINTER_UTIL_H_ +#define _POINTER_UTIL_H_ /* Genode includes */ #include #include -namespace Vbox_pointer { +namespace Pointer { typedef Genode::String<64> String; inline String read_string_attribute(Genode::Xml_node const &node, @@ -28,9 +28,9 @@ namespace Vbox_pointer { } -Vbox_pointer::String Vbox_pointer::read_string_attribute(Genode::Xml_node const &node, - char const *attr, - String const &default_value) +Pointer::String Pointer::read_string_attribute(Genode::Xml_node const &node, + char const *attr, + String const &default_value) { try { char buf[String::capacity()]; @@ -39,4 +39,4 @@ Vbox_pointer::String Vbox_pointer::read_string_attribute(Genode::Xml_node const } catch (...) { return default_value; } } -#endif /* _VBOX_POINTER_UTIL_H_ */ +#endif /* _POINTER_UTIL_H_ */ diff --git a/repos/ports/src/test/vbox_pointer/main.cc b/repos/os/src/test/pointer/main.cc similarity index 95% rename from repos/ports/src/test/vbox_pointer/main.cc rename to repos/os/src/test/pointer/main.cc index 199e43d84f..2ed172394f 100644 --- a/repos/ports/src/test/vbox_pointer/main.cc +++ b/repos/os/src/test/pointer/main.cc @@ -15,7 +15,7 @@ #include #include #include -#include +#include struct Shape { @@ -141,11 +141,11 @@ struct Main { Genode::Env &_env; - Vbox_pointer::Shape_report _shape_report { + Pointer::Shape_report _shape_report { true, 0, 0, Shape::WIDTH, Shape::HEIGHT, { 0 } }; Genode::Reporter _reporter { - _env, "shape", "shape", sizeof(Vbox_pointer::Shape_report) }; + _env, "shape", "shape", sizeof(Pointer::Shape_report) }; Genode::Signal_handler
_config_handler { _env.ep(), *this, &Main::_handle_config }; @@ -173,7 +173,7 @@ struct Main } } - _reporter.report(&_shape_report, sizeof(Vbox_pointer::Shape_report)); + _reporter.report(&_shape_report, sizeof(Pointer::Shape_report)); } Main(Genode::Env &env) : _env(env) diff --git a/repos/ports/src/test/vbox_pointer/target.mk b/repos/os/src/test/pointer/target.mk similarity index 53% rename from repos/ports/src/test/vbox_pointer/target.mk rename to repos/os/src/test/pointer/target.mk index 19ef27af1b..5dfe2a6bf9 100644 --- a/repos/ports/src/test/vbox_pointer/target.mk +++ b/repos/os/src/test/pointer/target.mk @@ -1,3 +1,3 @@ -TARGET = test-vbox_pointer +TARGET = test-pointer SRC_CC = main.cc LIBS = base diff --git a/repos/ports/recipes/src/vbox5-nova/content.mk b/repos/ports/recipes/src/vbox5-nova/content.mk index 96b44d6dc4..8b9d6fd8cd 100644 --- a/repos/ports/recipes/src/vbox5-nova/content.mk +++ b/repos/ports/recipes/src/vbox5-nova/content.mk @@ -15,7 +15,6 @@ MIRROR_FROM_REP_DIR := src/virtualbox5 \ src/virtualbox/rt.cc \ src/virtualbox/thread.cc \ include/vmm \ - include/vbox_pointer/shape_report.h \ $(addprefix lib/mk/,$(LIB_MK_FILES)) content: $(MIRROR_FROM_REP_DIR) @@ -73,7 +72,8 @@ $(MIRROR_FROM_QEMU_USB_PORT_DIR): mkdir -p $(dir $@) cp -r $(QEMU_USB_PORT_DIR)/$@ $(dir $@) -MIRROR_FROM_OS := src/drivers/input/spec/ps2/scan_code_set_1.h +MIRROR_FROM_OS := src/drivers/input/spec/ps2/scan_code_set_1.h \ + include/pointer/shape_report.h \ content: $(MIRROR_FROM_OS) diff --git a/repos/ports/recipes/src/vbox_pointer/content.mk b/repos/ports/recipes/src/vbox_pointer/content.mk deleted file mode 100644 index 0d1ca6fe4d..0000000000 --- a/repos/ports/recipes/src/vbox_pointer/content.mk +++ /dev/null @@ -1,7 +0,0 @@ -SRC_DIR := src/app/vbox_pointer -include $(GENODE_DIR)/repos/base/recipes/src/content.inc - -content: include/vbox_pointer - -include/vbox_pointer: - $(mirror_from_rep_dir) diff --git a/repos/ports/recipes/src/vbox_pointer/hash b/repos/ports/recipes/src/vbox_pointer/hash deleted file mode 100644 index 93a988a36f..0000000000 --- a/repos/ports/recipes/src/vbox_pointer/hash +++ /dev/null @@ -1 +0,0 @@ -2017-11-08 a885637d5623c31559066e231cb22a050674e5ec diff --git a/repos/ports/recipes/src/vbox_pointer/used_apis b/repos/ports/recipes/src/vbox_pointer/used_apis deleted file mode 100644 index 8d277d6069..0000000000 --- a/repos/ports/recipes/src/vbox_pointer/used_apis +++ /dev/null @@ -1,6 +0,0 @@ -base -os -gems -input_session -nitpicker_session -framebuffer_session diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc index c3601d9811..9b7534f066 100644 --- a/repos/ports/run/vbox_win.inc +++ b/repos/ports/run/vbox_win.inc @@ -28,7 +28,7 @@ set build_components { drivers/nic drivers/audio server/nitpicker - app/vbox_pointer + app/pointer server/nit_fb server/report_rom server/dynamic_rom @@ -39,7 +39,7 @@ set boot_modules { nic_drv audio_drv nitpicker - vbox_pointer + pointer nit_fb report_rom dynamic_rom @@ -111,8 +111,8 @@ append config_of_app { - - } + + } append config_of_app { @@ -140,13 +140,13 @@ append config_of_app { - + - + @@ -297,7 +297,7 @@ for { set i 1} { $i <= $use_vms } { incr i} { - \"/> + \"/> " append config_of_app { diff --git a/repos/ports/run/virtualbox.run b/repos/ports/run/virtualbox.run index d6a58117e2..8561138205 100644 --- a/repos/ports/run/virtualbox.run +++ b/repos/ports/run/virtualbox.run @@ -43,7 +43,7 @@ lappend_if [expr $use_bridge] build_components server/nic_bridge lappend_if [expr $use_gui] build_components server/report_rom lappend_if [expr $use_gui] build_components server/nitpicker lappend_if [expr $use_gui] build_components server/nit_fb -lappend_if [expr $use_gui] build_components app/vbox_pointer +lappend_if [expr $use_gui] build_components app/pointer append_platform_drv_build_components @@ -157,8 +157,8 @@ append_if [expr $use_gui] config { - - + + @@ -183,12 +183,12 @@ append_if [expr $use_gui] config { - + - + @@ -244,7 +244,7 @@ append_if [expr $use_gui] config { - + @@ -277,7 +277,7 @@ append_if [expr $use_bridge] config { } append_if [expr $use_gui] config { - + } @@ -307,7 +307,7 @@ lappend_if [have_spec x86] boot_modules rtc_drv lappend_if [expr $use_gui] boot_modules report_rom lappend_if [expr $use_gui] boot_modules nitpicker lappend_if [expr $use_gui] boot_modules nit_fb -lappend_if [expr $use_gui] boot_modules vbox_pointer +lappend_if [expr $use_gui] boot_modules pointer append boot_modules { ld.lib.so libc.lib.so libm.lib.so pthread.lib.so libc_pipe.lib.so diff --git a/repos/ports/src/app/vbox_pointer/README b/repos/ports/src/app/vbox_pointer/README deleted file mode 100644 index 886f880f24..0000000000 --- a/repos/ports/src/app/vbox_pointer/README +++ /dev/null @@ -1,26 +0,0 @@ -Hover-sensitive pointer for Nitpicker with VirtualBox shape support - -Per default the standard "big mouse" pointer is rendered on screen, -which is the behavior known from the classical app/pointer. -Additionally, VirtualBox pointer supports to render "pointer shapes" -when hovering configured Nitpicker sessions. The policies can be -defined for labels or domains of the sessions. - -! -! -! -! -! -! -! -! - -In the example above, which is from vbox_pointer.run, the domain -"smiley" gets the ROM "smiley" as pointer shape. The labels -"test-label-blade" and "test-label-arrow" will render the ROMs "arrow" -resp. "blade" as pointer shape. Note that label matching is done from -the start of the actual label until the defined label ends. So, -"test-label-blade2" will also match the policy defined above. - -The most common use case for vbox_pointer is VirtualBox, which reports -the guest-pointer shapes if Guest Additions are installed. diff --git a/repos/ports/src/app/vbox_pointer/big_mouse.h b/repos/ports/src/app/vbox_pointer/big_mouse.h deleted file mode 100644 index 9698d08483..0000000000 --- a/repos/ports/src/app/vbox_pointer/big_mouse.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * \brief Mouse cursor pixel data - * \author Norman Feske - * \date 2006-08-09 - */ - -/* - * 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. - */ - -static struct { - unsigned short w, h, pixels[16][16]; -} big_mouse = { - 16,16, - { - {0x738E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x94B2,0x7BCF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x630C,0xC638,0xC638,0x6B4D,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x738E,0x8C71,0xFFFF,0xB5B6,0x6B4D,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x630C,0x4A49,0x630C,0xB5B6,0xFFFF,0xB5B6,0x630C,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x528A,0x528A,0x630C,0x9492,0xB5B6,0xFFFF,0xB5B6,0x630C,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x528A,0x39C7,0x4208,0x630C,0x7BCF,0xB5B6,0xFFFF,0xFFFF,0xB5B6,0x630C,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x4208,0x39C7,0x4208,0x630C,0x7BCF,0xB5B6,0xDEFB,0xFFFF,0xFFFF,0xB5B6,0x630C,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x4A49,0x1082,0x39C7,0x4208,0x5ACB,0x7BCF,0x8C71,0xAD75,0x630C,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x4208,0x1082,0x39C7,0x5ACB,0x630C,0xB5B6,0x0000,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x4A49,0x1082,0x1082,0x39C7,0x4A49,0x630C,0xAD75,0x0000,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4208,0x1082,0x4A49,0x0000,0x4A49,0x630C,0x8C71,0x0000,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4A49,0x39C7,0x4A49,0x0000,0x0000,0x4A49,0x630C,0x8C71,0x0000,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4A49,0x0000,0x0000,0x0000,0x0000,0x4A49,0x630C,0x8C71,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4A49,0x0000,0x0000,0x0000,0x0000,0x0000,0x4A49,0x4A49,0x0000}, - {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}, - } -}; diff --git a/repos/ports/src/app/vbox_pointer/main.cc b/repos/ports/src/app/vbox_pointer/main.cc deleted file mode 100644 index 2fe25a68f9..0000000000 --- a/repos/ports/src/app/vbox_pointer/main.cc +++ /dev/null @@ -1,378 +0,0 @@ -/* - * \brief Nitpicker pointer with support for VirtualBox-defined shapes - * \author Norman Feske - * \author Christian Helmuth - * \author Christian Prochaska - * \date 2014-07-02 - */ - -/* - * Copyright (C) 2014-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. - */ - -/* Genode includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* local includes */ -#include "util.h" -#include "rom_registry.h" -#include "big_mouse.h" - -namespace Vbox_pointer { class Main; } - - -template -void convert_default_pointer_data_to_pixels(PT *pixel, Nitpicker::Area size) -{ - unsigned char *alpha = (unsigned char *)(pixel + size.count()); - - for (unsigned y = 0; y < size.h(); y++) { - for (unsigned x = 0; x < size.w(); x++) { - - /* the source is known to be in RGB565 format */ - Genode::Pixel_rgb565 src = - *(Genode::Pixel_rgb565 *)(&big_mouse.pixels[y][x]); - - unsigned const i = y*size.w() + x; - pixel[i] = PT(src.r(), src.g(), src.b()); - alpha[i] = src.r() ? 255 : 0; - } - } -} - - -class Vbox_pointer::Main : public Rom::Reader -{ - private: - - typedef Vbox_pointer::String String; - - Genode::Env &_env; - - Genode::Attached_rom_dataspace _config { _env, "config" }; - - bool _verbose = _config.xml().attribute_value("verbose", false); - - Nitpicker::Connection _nitpicker { _env }; - - Nitpicker::Session::View_handle _view = _nitpicker.create_view(); - - bool _default_pointer_visible = false; - - Nitpicker::Area _current_pointer_size; - Genode::Dataspace_capability _pointer_ds; - - void _resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size); - void _show_default_pointer(); - void _update_pointer(); - - /* custom shape support */ - - bool _shapes_enabled = _config.xml().attribute_value("shapes", false); - - bool _xray = false; - - Genode::Constructible _hover_ds; - Genode::Constructible _xray_ds; - - Genode::Signal_handler
_hover_signal_handler { - _env.ep(), *this, &Main::_handle_hover }; - Genode::Signal_handler
_xray_signal_handler { - _env.ep(), *this, &Main::_handle_xray }; - - Genode::Sliced_heap _sliced_heap { _env.ram(), _env.rm() }; - - Rom::Registry _rom_registry { _sliced_heap, _env.ram(), _env.rm(), *this }; - - Report::Root _report_root { _env, _sliced_heap, _rom_registry, _verbose }; - - String _hovered_label; - - Genode::Attached_ram_dataspace _texture_pixel_ds { _env.ram(), _env.rm(), - Vbox_pointer::MAX_WIDTH * - Vbox_pointer::MAX_HEIGHT * - sizeof(Genode::Pixel_rgb888) }; - - Genode::Attached_ram_dataspace _texture_alpha_ds { _env.ram(), _env.rm(), - Vbox_pointer::MAX_WIDTH * - Vbox_pointer::MAX_HEIGHT }; - - void _show_shape_pointer(Shape_report &shape_report); - void _handle_hover(); - void _handle_xray(); - - public: - - /** - * Reader interface - */ - void notify_module_changed() override - { - _update_pointer(); - } - - void notify_module_invalidated() override - { - _update_pointer(); - } - - Main(Genode::Env &); -}; - - -void Vbox_pointer::Main::_resize_nitpicker_buffer_if_needed(Nitpicker::Area pointer_size) -{ - if (pointer_size == _current_pointer_size) - return; - - Framebuffer::Mode const mode { (int)pointer_size.w(), - (int)pointer_size.h(), - Framebuffer::Mode::RGB565 }; - - _nitpicker.buffer(mode, true /* use alpha */); - - _pointer_ds = _nitpicker.framebuffer()->dataspace(); - - _current_pointer_size = pointer_size; -} - - -void Vbox_pointer::Main::_show_default_pointer() -{ - /* only draw default pointer if not already drawn */ - if (_default_pointer_visible) - return; - - Nitpicker::Area const pointer_size { big_mouse.w, big_mouse.h }; - - try { - _resize_nitpicker_buffer_if_needed(pointer_size); - } catch (...) { - Genode::error(__func__, ": could not resize the pointer buffer " - "for ", pointer_size.w(), "x", pointer_size.h(), " pixels"); - return; - } - - Genode::Attached_dataspace ds { _env.rm(), _pointer_ds }; - - convert_default_pointer_data_to_pixels(ds.local_addr(), - pointer_size); - _nitpicker.framebuffer()->refresh(0, 0, pointer_size.w(), pointer_size.h()); - - Nitpicker::Rect geometry(Nitpicker::Point(0, 0), pointer_size); - _nitpicker.enqueue(_view, geometry); - _nitpicker.execute(); - - _default_pointer_visible = true; -} - - -void Vbox_pointer::Main::_show_shape_pointer(Shape_report &shape_report) -{ - Nitpicker::Area shape_size { shape_report.width, shape_report.height }; - Nitpicker::Point shape_hot { (int)-shape_report.x_hot, (int)-shape_report.y_hot }; - - try { - _resize_nitpicker_buffer_if_needed(shape_size); - } catch (...) { - error(__func__, ": could not resize the pointer buffer " - "for ", shape_size, " pixels"); - throw; - } - - if (shape_report.visible) { - - using namespace Genode; - - /* import shape into texture */ - - Texture - texture(_texture_pixel_ds.local_addr(), - _texture_alpha_ds.local_addr(), - shape_size); - - for (unsigned int y = 0; y < shape_size.h(); y++) { - - /* import the RGBA-encoded line into the texture */ - unsigned char *shape = shape_report.shape; - unsigned char *line = &shape[y * shape_size.w() * 4]; - texture.rgba(line, shape_size.w(), y); - } - - /* draw texture */ - - Attached_dataspace ds { _env.rm(), _pointer_ds }; - - Pixel_rgb565 *pixel = ds.local_addr(); - - Pixel_alpha8 *alpha = - reinterpret_cast(pixel + shape_size.count()); - - Surface pixel_surface(pixel, shape_size); - Surface alpha_surface(alpha, shape_size); - - Dither_painter::paint(pixel_surface, texture); - Dither_painter::paint(alpha_surface, texture); - } - - _nitpicker.framebuffer()->refresh(0, 0, shape_size.w(), shape_size.h()); - - Nitpicker::Rect geometry(shape_hot, shape_size); - _nitpicker.enqueue(_view, geometry); - _nitpicker.execute(); - - _default_pointer_visible = false; -} - - -void Vbox_pointer::Main::_update_pointer() -{ - if (!_shapes_enabled || _xray) { - _show_default_pointer(); - return; - } - - try { - - Rom::Readable_module &shape_module = - _rom_registry.lookup(*this, _hovered_label); - - try { - Shape_report shape_report; - - shape_module.read_content(*this, (char*)&shape_report, sizeof(shape_report)); - - if (shape_report.visible) { - - if ((shape_report.width == 0) || - (shape_report.height == 0) || - (shape_report.width > MAX_WIDTH) || - (shape_report.height > MAX_HEIGHT)) - throw Genode::Exception(); - - _show_shape_pointer(shape_report); - } - - } catch (...) { - _rom_registry.release(*this, shape_module); - throw; - } - - _rom_registry.release(*this, shape_module); - - } catch (...) { - _show_default_pointer(); - } -} - - -void Vbox_pointer::Main::_handle_hover() -{ - using Vbox_pointer::read_string_attribute; - - _hover_ds->update(); - if (!_hover_ds->valid()) - return; - - /* read new hover information from nitpicker's hover report */ - try { - Genode::Xml_node node(_hover_ds->local_addr()); - - String hovered_label = read_string_attribute(node, "label", String()); - - if (_verbose) - Genode::log("hovered_label: ", hovered_label); - - /* update pointer if hovered label changed */ - if (hovered_label != _hovered_label) { - _hovered_label = hovered_label; - _update_pointer(); - } - } - catch (...) { - Genode::warning("could not parse hover report"); - } -} - - -void Vbox_pointer::Main::_handle_xray() -{ - _xray_ds->update(); - if (!_xray_ds->valid()) - return; - - try { - Genode::Xml_node node(_xray_ds->local_addr()); - - bool xray = node.attribute_value("enabled", false); - - /* update pointer if xray status changed */ - if (xray != _xray) { - _xray = xray; - _update_pointer(); - } - } - catch (...) { - Genode::warning("could not parse xray report"); - } -} - -Vbox_pointer::Main::Main(Genode::Env &env) : _env(env) -{ - /* - * Try to allocate the Nitpicker buffer for the maximum supported - * pointer size to let the user know right from the start if the - * RAM quota is too low. - */ - Framebuffer::Mode const mode { Vbox_pointer::MAX_WIDTH, Vbox_pointer::MAX_HEIGHT, - Framebuffer::Mode::RGB565 }; - - _nitpicker.buffer(mode, true /* use alpha */); - - if (_shapes_enabled) { - try { - _hover_ds.construct(_env, "hover"); - _hover_ds->sigh(_hover_signal_handler); - _handle_hover(); - } catch (Genode::Rom_connection::Rom_connection_failed) { - Genode::warning("Could not open ROM session for \"hover\".", - " This ROM is used for custom pointer shape support."); - } - - try { - _xray_ds.construct(_env, "xray"); - _xray_ds->sigh(_xray_signal_handler); - _handle_xray(); - } catch (Genode::Rom_connection::Rom_connection_failed) { - Genode::warning("Could not open ROM session for \"xray\".", - " This ROM is used for custom pointer shape support."); - } - } - - _nitpicker.enqueue(_view); - _nitpicker.execute(); - - _update_pointer(); - - if (_shapes_enabled) { - /* announce 'Report' service */ - env.parent().announce(env.ep().manage(_report_root)); - } -} - - -void Component::construct(Genode::Env &env) { static Vbox_pointer::Main main(env); } diff --git a/repos/ports/src/app/vbox_pointer/target.mk b/repos/ports/src/app/vbox_pointer/target.mk deleted file mode 100644 index 2280cd9f77..0000000000 --- a/repos/ports/src/app/vbox_pointer/target.mk +++ /dev/null @@ -1,3 +0,0 @@ -TARGET = vbox_pointer -SRC_CC = main.cc -LIBS += base diff --git a/repos/ports/src/virtualbox/frontend/console.h b/repos/ports/src/virtualbox/frontend/console.h index 6e53e8d56c..c2fd378d32 100644 --- a/repos/ports/src/virtualbox/frontend/console.h +++ b/repos/ports/src/virtualbox/frontend/console.h @@ -27,7 +27,7 @@ #include /* repos/ports includes */ -#include +#include #include "../vmm.h" @@ -117,7 +117,7 @@ class GenodeConsole : public Console { Report::Connection _shape_report_connection; Genode::Attached_dataspace _shape_report_ds; Genode::Constructible _caps_lock; - Vbox_pointer::Shape_report *_shape_report; + Pointer::Shape_report *_shape_report; Genode::Reporter *_clipboard_reporter; Genode::Attached_rom_dataspace *_clipboard_rom; IKeyboard *_vbox_keyboard; @@ -145,9 +145,9 @@ class GenodeConsole : public Console { _ax(0), _ay(0), _last_received_motion_event_was_absolute(false), _shape_report_connection(genode_env(), "shape", - sizeof(Vbox_pointer::Shape_report)), + sizeof(Pointer::Shape_report)), _shape_report_ds(genode_env().rm(), _shape_report_connection.dataspace()), - _shape_report(_shape_report_ds.local_addr()), + _shape_report(_shape_report_ds.local_addr()), _clipboard_reporter(nullptr), _clipboard_rom(nullptr), _vbox_keyboard(0), @@ -204,7 +204,7 @@ class GenodeConsole : public Console { size_t shape_size = shape_array.size() - (shape - and_mask); - if (shape_size > Vbox_pointer::MAX_SHAPE_SIZE) { + if (shape_size > Pointer::MAX_SHAPE_SIZE) { Genode::error(__func__, ": shape data buffer is too small " "for ", shape_size, " bytes"); return; @@ -235,7 +235,7 @@ class GenodeConsole : public Console { } } - _shape_report_connection.submit(sizeof(Vbox_pointer::Shape_report)); + _shape_report_connection.submit(sizeof(Pointer::Shape_report)); } void update_video_mode(); diff --git a/repos/ports/src/virtualbox5/frontend/console.h b/repos/ports/src/virtualbox5/frontend/console.h index 9d1be85f57..b475ac71ff 100644 --- a/repos/ports/src/virtualbox5/frontend/console.h +++ b/repos/ports/src/virtualbox5/frontend/console.h @@ -27,7 +27,7 @@ #include /* repos/ports includes */ -#include +#include #include "../vmm.h" @@ -117,7 +117,7 @@ class GenodeConsole : public Console { Report::Connection _shape_report_connection; Genode::Attached_dataspace _shape_report_ds; Genode::Constructible _caps_lock; - Vbox_pointer::Shape_report *_shape_report; + Pointer::Shape_report *_shape_report; Genode::Reporter *_clipboard_reporter; Genode::Attached_rom_dataspace *_clipboard_rom; IKeyboard *_vbox_keyboard; @@ -145,9 +145,9 @@ class GenodeConsole : public Console { _ax(0), _ay(0), _last_received_motion_event_was_absolute(false), _shape_report_connection(genode_env(), "shape", - sizeof(Vbox_pointer::Shape_report)), + sizeof(Pointer::Shape_report)), _shape_report_ds(genode_env().rm(), _shape_report_connection.dataspace()), - _shape_report(_shape_report_ds.local_addr()), + _shape_report(_shape_report_ds.local_addr()), _clipboard_reporter(nullptr), _clipboard_rom(nullptr), _vbox_keyboard(0), @@ -204,7 +204,7 @@ class GenodeConsole : public Console { size_t shape_size = cbShape - (shape - and_mask); - if (shape_size > Vbox_pointer::MAX_SHAPE_SIZE) { + if (shape_size > Pointer::MAX_SHAPE_SIZE) { Genode::error(__func__, ": shape data buffer is too small for ", shape_size, " bytes"); return; @@ -249,7 +249,7 @@ class GenodeConsole : public Console { } } - _shape_report_connection.submit(sizeof(Vbox_pointer::Shape_report)); + _shape_report_connection.submit(sizeof(Pointer::Shape_report)); } void update_video_mode();