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