diff --git a/run/julia_fractal.run b/run/julia_fractal.run
new file mode 100644
index 0000000..b2b3a18
--- /dev/null
+++ b/run/julia_fractal.run
@@ -0,0 +1,85 @@
+create_boot_directory
+
+import_from_depot genodelabs/pkg/wm
+
+build "core init drivers/timer server/nitpicker server/wm app/julia_fractal"
+
+# Only supports the linux kernel, for now;
+# instantiates an fb_sdl explicitly, rather than using custom code or a package.
+install_config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+set fd [open [run_dir]/genode/focus w]
+puts $fd " wm -> \"/>"
+close $fd
+
+build_boot_image "core ld.lib.so libc.lib.so vfs.lib.so libm.lib.so stdcxx.lib.so init timer fb_sdl nitpicker wm pointer julia_fractal"
+run_genode_until forever
diff --git a/src/app/julia_fractal/main.cc b/src/app/julia_fractal/main.cc
new file mode 100644
index 0000000..de1156d
--- /dev/null
+++ b/src/app/julia_fractal/main.cc
@@ -0,0 +1,191 @@
+/*
+ * \brief Displays julia sets and responds to mode resize events
+ * \author Daniel Collins
+ * \date 2018-06-22
+ *
+ * Creates a pretty animation by drawing successive julia set representations,
+ * periodically varying a constant factor.
+ *
+ * The program responds to mode changes. Hence, one can resize the Julia window.
+ */
+
+/*
+ * Copyright (C) 2018 Daniel Collins
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include // STL
+
+struct Painter_T {
+ virtual ~Painter_T() = default;
+ virtual void paint(Genode::Pixel_rgb565*, unsigned w, unsigned h) = 0;
+};
+
+class window {
+ using View_handle = Nitpicker::Session::View_handle;
+ using Reattachable_dataspace = Genode::Constructible;
+
+ Genode::Env& _env;
+ Nitpicker::Connection _npconn;
+ Framebuffer::Mode _mode;
+ Painter_T& _draw;
+ Reattachable_dataspace _ds{};
+ View_handle _view{};
+
+ void _draw_frame() {
+ _draw.paint(_ds->local_addr(), _mode.width(), _mode.height()); }
+
+ void _refresh() {
+ _npconn.framebuffer()->refresh(0, 0, _mode.width(), _mode.height()); }
+
+ void _new_mode() {
+ _mode = _npconn.mode();
+ _npconn.buffer(_mode, false);
+ _ds.construct(_env.rm(), _npconn.framebuffer()->dataspace());
+ _draw_frame();
+ _refresh();
+
+ auto rect = Nitpicker::Rect{Nitpicker::Point{0, 0},
+ Nitpicker::Area{(unsigned)_mode.width(),
+ (unsigned)_mode.height()}};
+ _npconn.enqueue(_view, rect);
+ _npconn.execute();
+ }
+
+ Genode::Signal_handler _on_resize{_env.ep(), *this, &window::_new_mode};
+
+public:
+ using Title_String_T = Genode::String<64>;
+ ~window() = default;
+ window() = delete;
+ window(Genode::Env& env, Painter_T& painter,
+ Title_String_T title, Nitpicker::Area wsize)
+ : _env{env}, _npconn{env},
+ _mode{(int)wsize.w(), (int)wsize.h(), Framebuffer::Mode::RGB565},
+ _draw{painter}, _ds{env.rm(), _npconn.framebuffer()->dataspace()}
+ {
+ using Nitpicker::Session;
+
+ _npconn.buffer(_mode, false);
+ _view = _npconn.create_view();
+
+ _new_mode(); /* Get the newest mode+buffer and start drawing */
+
+ _npconn.enqueue(_view, title);
+ _npconn.enqueue(_view, View_handle{});
+ _npconn.execute();
+ _npconn.mode_sigh(_on_resize);
+ }
+
+ void draw_next_frame() {
+ _draw_frame();
+ _refresh();
+ }
+
+};
+
+class julia : public Painter_T {
+ using flt_t = double;
+ using cmplx = std::complex;
+public:
+
+ /** Changed using direct assignment **/
+ flt_t C;
+ unsigned N;
+
+ virtual ~julia() = default;
+ julia(flt_t c, unsigned n) : C{c}, N{n} {}
+
+ /**
+ * Draw a calculated set in the buffer.
+ */
+ virtual void paint(Genode::Pixel_rgb565* buf, unsigned w, unsigned h)
+ {
+ --w, --h;
+ const auto _w = w;
+ const auto _h = h;
+ Genode::size_t idx{0};
+ do do {
+ /// Scale pixels
+ cmplx Z {w*3.5/_w - 1.75, h*2.0/_h - 1};
+ unsigned i {0};
+ for (; i < N && (Z.real()*Z.real() + Z.imag()*Z.imag()) < 4.0; ++i)
+ Z = Z*Z + C;
+
+ unsigned c = ((i)*255) / N;
+ if (i < N) {
+ double quotient = ((double) i) / N;
+ if (quotient > 0.5)
+ buf[idx++].rgba(255, c, c);
+ else
+ buf[idx++].rgba(c, 0, 0);
+ } else buf[idx++].rgba(0, 0, 0);
+
+ } while (w-- > 0); while (w = _w, h-- > 0);
+ }
+};
+
+/**
+ * Calls a functor on an interval
+ */
+template
+class Timer_callback {
+ Genode::Env& _env;
+ Timer::Connection _timer{_env};
+
+ Fn_T _callback;
+ void _call() { _callback(); }
+
+ Genode::Signal_handler> _time_sigh {
+ _env.ep(), *this, &Timer_callback::_call };
+
+public:
+ Timer_callback(Genode::Env& env, unsigned interval, Fn_T func)
+ : _env{env}, _callback{func} {
+ _timer.sigh(_time_sigh);
+ _timer.trigger_periodic(interval);
+ }
+};
+
+
+void Libc::Component::construct(Libc::Env& env) {
+ static julia painter{-.75, 20};
+ static window win{env, painter, "julia", Nitpicker::Area{256, 256}};
+
+ auto update_win = [&] {
+ painter.C -= 0.003;
+ win.draw_next_frame();
+ };
+
+ /* Update the window's contents on a static interval. */
+ static Timer_callback
+ window_update_timer{env, 15000, update_win};
+ Genode::log("constructed");
+}
diff --git a/src/app/julia_fractal/target.mk b/src/app/julia_fractal/target.mk
new file mode 100644
index 0000000..29a29a6
--- /dev/null
+++ b/src/app/julia_fractal/target.mk
@@ -0,0 +1,4 @@
+TARGET = julia_fractal
+SRC_CC = main.cc
+LIBS += base
+LIBS += stdcxx # evil!