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