diff --git a/repos/dde_linux/run/intel_fb.run b/repos/dde_linux/run/intel_fb.run
index 647fef9a11..887e25814b 100644
--- a/repos/dde_linux/run/intel_fb.run
+++ b/repos/dde_linux/run/intel_fb.run
@@ -48,8 +48,38 @@ append config {
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -58,6 +88,16 @@ append config {
+
+
+
+
+
+
+
+
+
+
@@ -71,8 +111,8 @@ install_config $config
# generic modules
set boot_modules {
- core init timer intel_fb_drv
- test-framebuffer report_rom
+ core init timer intel_fb_drv intel_fb_controller
+ test-framebuffer report_rom ram_fs fs_rom
}
append_platform_drv_boot_modules
diff --git a/repos/dde_linux/src/test/framebuffer/intel/main.cc b/repos/dde_linux/src/test/framebuffer/intel/main.cc
new file mode 100644
index 0000000000..9dde78c974
--- /dev/null
+++ b/repos/dde_linux/src/test/framebuffer/intel/main.cc
@@ -0,0 +1,127 @@
+/*
+ * \brief Test controller for Intel framebuffer driver
+ * \author Stefan Kalkowski
+ * \date 2016-04-19
+ */
+
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace Genode;
+
+
+struct Framebuffer_controller
+{
+ Attached_rom_dataspace rom;
+ Signal_handler rom_sigh;
+ Heap heap;
+ Allocator_avl fs_alloc;
+ File_system::Connection fs;
+
+ void update_connector_config(Xml_generator & xml, Xml_node & node);
+ void update_fb_config(Xml_node & report);
+ void report_changed();
+
+ Framebuffer_controller(Env &env)
+ : rom("connectors"),
+ rom_sigh(env.ep(), *this, &Framebuffer_controller::report_changed),
+ heap(env.ram(), env.rm()),
+ fs_alloc(&heap),
+ fs(fs_alloc, 128*1024, "")
+ {
+ rom.sigh(rom_sigh);
+ }
+};
+
+
+void Framebuffer_controller::update_connector_config(Xml_generator & xml,
+ Xml_node & node)
+{
+ xml.node("connector", [&] {
+ String<64> name;
+ node.attribute("name").value(&name);
+ xml.attribute("name", name.string());
+
+ bool connected = node.attribute_value("connected", false);
+ xml.attribute("enabled", connected ? "true" : "false");
+
+ unsigned long width = 0, height = 0;
+ node.for_each_sub_node("mode", [&] (Xml_node &mode) {
+ unsigned long w, h;
+ w = mode.attribute_value("width", 0);
+ h = mode.attribute_value("height", 0);
+ if (w > width) {
+ width = w;
+ height = h;
+ }
+ });
+
+ if (width && height) {
+ xml.attribute("width", width);
+ xml.attribute("height", height);
+ }
+ });
+}
+
+
+void Framebuffer_controller::update_fb_config(Xml_node & report)
+{
+ try {
+ static char buf[4096];
+
+ Xml_generator xml(buf, sizeof(buf), "config", [&] {
+ xml.attribute("buffered", "yes");
+ xml.node("report", [&] {
+ xml.attribute("connectors", "yes");
+ });
+
+ report.for_each_sub_node("connector", [&] (Xml_node &node) {
+ update_connector_config(xml, node); });
+ });
+ buf[xml.used()] = 0;
+
+ File_system::Dir_handle root_dir = fs.dir("/", false);
+ File_system::File_handle file =
+ fs.file(root_dir, "fb_drv.config", File_system::READ_WRITE, false);
+ if (File_system::write(fs, file, buf, xml.used()) == 0)
+ error("Could not write config");
+ fs.close(file);
+ } catch (...) {
+ error("Cannot update config");
+ }
+}
+
+
+void Framebuffer_controller::report_changed()
+{
+ rom.update();
+ if (!rom.is_valid()) return;
+
+ Xml_node report(rom.local_addr(), rom.size());
+ update_fb_config(report);
+}
+
+
+void Component::construct(Genode::Env &env)
+{
+ log("--- Framebuffer controller ---\n");
+ static Framebuffer_controller controller(env);
+}
+
+
+size_t Component::stack_size() {
+ return 4*1024*sizeof(long); }
diff --git a/repos/dde_linux/src/test/framebuffer/intel/target.mk b/repos/dde_linux/src/test/framebuffer/intel/target.mk
new file mode 100644
index 0000000000..d13e873cb3
--- /dev/null
+++ b/repos/dde_linux/src/test/framebuffer/intel/target.mk
@@ -0,0 +1,3 @@
+TARGET = intel_fb_controller
+LIBS = base
+SRC_CC = main.cc