Haiku: use a BLooper for events, only create a BApplication when it doesn't already exist. (#7555)

This commit is contained in:
Jérôme Duval
2023-03-30 16:12:10 +02:00
committed by GitHub
parent cae6b4489d
commit 2d64f419c5
10 changed files with 113 additions and 81 deletions

View File

@@ -32,7 +32,7 @@
#include <unistd.h>
#include <memory>
#include "SDL_BApp.h" /* SDL_BApp class definition */
#include "SDL_BApp.h" /* SDL_BLooper class definition */
#include "SDL_BeApp.h"
#include "../../video/haiku/SDL_BWin.h"
@@ -43,12 +43,38 @@ extern "C" {
#include "../../thread/SDL_systhread.h"
/* Flag to tell whether or not the Be application is active or not */
/* Flag to tell whether or not the Be application and looper are active or not */
static int SDL_BeAppActive = 0;
static SDL_Thread *SDL_AppThread = NULL;
SDL_BLooper *SDL_Looper = NULL;
/* Default application signature */
const char *signature = "application/x-SDL-executable";
const char *SDL_signature = "application/x-SDL-executable";
/* Create a descendant of BApplication */
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, referencePath.Path());
}
return;
}
};
static int StartBeApp(void *unused)
{
@@ -65,47 +91,61 @@ static int StartBeApp(void *unused)
if (app_info.InitCheck() == B_OK) {
char sig[B_MIME_TYPE_LENGTH];
if (app_info.GetSignature(sig) == B_OK) {
signature = strndup(sig, B_MIME_TYPE_LENGTH);
SDL_signature = strndup(sig, B_MIME_TYPE_LENGTH);
}
}
}
}
App = std::unique_ptr<BApplication>(new SDL_BApp(signature));
App = std::unique_ptr<BApplication>(new SDL_BApp(SDL_signature));
App->Run();
return 0;
}
static int
StartBeLooper()
{
if (!be_app) {
SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL);
if (SDL_AppThread == NULL) {
return SDL_SetError("Couldn't create BApplication thread");
}
do {
SDL_Delay(10);
} while ((be_app == NULL) || be_app->IsLaunching());
}
/* Change working directory to that of executable */
app_info info;
if (B_OK == be_app->GetAppInfo(&info)) {
entry_ref ref = info.ref;
BEntry entry;
if (B_OK == entry.SetTo(&ref)) {
BPath path;
if (B_OK == path.SetTo(&entry)) {
if (B_OK == path.GetParent(&path)) {
chdir(path.Path());
}
}
}
}
SDL_Looper = new SDL_BLooper("SDLLooper");
SDL_Looper->Run();
return (0);
}
/* Initialize the Be Application, if it's not already started */
int
SDL_InitBeApp(void)
{
/* Create the BApplication that handles appserver interaction */
if (SDL_BeAppActive <= 0) {
SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL);
if (SDL_AppThread == NULL) {
return SDL_SetError("Couldn't create BApplication thread");
}
/* Change working directory to that of executable */
app_info info;
if (B_OK == be_app->GetAppInfo(&info)) {
entry_ref ref = info.ref;
BEntry entry;
if (B_OK == entry.SetTo(&ref)) {
BPath path;
if (B_OK == path.SetTo(&entry)) {
if (B_OK == path.GetParent(&path)) {
chdir(path.Path());
}
}
}
}
do {
SDL_Delay(10);
} while ((be_app == NULL) || be_app->IsLaunching());
StartBeLooper();
/* Mark the application active */
SDL_BeAppActive = 0;
@@ -127,6 +167,9 @@ SDL_QuitBeApp(void)
/* If the reference count reached zero, clean up the app */
if (SDL_BeAppActive == 0) {
SDL_Looper->Lock();
SDL_Looper->Quit();
SDL_Looper = NULL;
if (SDL_AppThread != NULL) {
if (be_app != NULL) { /* Not tested */
be_app->PostMessage(B_QUIT_REQUESTED);
@@ -143,7 +186,7 @@ SDL_QuitBeApp(void)
#endif
/* SDL_BApp functions */
void SDL_BApp::ClearID(SDL_BWin *bwin) {
void SDL_BLooper::ClearID(SDL_BWin *bwin) {
_SetSDLWindow(NULL, bwin->GetID());
int32 i = _GetNumWindowSlots() - 1;
while (i >= 0 && GetSDLWindow(i) == NULL) {