#include "SDL_internal.h"
#ifdef SDL_PLATFORM_HAIKU
#include <AppKit.h>
#include <storage/AppFileInfo.h>
#include <storage/Path.h>
#include <storage/Entry.h>
#include <storage/File.h>
#include <unistd.h>
#include <memory>
#include "SDL_BApp.h"
#include "SDL_BeApp.h"
#include "../../video/haiku/SDL_BWin.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "../../thread/SDL_systhread.h"
static int SDL_BeAppActive = 0;
static SDL_Thread *SDL_AppThread = NULL;
SDL_BLooper *SDL_Looper = NULL;
const char *SDL_signature = "application/x-SDL-executable";
class SDL_BApp : public BApplication {
public:
SDL_BApp(const char *signature) :
BApplication(signature) {
}
virtual ~SDL_BApp() {
}
virtual void RefsReceived(BMessage *message) {
entry_ref entryRef;
for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) {
BPath referencePath = BPath(&entryRef);
SDL_SendDropFile(NULL, NULL, referencePath.Path());
}
return;
}
};
static int StartBeApp(void *unused)
{
std::unique_ptr<BApplication> App;
(void)unused;
image_info info;
int32 cookie = 0;
if (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) {
BFile f(info.name, O_RDONLY);
if (f.InitCheck() == B_OK) {
BAppFileInfo app_info(&f);
if (app_info.InitCheck() == B_OK) {
char sig[B_MIME_TYPE_LENGTH];
if (app_info.GetSignature(sig) == B_OK) {
SDL_signature = strndup(sig, B_MIME_TYPE_LENGTH);
}
}
}
}
App = std::unique_ptr<BApplication>(new SDL_BApp(SDL_signature));
App->Run();
return 0;
}
static bool StartBeLooper()
{
if (!be_app) {
SDL_AppThread = SDL_CreateThread(StartBeApp, "SDLApplication", NULL);
if (!SDL_AppThread) {
return SDL_SetError("Couldn't create BApplication thread");
}
do {
SDL_Delay(10);
} while ((!be_app) || be_app->IsLaunching());
}
SDL_Looper = new SDL_BLooper("SDLLooper");
SDL_Looper->Run();
return true;
}
bool SDL_InitBeApp(void)
{
if (SDL_BeAppActive <= 0) {
if (!StartBeLooper()) {
return false;
}
SDL_BeAppActive = 0;
}
++SDL_BeAppActive;
return true;
}
void SDL_QuitBeApp(void)
{
--SDL_BeAppActive;
if (SDL_BeAppActive == 0) {
SDL_Looper->Lock();
SDL_Looper->Quit();
SDL_Looper = NULL;
if (SDL_AppThread) {
if (be_app != NULL) { be_app->PostMessage(B_QUIT_REQUESTED);
}
SDL_WaitThread(SDL_AppThread, NULL);
SDL_AppThread = NULL;
}
}
}
#ifdef __cplusplus
}
#endif
void SDL_BLooper::ClearID(SDL_BWin *bwin) {
_SetSDLWindow(NULL, bwin->GetID());
int32 i = _GetNumWindowSlots() - 1;
while (i >= 0 && GetSDLWindow(i) == NULL) {
_PopBackWindow();
--i;
}
}
#endif