/* * \brief Window manager * \author Norman Feske * \date 2014-01-06 */ /* * Copyright (C) 2014 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ /* Genode includes */ #include #include #include #include #include #include #include /* local includes */ #include #include #include #include #include #include #include namespace Wm { class Main; using Genode::size_t; using Genode::env; using Genode::Rom_session_client; using Genode::Rom_connection; using Genode::Xml_node; } struct Wm::Main { Server::Entrypoint ep; Genode::Cap_connection cap; Report_rom_slave report_rom_slave = { cap, *env()->ram_session() }; Rom_session_capability window_list_rom = report_rom_slave.rom_session("window_list"); Rom_session_capability window_layout_rom = report_rom_slave.rom_session("window_layout"); Rom_session_capability pointer_rom = report_rom_slave.rom_session("pointer"); Rom_session_capability hover_rom = report_rom_slave.rom_session("hover"); Rom_session_client focus_rom { report_rom_slave.rom_session("focus") }; Rom_session_client resize_request_rom { report_rom_slave.rom_session("resize_request") }; /* pointer position reported by nitpicker */ Capability pointer_report = report_rom_slave.report_session("pointer"); Local_reporter pointer_reporter = { "pointer", pointer_report }; /* hovered element reported by decorator */ Capability hover_report = report_rom_slave.report_session("hover"); Capability window_list_report = report_rom_slave.report_session("window_list"); Local_reporter window_list_reporter = { "window_list", window_list_report }; Capability window_layout_report = report_rom_slave.report_session("window_layout"); Capability resize_request_report = report_rom_slave.report_session("resize_request"); Capability focus_report = report_rom_slave.report_session("focus"); Input::Session_component window_layouter_input; Window_registry window_registry { *env()->heap(), window_list_reporter }; Nitpicker::Root nitpicker_root { ep, window_registry, *env()->heap(), env()->ram_session_cap() }; Decorator_nitpicker_service decorator_nitpicker_service { ep, *env()->heap(), env()->ram_session_cap(), pointer_reporter, window_layouter_input, nitpicker_root }; Window_layouter_slave window_layouter_slave = { cap, *env()->ram_session(), window_list_rom, hover_rom, ep.manage(window_layouter_input), window_layout_report, resize_request_report, focus_report }; Decorator_slave decorator_slave = { cap, decorator_nitpicker_service, *env()->ram_session(), window_layout_rom, pointer_rom, hover_report }; Genode::Lazy_volatile_object focus_ds; Nitpicker::Connection focus_nitpicker_session; void handle_focus_update(unsigned) { try { if (!focus_ds.is_constructed() || focus_rom.update() == false) { if (focus_ds.is_constructed()) focus_ds->invalidate(); focus_ds.construct(focus_rom.dataspace()); } unsigned long win_id = 0; Xml_node(focus_ds->local_addr()).sub_node("window") .attribute("id").value(&win_id); if (win_id) { Nitpicker::Session_capability session_cap = nitpicker_root.lookup_nitpicker_session(win_id); focus_nitpicker_session.focus(session_cap); } } catch (...) { PWRN("no focus model available"); } } Genode::Signal_rpc_member
focus_dispatcher = { ep, *this, &Main::handle_focus_update }; Genode::Lazy_volatile_object resize_request_ds; void handle_resize_request_update(unsigned) { try { if (!resize_request_ds.is_constructed() || resize_request_rom.update() == false) { if (resize_request_ds.is_constructed()) resize_request_ds->invalidate(); resize_request_ds.construct(resize_request_rom.dataspace()); } char const * const node_type = "window"; Xml_node window = Xml_node(resize_request_ds->local_addr()).sub_node(node_type); for (;;) { unsigned long win_id = 0, width = 0, height = 0; window.attribute("id") .value(&win_id); window.attribute("width") .value(&width); window.attribute("height").value(&height); nitpicker_root.request_resize(win_id, Area(width, height)); if (window.is_last(node_type)) break; window = window.next(node_type); } } catch (...) { /* no resize-request model available */ } } Genode::Signal_rpc_member
resize_request_dispatcher = { ep, *this, &Main::handle_resize_request_update }; Main(Server::Entrypoint &ep) : ep(ep) { window_layouter_input.event_queue().enabled(true); /* initially report an empty window list */ Local_reporter::Xml_generator xml(window_list_reporter, [&] () { }); focus_rom.sigh(focus_dispatcher); resize_request_rom.sigh(resize_request_dispatcher); } }; /************ ** Server ** ************/ namespace Server { char const *name() { return "desktop_ep"; } size_t stack_size() { return 4*1024*sizeof(long); } void construct(Entrypoint &ep) { static Wm::Main desktop(ep); } }