]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/android/display.cpp
Android support
[libs/gui.git] / source / graphics / android / display.cpp
diff --git a/source/graphics/android/display.cpp b/source/graphics/android/display.cpp
new file mode 100644 (file)
index 0000000..f0afc72
--- /dev/null
@@ -0,0 +1,118 @@
+#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