--- /dev/null
+#include <msp/core/application.h>
+#include <msp/core/mainthread.h>
+#include "display.h"
+#include "display_private.h"
+
+using namespace std;
+
+namespace Msp {
+namespace Graphics {
+
+Display::Display(const string &)
+{
+ Android::MainThread *thread = reinterpret_cast<Android::MainThread *>(Application::get_data());
+ if(!thread->is_starting_up())
+ throw logic_error("Display must be created during startup");
+
+ priv = new Private;
+ priv->input_queue = 0;
+ priv->native_window = 0;
+
+ thread->signal_native_window_created.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_created));
+ thread->signal_native_window_resized.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_resized));
+ thread->signal_native_window_destroyed.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_destroyed));
+ thread->signal_input_queue_created.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::input_queue_created));
+ thread->signal_input_queue_destroyed.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::input_queue_destroyed));
+ thread->resume_startup();
+}
+
+Display::~Display()
+{
+ delete priv;
+}
+
+void Display::set_mode(const VideoMode &, bool)
+{
+ throw runtime_error("video mode switching not supported");
+}
+
+bool Display::process_events()
+{
+ MutexLock lock(priv->event_mutex);
+ if(!priv->input_queue)
+ return false;
+
+ Window::Event event;
+ if(!priv->events.empty())
+ {
+ event = priv->events.front();
+ priv->events.pop_front();
+ }
+ else if(AInputQueue_getEvent(priv->input_queue, &event.aevent)>=0)
+ {
+ if(AInputQueue_preDispatchEvent(priv->input_queue, event.aevent))
+ return true;
+
+ event.type = INPUT_EVENT;
+ }
+ else
+ return false;
+
+ bool handled = false;
+ if(!priv->windows.empty())
+ handled = priv->windows.begin()->second->event(event);
+
+ if(event.type==INPUT_EVENT)
+ AInputQueue_finishEvent(priv->input_queue, event.aevent, handled);
+ else if(event.type==WINDOW_CREATED)
+ priv->window_mutex.lock();
+ else if(event.type==WINDOW_DESTROYED)
+ priv->window_mutex.unlock();
+
+ return true;
+}
+
+void Display::check_error()
+{
+}
+
+
+void PlatformDisplayPrivate::push_event(Msp::Graphics::AndroidEventType type)
+{
+ MutexLock lock(event_mutex);
+ Window::Event event;
+ event.type = type;
+ events.push_back(event);
+}
+
+void PlatformDisplayPrivate::native_window_created(ANativeWindow *window)
+{
+ native_window = window;
+ push_event(WINDOW_CREATED);
+}
+
+void PlatformDisplayPrivate::native_window_resized(ANativeWindow *)
+{
+ push_event(WINDOW_RESIZED);
+}
+
+void PlatformDisplayPrivate::native_window_destroyed(ANativeWindow *)
+{
+ push_event(WINDOW_DESTROYED);
+ MutexLock lock(window_mutex);
+ native_window = 0;
+}
+
+void PlatformDisplayPrivate::input_queue_created(AInputQueue *queue)
+{
+ MutexLock lock(event_mutex);
+ input_queue = queue;
+}
+
+void PlatformDisplayPrivate::input_queue_destroyed(AInputQueue *)
+{
+ MutexLock lock(event_mutex);
+ input_queue = 0;
+}
+} // namespace Graphics
+} // namespace Msp