]> git.tdb.fi Git - libs/core.git/blob - source/core/android/mainthread.cpp
Chdir into a sensible location before starting the application
[libs/core.git] / source / core / android / mainthread.cpp
1 #include <cstring>
2 #include <msp/fs/dir.h>
3 #include <msp/fs/path.h>
4 #include <msp/fs/utils.h>
5 #include "application.h"
6 #include "errorlogger.h"
7 #include "mainthread.h"
8
9 using namespace std;
10
11 namespace Msp {
12 namespace Android {
13
14 MainThread::MainThread(ANativeActivity *a):
15         asset_manager(a->assetManager),
16         int_data_path(a->internalDataPath),
17         starting_up(true)
18 {
19         attach_to_activity(a);
20         startup_mutex.lock();
21         launch();
22 }
23
24 void MainThread::attach_to_activity(ANativeActivity *a)
25 {
26         activity = a;
27         activity->callbacks->onDestroy = &activity_destroyed;
28         activity->callbacks->onNativeWindowCreated = &native_window_created;
29         activity->callbacks->onNativeWindowResized = &native_window_resized;
30         activity->callbacks->onNativeWindowDestroyed = &native_window_destroyed;
31         activity->callbacks->onInputQueueCreated = &input_queue_created;
32         activity->callbacks->onInputQueueDestroyed = &input_queue_destroyed;
33         activity->instance = this;
34 }
35
36 void MainThread::wait_for_app_created()
37 {
38         MutexLock lock(startup_mutex);
39 }
40
41 void MainThread::resume_startup()
42 {
43         if(starting_up)
44         {
45                 starting_up = false;
46                 startup_mutex.unlock();
47         }
48 }
49
50 void MainThread::main()
51 {
52         /* I have no idea how dependable this is, but it seems to be the only way
53         to get the package name aside from making a Java call through JNI */
54         char *appname = strdup(int_data_path[-2].c_str());
55         char *argv[] = { appname, 0 };
56         Msp::Android::ErrorLogger err_logger;
57         FS::chdir(FS::dirname(int_data_path));
58         Msp::Application::run(1, argv, this, &app_created);
59         free(appname);
60         if(activity)
61                 ANativeActivity_finish(activity);
62 }
63
64 void MainThread::app_created(void *data)
65 {
66         reinterpret_cast<MainThread *>(data)->resume_startup();
67 }
68
69 void MainThread::activity_destroyed(ANativeActivity *activity)
70 {
71         reinterpret_cast<MainThread *>(activity->instance)->activity = 0;
72 }
73
74 void MainThread::native_window_created(ANativeActivity *activity, ANativeWindow *window)
75 {
76         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_created.emit(window);
77 }
78
79 void MainThread::native_window_resized(ANativeActivity *activity, ANativeWindow *window)
80 {
81         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_resized.emit(window);
82 }
83
84 void MainThread::native_window_destroyed(ANativeActivity *activity, ANativeWindow *window)
85 {
86         reinterpret_cast<MainThread *>(activity->instance)->signal_native_window_destroyed.emit(window);
87 }
88
89 void MainThread::input_queue_created(ANativeActivity *activity, AInputQueue *queue)
90 {
91         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_created.emit(queue);
92 }
93
94 void MainThread::input_queue_destroyed(ANativeActivity *activity, AInputQueue *queue)
95 {
96         reinterpret_cast<MainThread *>(activity->instance)->signal_input_queue_destroyed.emit(queue);
97 }
98
99 } // namespace Android
100 } // namespace Msp