]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/android/display.cpp
f0afc726c2afe4fd5173d3fd82e5ca395115272e
[libs/gui.git] / source / graphics / android / display.cpp
1 #include <msp/core/application.h>
2 #include <msp/core/mainthread.h>
3 #include "display.h"
4 #include "display_private.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace Graphics {
10
11 Display::Display(const string &)
12 {
13         Android::MainThread *thread = reinterpret_cast<Android::MainThread *>(Application::get_data());
14         if(!thread->is_starting_up())
15                 throw logic_error("Display must be created during startup");
16
17         priv = new Private;
18         priv->input_queue = 0;
19         priv->native_window = 0;
20
21         thread->signal_native_window_created.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_created));
22         thread->signal_native_window_resized.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_resized));
23         thread->signal_native_window_destroyed.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::native_window_destroyed));
24         thread->signal_input_queue_created.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::input_queue_created));
25         thread->signal_input_queue_destroyed.connect(sigc::mem_fun(priv, &PlatformDisplayPrivate::input_queue_destroyed));
26         thread->resume_startup();
27 }
28
29 Display::~Display()
30 {
31         delete priv;
32 }
33
34 void Display::set_mode(const VideoMode &, bool)
35 {
36         throw runtime_error("video mode switching not supported");
37 }
38
39 bool Display::process_events()
40 {
41         MutexLock lock(priv->event_mutex);
42         if(!priv->input_queue)
43                 return false;
44
45         Window::Event event;
46         if(!priv->events.empty())
47         {
48                 event = priv->events.front();
49                 priv->events.pop_front();
50         }
51         else if(AInputQueue_getEvent(priv->input_queue, &event.aevent)>=0)
52         {
53                 if(AInputQueue_preDispatchEvent(priv->input_queue, event.aevent))
54                         return true;
55
56                 event.type = INPUT_EVENT;
57         }
58         else
59                 return false;
60
61         bool handled = false;
62         if(!priv->windows.empty())
63                 handled = priv->windows.begin()->second->event(event);
64
65         if(event.type==INPUT_EVENT)
66                 AInputQueue_finishEvent(priv->input_queue, event.aevent, handled);
67         else if(event.type==WINDOW_CREATED)
68                 priv->window_mutex.lock();
69         else if(event.type==WINDOW_DESTROYED)
70                 priv->window_mutex.unlock();
71
72         return true;
73 }
74
75 void Display::check_error()
76 {
77 }
78
79
80 void PlatformDisplayPrivate::push_event(Msp::Graphics::AndroidEventType type)
81 {
82         MutexLock lock(event_mutex);
83         Window::Event event;
84         event.type = type;
85         events.push_back(event);
86 }
87
88 void PlatformDisplayPrivate::native_window_created(ANativeWindow *window)
89 {
90         native_window = window;
91         push_event(WINDOW_CREATED);
92 }
93
94 void PlatformDisplayPrivate::native_window_resized(ANativeWindow *)
95 {
96         push_event(WINDOW_RESIZED);
97 }
98
99 void PlatformDisplayPrivate::native_window_destroyed(ANativeWindow *)
100 {
101         push_event(WINDOW_DESTROYED);
102         MutexLock lock(window_mutex);
103         native_window = 0;
104 }
105
106 void PlatformDisplayPrivate::input_queue_created(AInputQueue *queue)
107 {
108         MutexLock lock(event_mutex);
109         input_queue = queue;
110 }
111
112 void PlatformDisplayPrivate::input_queue_destroyed(AInputQueue *)
113 {
114         MutexLock lock(event_mutex);
115         input_queue = 0;
116 }
117 } // namespace Graphics
118 } // namespace Msp