diff --git a/os/src/drivers/input/ps2/event_queue.h b/os/include/input/event_queue.h
similarity index 98%
rename from os/src/drivers/input/ps2/event_queue.h
rename to os/include/input/event_queue.h
index a35dcd323..499b6f5d1 100644
--- a/os/src/drivers/input/ps2/event_queue.h
+++ b/os/include/input/event_queue.h
@@ -14,6 +14,7 @@
#ifndef _EVENT_QUEUE_H_
#define _EVENT_QUEUE_H_
+#include
#include
#include
diff --git a/os/src/drivers/input/ps2/ps2_keyboard.h b/os/src/drivers/input/ps2/ps2_keyboard.h
index 52ff0b885..435653f61 100644
--- a/os/src/drivers/input/ps2/ps2_keyboard.h
+++ b/os/src/drivers/input/ps2/ps2_keyboard.h
@@ -15,13 +15,13 @@
#define _PS2_KEYBOARD_H_
#include
+#include
#include
#include "input_driver.h"
#include "serial_interface.h"
#include "scan_code_set_1.h"
#include "scan_code_set_2.h"
-#include "event_queue.h"
class Ps2_keyboard : public Input_driver
{
diff --git a/os/src/drivers/input/ps2/ps2_mouse.h b/os/src/drivers/input/ps2/ps2_mouse.h
index 8b92a2060..d9a4e7074 100644
--- a/os/src/drivers/input/ps2/ps2_mouse.h
+++ b/os/src/drivers/input/ps2/ps2_mouse.h
@@ -15,9 +15,9 @@
#define _PS2_MOUSE_H_
#include
+#include
#include
-#include "event_queue.h"
#include "input_driver.h"
class Ps2_mouse : public Input_driver
diff --git a/qt4/run/qt_avplay.run b/qt4/run/qt_avplay.run
new file mode 100644
index 000000000..1764a9697
--- /dev/null
+++ b/qt4/run/qt_avplay.run
@@ -0,0 +1,160 @@
+#
+# Build
+#
+
+build {
+ core
+ init
+ drivers/input/ps2
+ drivers/pci
+ drivers/framebuffer
+ drivers/timer
+ drivers/audio_out
+ server/nitpicker
+ app/avplay
+ app/qt_avplay
+}
+
+#
+# Download media file
+#
+
+set media_url "ftp://ftp.untergrund.net/users/ae/dhstv/escape-chotro.mp4"
+if {![file exists bin/mediafile]} {
+ puts "downloading media file from $media_url"
+ catch { exec wget -O bin/mediafile $media_url }
+}
+
+create_boot_directory
+
+#
+# Generate config
+#
+
+set config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_if [have_spec sdl] config {
+
+
+
+
+
+
+ }
+
+append_if [have_spec pci] config {
+
+
+
+ }
+
+append_if [have_spec vesa] config {
+
+
+
+ }
+
+append_if [have_spec pl11x] config {
+
+
+
+ }
+
+append_if [have_spec ps2] config {
+
+
+
+ }
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+#
+# Boot modules
+#
+
+# generic modules
+set boot_modules {
+ core
+ init
+ timer
+ audio_out_drv
+ nitpicker
+ qt_avplay
+ dejavusans.lib.so
+ freetype.lib.so
+ ld.lib.so
+ libc.lib.so
+ libc_lock_pipe.lib.so
+ libm.lib.so
+ libpng.lib.so
+ jpeg.lib.so
+ qnitpickerviewwidget.lib.so
+ qt_core.lib.so
+ qt_gui.lib.so
+ qt_xml.lib.so
+ zlib.lib.so
+ avcodec.lib.so
+ avformat.lib.so
+ avutil.lib.so
+ avfilter.lib.so
+ swscale.lib.so
+ sdl.lib.so
+ pthread.lib.so
+ libc_log.lib.so
+ libc_rom.lib.so
+ avplay
+ mediafile
+}
+
+# platform-specific modules
+lappend_if [have_spec linux] boot_modules fb_sdl
+lappend_if [have_spec pci] boot_modules pci_drv
+lappend_if [have_spec vesa] boot_modules vesa_drv
+lappend_if [have_spec ps2] boot_modules ps2_drv
+lappend_if [have_spec pl11x] boot_modules pl11x_drv
+
+build_boot_image $boot_modules
+
+append qemu_args " -m 512 -soundhw all"
+
+run_genode_until forever
+
diff --git a/qt4/src/app/qt_avplay/README b/qt4/src/app/qt_avplay/README
new file mode 100644
index 000000000..5e9a2ef51
--- /dev/null
+++ b/qt4/src/app/qt_avplay/README
@@ -0,0 +1,18 @@
+This directory contains a simple Qt-based media player which is actually a
+graphical user interface for the SDL-based 'avplay' media player from 'libav'.
+It starts 'avplay' as a child and shows its graphical output in a
+'QNitpickerViewWidget'. The widgets for controlling the player state send the
+according keyboard and mouse input events to 'avplay'.
+
+The 'qt_avplay' player supports the following configuration options:
+
+:':'
+ name of the media file to play
+
+:'':
+
+ This node contains the name of a framebuffer filter service to filter the
+ video output. It may appear multiple times. If specified more than once, it
+ is possible to build a post-processing pipeline for the video display where
+ each processing stage is executed by a separate program.
+
diff --git a/qt4/src/app/qt_avplay/avplay_policy.h b/qt4/src/app/qt_avplay/avplay_policy.h
new file mode 100644
index 000000000..e010ab528
--- /dev/null
+++ b/qt4/src/app/qt_avplay/avplay_policy.h
@@ -0,0 +1,115 @@
+/*
+ * \brief Avplay policy
+ * \author Christian Prochaska
+ * \date 2012-04-05
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _AVPLAY_POLICY_H_
+#define _AVPLAY_POLICY_H_
+
+/* Qt4 includes */
+#include
+#include
+#include
+#include
+#include
+
+/* Genode includes */
+#include
+
+
+class Avplay_policy : public QObject, public Genode::Slave_policy
+{
+ Q_OBJECT
+
+ private:
+
+ Genode::Service_registry &_input_in;
+ Genode::Service_registry &_framebuffer_in;
+
+ const char *_mediafile;
+ int _sdl_audio_volume;
+ QByteArray _config_byte_array;
+
+
+ const char *_config()
+ {
+ QDomDocument config_doc;
+
+ QDomElement config_node = config_doc.createElement("config");
+ config_doc.appendChild(config_node);
+
+ QDomElement arg0_node = config_doc.createElement("arg");
+ arg0_node.setAttribute("value", "avplay");
+ config_node.appendChild(arg0_node);
+
+ QDomElement arg1_node = config_doc.createElement("arg");
+ arg1_node.setAttribute("value", _mediafile);
+ config_node.appendChild(arg1_node);
+
+ QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume");
+ sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume));
+ config_node.appendChild(sdl_audio_volume_node);
+
+ _config_byte_array = config_doc.toByteArray(4);
+
+ return _config_byte_array.constData();
+ }
+
+ protected:
+
+ const char **_permitted_services() const
+ {
+ static const char *permitted_services[] = {
+ "CAP", "LOG", "RM", "ROM", "SIGNAL",
+ "Timer", "Audio_out", 0 };
+
+ return permitted_services;
+ };
+
+ public:
+
+ Avplay_policy(Genode::Rpc_entrypoint &entrypoint,
+ Genode::Service_registry &input_in,
+ Genode::Service_registry &framebuffer_in,
+ const char *mediafile)
+ : Genode::Slave_policy("avplay", entrypoint, Genode::env()->ram_session()),
+ _input_in(input_in),
+ _framebuffer_in(framebuffer_in),
+ _mediafile(mediafile),
+ _sdl_audio_volume(100)
+ {
+ configure(_config());
+ }
+
+ Genode::Service *resolve_session_request(const char *service_name,
+ const char *args)
+ {
+ if (strcmp(service_name, "Input") == 0)
+ return _input_in.find(service_name);
+
+ if (strcmp(service_name, "Framebuffer") == 0) {
+ Genode::Client client;
+ return _framebuffer_in.wait_for_service(service_name, &client, name());
+ }
+
+ return Slave_policy::resolve_session_request(service_name, args);
+ }
+
+ public Q_SLOTS:
+
+ void volume_changed(int value)
+ {
+ _sdl_audio_volume = value;
+ configure(_config());
+ }
+};
+
+#endif /* _AVPLAY_POLICY_H_ */
diff --git a/qt4/src/app/qt_avplay/control_bar.cpp b/qt4/src/app/qt_avplay/control_bar.cpp
new file mode 100644
index 000000000..d830364ad
--- /dev/null
+++ b/qt4/src/app/qt_avplay/control_bar.cpp
@@ -0,0 +1,73 @@
+/*
+ * \brief Control bar
+ * \author Christian Prochaska
+ * \date 2012-03-30
+ */
+
+/*
+ * Copyright (C) 2012 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
+
+/* Qoost includes */
+#include
+
+#include "input_service.h"
+#include "main_window.h"
+
+
+void Control_bar::_rewind()
+{
+ /* mouse click at horizontal position 0 */
+ ev_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0));
+ ev_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0));
+}
+
+
+void Control_bar::_pause_resume()
+{
+ ev_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0));
+ ev_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0));
+
+ _playing = !_playing;
+ if (_playing)
+ update_style_id(_play_pause_button, "play");
+ else
+ update_style_id(_play_pause_button, "pause");
+}
+
+
+void Control_bar::_stop()
+{
+ if (_playing)
+ _pause_resume();
+
+ _rewind();
+}
+
+
+Control_bar::Control_bar()
+: _playing(true)
+{
+ update_style_id(_play_pause_button, "play");
+
+ _volume_slider->setOrientation(Qt::Horizontal);
+ _volume_slider->setRange(0, 100);
+ _volume_slider->setTickInterval(10);
+ _volume_slider->setValue(100);
+
+ _layout->addWidget(_play_pause_button);
+ _layout->addWidget(_stop_button);
+ _layout->addStretch();
+ _layout->addWidget(_volume_label);
+ _layout->addWidget(_volume_slider);
+
+ connect(_play_pause_button, SIGNAL(clicked()), this, SLOT(_pause_resume()));
+ connect(_stop_button, SIGNAL(clicked()), this, SLOT(_stop()));
+ connect(_volume_slider, SIGNAL(valueChanged(int)), this, SIGNAL(volume_changed(int)));
+}
diff --git a/qt4/src/app/qt_avplay/control_bar.h b/qt4/src/app/qt_avplay/control_bar.h
new file mode 100644
index 000000000..05b1db5a7
--- /dev/null
+++ b/qt4/src/app/qt_avplay/control_bar.h
@@ -0,0 +1,58 @@
+/*
+ * \brief Control bar
+ * \author Christian Prochaska
+ * \date 2012-03-30
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _CONTROL_BAR_H_
+#define _CONTROL_BAR_H_
+
+/* Qt includes */
+#include
+
+/* Qoost includes */
+#include
+#include
+
+struct Play_pause_button : QPushButton { Q_OBJECT };
+struct Stop_button : QPushButton { Q_OBJECT };
+struct Volume_label : QLabel { Q_OBJECT };
+struct Volume_slider : QSlider { Q_OBJECT };
+
+class Control_bar : public Compound_widget
+{
+ Q_OBJECT
+
+ private:
+
+ QMember _play_pause_button;
+ QMember _stop_button;
+ QMember _volume_label;
+ QMember _volume_slider;
+
+ bool _playing;
+
+ void _rewind();
+
+ private Q_SLOTS:
+
+ void _pause_resume();
+ void _stop();
+
+ public:
+
+ Control_bar();
+
+ Q_SIGNALS:
+
+ void volume_changed(int value);
+};
+
+#endif /* _CONTROL_BAR_H_ */
diff --git a/qt4/src/app/qt_avplay/filter_framebuffer_policy.h b/qt4/src/app/qt_avplay/filter_framebuffer_policy.h
new file mode 100644
index 000000000..e417d2505
--- /dev/null
+++ b/qt4/src/app/qt_avplay/filter_framebuffer_policy.h
@@ -0,0 +1,77 @@
+/*
+ * \brief Filter framebuffer policy
+ * \author Christian Prochaska
+ * \date 2012-04-11
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _FILTER_FRAMEBUFFER_POLICY_H_
+#define _FILTER_FRAMEBUFFER_POLICY_H_
+
+/* Genode includes */
+#include
+#include
+
+
+class Filter_framebuffer_policy : public Genode::Slave_policy
+{
+ private:
+
+ Genode::Service_registry &_framebuffer_in;
+ Genode::Service_registry &_framebuffer_out;
+
+ protected:
+
+ const char **_permitted_services() const
+ {
+ static const char *permitted_services[] = {
+ "CAP", "LOG", "RM", "ROM", "SIGNAL",
+ "Timer", 0 };
+
+ return permitted_services;
+ };
+
+ public:
+
+ Filter_framebuffer_policy(const char *name,
+ Genode::Rpc_entrypoint &entrypoint,
+ Genode::Service_registry &framebuffer_in,
+ Genode::Service_registry &framebuffer_out)
+ : Genode::Slave_policy(name, entrypoint, Genode::env()->ram_session()),
+ _framebuffer_in(framebuffer_in),
+ _framebuffer_out(framebuffer_out) { }
+
+ Genode::Service *resolve_session_request(const char *service_name,
+ const char *args)
+ {
+ if (strcmp(service_name, "Framebuffer") == 0) {
+ Genode::Client client;
+ return _framebuffer_in.wait_for_service(service_name, &client, name());
+ }
+
+ return Slave_policy::resolve_session_request(service_name, args);
+ }
+
+ bool announce_service(const char *name,
+ Genode::Root_capability root,
+ Genode::Allocator *alloc,
+ Genode::Server *server)
+ {
+ if (strcmp(name, "Framebuffer") == 0) {
+ _framebuffer_out.insert(new (alloc) Genode::Child_service(name, root, server));
+ return true;
+ }
+
+ return Slave_policy::announce_service(name, root, alloc, server);
+ }
+
+
+};
+
+#endif /* _FILTER_FRAMEBUFFER_POLICY_H_ */
diff --git a/qt4/src/app/qt_avplay/framebuffer_root.h b/qt4/src/app/qt_avplay/framebuffer_root.h
new file mode 100644
index 000000000..b4d933099
--- /dev/null
+++ b/qt4/src/app/qt_avplay/framebuffer_root.h
@@ -0,0 +1,64 @@
+/*
+ * \brief Framebuffer root
+ * \author Christian Prochaska
+ * \date 2012-04-02
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+
+#ifndef _FRAMEBUFFER_ROOT_H_
+#define _FRAMEBUFFER_ROOT_H_
+
+/* Genode includes */
+#include
+
+#include "framebuffer_session_component.h"
+
+namespace Framebuffer {
+
+ /**
+ * Shortcut for single-client root component
+ */
+ typedef Genode::Root_component Root_component;
+
+
+ class Root : public Root_component
+ {
+ private:
+
+ QNitpickerViewWidget &_nitpicker_view_widget;
+ int _max_width;
+ int _max_height;
+
+ protected:
+
+ Session_component *_create_session(const char *args)
+ {
+ return new (md_alloc())
+ Session_component(args, _nitpicker_view_widget,
+ _max_width, _max_height);
+ }
+
+ public:
+
+ Root(Genode::Rpc_entrypoint *session_ep,
+ Genode::Allocator *md_alloc,
+ QNitpickerViewWidget &nitpicker_view_widget,
+ int max_width = 0,
+ int max_height = 0)
+ : Root_component(session_ep, md_alloc),
+ _nitpicker_view_widget(nitpicker_view_widget),
+ _max_width(max_width),
+ _max_height(max_height) { }
+
+ };
+
+}
+
+#endif /* _FRAMEBUFFER_ROOT_H_ */
diff --git a/qt4/src/app/qt_avplay/framebuffer_session_component.cc b/qt4/src/app/qt_avplay/framebuffer_session_component.cc
new file mode 100644
index 000000000..f2ae5f45b
--- /dev/null
+++ b/qt4/src/app/qt_avplay/framebuffer_session_component.cc
@@ -0,0 +1,86 @@
+/*
+ * \brief Framebuffer session component
+ * \author Christian Prochaska
+ * \date 2012-04-02
+ */
+
+/*
+ * Copyright (C) 2012 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 "framebuffer_session_component.h"
+
+namespace Framebuffer {
+
+
+ int Session_component::_limited_size(int requested_size, int max_size)
+ {
+ if (requested_size == 0)
+ return max_size;
+ else
+ return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size;
+ }
+
+
+ static inline long session_arg(const char *arg, const char *key)
+ {
+ return Genode::Arg_string::find_arg(arg, key).long_value(0);
+ }
+
+
+ Session_component::Session_component(const char *args,
+ QNitpickerViewWidget &nitpicker_view_widget,
+ int max_width,
+ int max_height)
+ : _nitpicker(Nitpicker::Connection(
+ _limited_size(session_arg(args, "fb_width"), max_width),
+ _limited_size(session_arg(args, "fb_height"), max_height))),
+ _framebuffer(_nitpicker.framebuffer_session())
+ {
+ Nitpicker::View_capability nitpicker_view_cap = _nitpicker.create_view();
+ Mode _mode = _framebuffer.mode();
+ nitpicker_view_widget.setNitpickerView(nitpicker_view_cap,
+ 0, 0,
+ _mode.width(),
+ _mode.height());
+ }
+
+
+ Genode::Dataspace_capability Session_component::dataspace()
+ {
+ return _framebuffer.dataspace();
+ }
+
+
+ void Session_component::release()
+ {
+ _framebuffer.release();
+ }
+
+
+ Mode Session_component::mode() const
+ {
+ return _framebuffer.mode();
+ }
+
+
+ void Session_component::mode_sigh(Genode::Signal_context_capability sigh_cap)
+ {
+ _framebuffer.mode_sigh(sigh_cap);
+ }
+
+
+ void Session_component::refresh(int x, int y, int w, int h)
+ {
+ _framebuffer.refresh(x, y, w, h);
+ }
+}
diff --git a/qt4/src/app/qt_avplay/framebuffer_session_component.h b/qt4/src/app/qt_avplay/framebuffer_session_component.h
new file mode 100644
index 000000000..ed917b97c
--- /dev/null
+++ b/qt4/src/app/qt_avplay/framebuffer_session_component.h
@@ -0,0 +1,57 @@
+/*
+ * \brief Framebuffer session component
+ * \author Christian Prochaska
+ * \date 2012-04-02
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+
+#ifndef _FRAMEBUFFER_SESSION_COMPONENT_H_
+#define _FRAMEBUFFER_SESSION_COMPONENT_H_
+
+/* Genode includes */
+#include
+#include
+#include
+
+/* Qt4 includes */
+#include
+
+
+namespace Framebuffer {
+
+ class Session_component : public Genode::Rpc_object
+ {
+ private:
+
+ Nitpicker::Connection _nitpicker;
+ Session_client _framebuffer;
+
+ int _limited_size(int requested_size, int max_size);
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Session_component(const char *args,
+ QNitpickerViewWidget &nitpicker_view_widget,
+ int max_width = 0,
+ int max_height = 0);
+
+ Genode::Dataspace_capability dataspace();
+ void release();
+ Mode mode() const;
+ void mode_sigh(Genode::Signal_context_capability sigh_cap);
+ void refresh(int x, int y, int w, int h);
+ };
+
+}
+
+#endif /* _FRAMEBUFFER_SESSION_COMPONENT_H_ */
diff --git a/qt4/src/app/qt_avplay/input_service.cpp b/qt4/src/app/qt_avplay/input_service.cpp
new file mode 100644
index 000000000..99d9a098f
--- /dev/null
+++ b/qt4/src/app/qt_avplay/input_service.cpp
@@ -0,0 +1,40 @@
+/*
+ * \brief Input service
+ * \author Christian Prochaska
+ * \date 2012-03-29
+ */
+
+/*
+ * Copyright (C) 2012 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 "input_service.h"
+
+using namespace Genode;
+
+Event_queue ev_queue;
+
+
+namespace Input {
+
+ /*
+ * Event handling is disabled on queue creation and will be enabled later if a
+ * session is created.
+ */
+ void event_handling(bool enable)
+ {
+ if (enable)
+ ev_queue.enable();
+ else
+ ev_queue.disable();
+ }
+
+ bool event_pending() { return !ev_queue.empty(); }
+ Event get_event() { return ev_queue.get(); }
+}
diff --git a/qt4/src/app/qt_avplay/input_service.h b/qt4/src/app/qt_avplay/input_service.h
new file mode 100644
index 000000000..0fb0f06a1
--- /dev/null
+++ b/qt4/src/app/qt_avplay/input_service.h
@@ -0,0 +1,24 @@
+/*
+ * \brief Input service
+ * \author Christian Prochaska
+ * \date 2012-03-29
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _INPUT_SERVICE_H_
+#define _INPUT_SERVICE_H_
+
+/* Genode includes */
+#include
+
+extern Event_queue ev_queue;
+
+extern void create_input_service();
+
+#endif /* _INPUT_SERVICE_H_ */
diff --git a/qt4/src/app/qt_avplay/main.cpp b/qt4/src/app/qt_avplay/main.cpp
new file mode 100644
index 000000000..5e4b5094f
--- /dev/null
+++ b/qt4/src/app/qt_avplay/main.cpp
@@ -0,0 +1,45 @@
+/*
+ * \brief Simple Qt interface for 'avplay' media player
+ * \author Christian Prochaska
+ * \date 2012-03-21
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/* Qt includes */
+#include
+
+/* qt_avplay includes */
+#include "main_window.h"
+
+
+static inline void load_stylesheet()
+{
+ QFile file(":style.qss");
+ if (!file.open(QFile::ReadOnly)) {
+ qWarning() << "Warning:" << file.errorString()
+ << "opening file" << file.fileName();
+ return;
+ }
+
+ qApp->setStyleSheet(QLatin1String(file.readAll()));
+}
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ load_stylesheet();
+
+ QMember main_window;
+
+ main_window->show();
+
+ return app.exec();
+}
diff --git a/qt4/src/app/qt_avplay/main_window.cpp b/qt4/src/app/qt_avplay/main_window.cpp
new file mode 100644
index 000000000..49670d5b3
--- /dev/null
+++ b/qt4/src/app/qt_avplay/main_window.cpp
@@ -0,0 +1,129 @@
+/*
+ * \brief Main window of the media player
+ * \author Christian Prochaska
+ * \date 2012-03-29
+ */
+
+/*
+ * Copyright (C) 2012 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
+
+/* qt_avplay includes */
+#include "avplay_policy.h"
+#include "filter_framebuffer_policy.h"
+#include "framebuffer_root.h"
+#include "input_service.h"
+#include "main_window.h"
+
+
+using namespace Genode;
+
+
+struct Framebuffer_filter
+{
+ enum { MAX_FILTER_NAME_SIZE = 32 };
+ char name[MAX_FILTER_NAME_SIZE];
+ Genode::Number_of_bytes ram_quota;
+
+ Service_registry *framebuffer_out_registry;
+ Rpc_entrypoint *ep;
+ Filter_framebuffer_policy *policy;
+ Slave *slave;
+};
+
+
+Main_window::Main_window()
+{
+ /* look for dynamic linker */
+
+ try {
+ static Rom_connection ldso_rom("ld.lib.so");
+ Process::dynamic_linker(ldso_rom.dataspace());
+ } catch (...) {
+ PERR("ld.lib.so not found");
+ }
+
+ /* get the name of the media file from the config file */
+ enum { MAX_LEN_MEDIAFILE_NAME = 256 };
+ static char mediafile[MAX_LEN_MEDIAFILE_NAME] = "mediafile";
+ try {
+ config()->xml_node().sub_node("mediafile").attribute("name").value(mediafile, sizeof(mediafile));
+ } catch(...) {
+ PWRN("no config node found, using \"mediafile\"");
+ }
+
+ /* create local services */
+
+ enum { STACK_SIZE = 2*sizeof(addr_t)*1024 };
+ static Cap_connection cap;
+ static Rpc_entrypoint avplay_ep(&cap, STACK_SIZE, "avplay_ep");
+ static Service_registry input_registry;
+ static Service_registry nitpicker_framebuffer_registry;
+
+ static Input::Root input_root(&avplay_ep, env()->heap());
+ static Local_service input_service(Input::Session::service_name(), &input_root);
+ input_registry.insert(&input_service);
+ avplay_ep.manage(&input_root);
+
+ /* find out which filtering framebuffer services to start and sort them in reverse order */
+
+ static QList framebuffer_filters;
+ try {
+ Xml_node node = config()->xml_node().sub_node("framebuffer_filter");
+ for (; ; node = node.next("framebuffer_filter")) {
+ Framebuffer_filter *framebuffer_filter = new Framebuffer_filter;
+ node.attribute("name").value(framebuffer_filter->name, sizeof(framebuffer_filter->name));
+ node.attribute("ram_quota").value(&framebuffer_filter->ram_quota);
+ qDebug() << "filter:" << framebuffer_filter->name << "," << framebuffer_filter->ram_quota;
+ framebuffer_filters.prepend(framebuffer_filter);
+ }
+ } catch (Config::Invalid) {
+ } catch (Xml_node::Nonexistent_sub_node) {
+ }
+
+ /* start the filtering framebuffer services */
+
+ Service_registry *framebuffer_in_registry = &nitpicker_framebuffer_registry;
+
+ Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) {
+ framebuffer_filter->framebuffer_out_registry = new Service_registry;
+ framebuffer_filter->ep = new Rpc_entrypoint(&cap, STACK_SIZE, "filter_fb_ep");
+ framebuffer_filter->policy = new Filter_framebuffer_policy(framebuffer_filter->name,
+ *framebuffer_filter->ep,
+ *framebuffer_in_registry,
+ *framebuffer_filter->framebuffer_out_registry);
+ framebuffer_filter->slave = new Slave(*framebuffer_filter->ep,
+ *framebuffer_filter->policy,
+ framebuffer_filter->ram_quota);
+ framebuffer_in_registry = framebuffer_filter->framebuffer_out_registry;
+ }
+
+ Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ?
+ &avplay_ep :
+ framebuffer_filters.at(0)->ep;
+
+ static Framebuffer::Root framebuffer_root(local_framebuffer_ep, env()->heap(), *_avplay_widget, 640, 480);
+ static Local_service framebuffer_service(Framebuffer::Session::service_name(), &framebuffer_root);
+ nitpicker_framebuffer_registry.insert(&framebuffer_service);
+
+ /* start avplay */
+
+ static Avplay_policy avplay_policy(avplay_ep, input_registry, *framebuffer_in_registry, mediafile);
+ static Genode::Slave avplay_slave(avplay_ep, avplay_policy, 32*1024*1024);
+
+ /* add widgets to layout */
+
+ _layout->addWidget(_avplay_widget);
+ _layout->addWidget(_control_bar);
+
+ connect(_control_bar, SIGNAL(volume_changed(int)), &avplay_policy, SLOT(volume_changed(int)));
+}
diff --git a/qt4/src/app/qt_avplay/main_window.h b/qt4/src/app/qt_avplay/main_window.h
new file mode 100644
index 000000000..7931c7a06
--- /dev/null
+++ b/qt4/src/app/qt_avplay/main_window.h
@@ -0,0 +1,43 @@
+/*
+ * \brief Main window of the media player
+ * \author Christian Prochaska
+ * \date 2012-03-29
+ */
+
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef _MAIN_WINDOW_H_
+#define _MAIN_WINDOW_H_
+
+/* Qt includes */
+#include
+#include
+#include
+
+/* Qoost includes */
+#include
+#include
+
+#include "control_bar.h"
+
+
+class Main_window : public Compound_widget
+{
+ Q_OBJECT
+
+ private:
+
+ QMember _avplay_widget;
+ QMember _control_bar;
+
+ public:
+
+ Main_window();
+};
+
+#endif /* _MAIN_WINDOW_H_ */
diff --git a/qt4/src/app/qt_avplay/qt_avplay.pro b/qt4/src/app/qt_avplay/qt_avplay.pro
new file mode 100644
index 000000000..8b9dc41c5
--- /dev/null
+++ b/qt4/src/app/qt_avplay/qt_avplay.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = qt_avplay
+QT = core gui xml
+HEADERS = avplay_policy.h \
+ control_bar.h \
+ main_window.h
+SOURCES = control_bar.cpp \
+ framebuffer_session_component.cc \
+ input_service.cpp \
+ main.cpp \
+ main_window.cpp
+RESOURCES = style.qrc
diff --git a/qt4/src/app/qt_avplay/style.qrc b/qt4/src/app/qt_avplay/style.qrc
new file mode 100644
index 000000000..0adacff03
--- /dev/null
+++ b/qt4/src/app/qt_avplay/style.qrc
@@ -0,0 +1,10 @@
+
+
+
+style.qss
+../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_play.png
+../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_pause.png
+../../../contrib/qt-everywhere-opensource-src-4.7.4/examples/network/torrent/icons/player_stop.png
+../../../contrib/qt-everywhere-opensource-src-4.7.4/demos/mobile/guitartuner/src/mycomponents/images/volume.png
+
+
diff --git a/qt4/src/app/qt_avplay/style.qss b/qt4/src/app/qt_avplay/style.qss
new file mode 100644
index 000000000..08e0a4d73
--- /dev/null
+++ b/qt4/src/app/qt_avplay/style.qss
@@ -0,0 +1,32 @@
+Main_window {
+ max-width: 640px;
+ max-height: 512px;
+}
+
+Play_pause_button, Stop_button {
+ width: 32px;
+ height: 32px;
+}
+
+Play_pause_button#play {
+ border-image: url(:player_pause.png);
+}
+
+
+Play_pause_button#pause {
+ border-image: url(:player_play.png);
+}
+
+
+Stop_button {
+ border-image: url(:player_stop.png);
+}
+
+Volume_label {
+ background-image: url(:volume.png);
+ min-width: 16px;
+ max-width: 32px;
+ min-height: 16px;
+ max-height: 32px;
+ margin-right: 5px;
+}
diff --git a/qt4/src/app/qt_avplay/target.mk b/qt4/src/app/qt_avplay/target.mk
new file mode 100644
index 000000000..d60ce481b
--- /dev/null
+++ b/qt4/src/app/qt_avplay/target.mk
@@ -0,0 +1,9 @@
+# identify the qt4 repository by searching for a file that is unique for qt4
+QT4_REP_DIR := $(call select_from_repositories,lib/import/import-qt4.inc)
+QT4_REP_DIR := $(realpath $(dir $(QT4_REP_DIR))../..)
+
+include $(QT4_REP_DIR)/src/app/tmpl/target_defaults.inc
+
+include $(QT4_REP_DIR)/src/app/tmpl/target_final.inc
+
+LIBS += qnitpickerviewwidget