2014-01-06 19:15:14 +01:00
|
|
|
/*
|
|
|
|
* \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 <os/server.h>
|
|
|
|
#include <nitpicker_session/client.h>
|
|
|
|
#include <framebuffer_session/client.h>
|
|
|
|
#include <cap_session/connection.h>
|
2015-06-03 11:20:58 +02:00
|
|
|
#include <os/attached_rom_dataspace.h>
|
2014-01-06 19:15:14 +01:00
|
|
|
#include <util/volatile_object.h>
|
|
|
|
#include <util/xml_node.h>
|
|
|
|
|
|
|
|
/* local includes */
|
|
|
|
#include <nitpicker.h>
|
|
|
|
|
|
|
|
namespace Wm {
|
|
|
|
|
|
|
|
class Main;
|
|
|
|
|
|
|
|
using Genode::size_t;
|
|
|
|
using Genode::env;
|
|
|
|
using Genode::Rom_session_client;
|
|
|
|
using Genode::Rom_connection;
|
|
|
|
using Genode::Xml_node;
|
2015-06-03 11:20:58 +02:00
|
|
|
using Genode::Attached_rom_dataspace;
|
2014-01-06 19:15:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct Wm::Main
|
|
|
|
{
|
|
|
|
Server::Entrypoint ep;
|
|
|
|
|
|
|
|
Genode::Cap_connection cap;
|
|
|
|
|
2015-06-03 11:20:58 +02:00
|
|
|
/* currently focused window, reported by the layouter */
|
|
|
|
Attached_rom_dataspace focus_rom { "focus" };
|
2014-01-06 19:15:14 +01:00
|
|
|
|
2015-06-03 11:20:58 +02:00
|
|
|
/* resize requests, issued by the layouter */
|
|
|
|
Attached_rom_dataspace resize_request_rom { "resize_request" };
|
2014-01-06 19:15:14 +01:00
|
|
|
|
2015-06-03 11:20:58 +02:00
|
|
|
/* pointer position to be consumed by the layouter */
|
|
|
|
Reporter pointer_reporter = { "pointer" };
|
2014-01-06 19:15:14 +01:00
|
|
|
|
2015-06-03 11:20:58 +02:00
|
|
|
/* list of present windows, to be consumed by the layouter */
|
|
|
|
Reporter window_list_reporter = { "window_list" };
|
2015-05-30 16:18:23 +02:00
|
|
|
|
2015-09-29 20:16:28 +02:00
|
|
|
/* request to the layouter to set the focus */
|
|
|
|
Reporter focus_request_reporter = { "focus_request" };
|
|
|
|
|
2014-01-06 19:15:14 +01:00
|
|
|
Window_registry window_registry { *env()->heap(), window_list_reporter };
|
|
|
|
|
2015-09-29 22:23:36 +02:00
|
|
|
Nitpicker::Connection focus_nitpicker_session;
|
|
|
|
|
2014-01-06 19:15:14 +01:00
|
|
|
Nitpicker::Root nitpicker_root { ep, window_registry,
|
2015-05-30 16:18:23 +02:00
|
|
|
*env()->heap(), env()->ram_session_cap(),
|
2015-09-29 22:23:36 +02:00
|
|
|
pointer_reporter, focus_request_reporter,
|
|
|
|
focus_nitpicker_session };
|
2014-01-06 19:15:14 +01:00
|
|
|
|
|
|
|
void handle_focus_update(unsigned)
|
|
|
|
{
|
|
|
|
try {
|
2015-06-03 11:20:58 +02:00
|
|
|
focus_rom.update();
|
2014-01-06 19:15:14 +01:00
|
|
|
|
|
|
|
unsigned long win_id = 0;
|
|
|
|
|
2015-06-03 11:20:58 +02:00
|
|
|
Xml_node(focus_rom.local_addr<char>()).sub_node("window")
|
2014-01-06 19:15:14 +01:00
|
|
|
.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<Main> focus_dispatcher = { ep, *this, &Main::handle_focus_update };
|
|
|
|
|
|
|
|
void handle_resize_request_update(unsigned)
|
|
|
|
{
|
|
|
|
try {
|
2015-06-03 11:20:58 +02:00
|
|
|
resize_request_rom.update();
|
2014-01-06 19:15:14 +01:00
|
|
|
|
|
|
|
char const * const node_type = "window";
|
|
|
|
|
|
|
|
Xml_node window =
|
2015-06-03 11:20:58 +02:00
|
|
|
Xml_node(resize_request_rom.local_addr<char>()).sub_node(node_type);
|
2014-01-06 19:15:14 +01:00
|
|
|
|
|
|
|
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<Main> resize_request_dispatcher =
|
|
|
|
{ ep, *this, &Main::handle_resize_request_update };
|
|
|
|
|
|
|
|
Main(Server::Entrypoint &ep) : ep(ep)
|
|
|
|
{
|
2015-06-03 11:20:58 +02:00
|
|
|
pointer_reporter.enabled(true);
|
2014-01-06 19:15:14 +01:00
|
|
|
|
|
|
|
/* initially report an empty window list */
|
2015-06-03 11:20:58 +02:00
|
|
|
window_list_reporter.enabled(true);
|
|
|
|
Genode::Reporter::Xml_generator xml(window_list_reporter, [&] () { });
|
2014-01-06 19:15:14 +01:00
|
|
|
|
2015-09-29 20:16:28 +02:00
|
|
|
focus_request_reporter.enabled(true);
|
|
|
|
|
2014-01-06 19:15:14 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|