Haiku: use a BLooper for events.

only create a BApplication when it doesn't already exist.
This commit is contained in:
Jerome Duval 2023-03-29 21:28:21 +02:00 committed by Sam Lantinga
parent 55f74c3285
commit eb0d214c17
10 changed files with 112 additions and 81 deletions

View file

@ -49,6 +49,7 @@ extern "C" {
#include <vector> #include <vector>
/* Forward declarations */ /* Forward declarations */
class SDL_BLooper;
class SDL_BWin; class SDL_BWin;
/* Message constants */ /* Message constants */
@ -74,32 +75,25 @@ enum ToSDL
BAPP_SCREEN_CHANGED BAPP_SCREEN_CHANGED
}; };
/* Create a descendant of BApplication */
class SDL_BApp : public BApplication extern "C" SDL_BLooper *SDL_Looper;
/* Create a descendant of BLooper */
class SDL_BLooper : public BLooper
{ {
public: public:
SDL_BApp(const char *signature) : BApplication(signature) SDL_BLooper(const char* name) : BLooper(name)
{ {
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL
_current_context = NULL; _current_context = NULL;
#endif #endif
} }
virtual ~SDL_BApp() virtual ~SDL_BLooper()
{ {
} }
virtual void RefsReceived(BMessage *message)
{
char filePath[512];
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;
}
/* Event-handling functions */ /* Event-handling functions */
virtual void MessageReceived(BMessage *message) virtual void MessageReceived(BMessage *message)
{ {
@ -170,7 +164,7 @@ class SDL_BApp : public BApplication
break; break;
default: default:
BApplication::MessageReceived(message); BLooper::MessageReceived(message);
break; break;
} }
} }

View file

@ -31,7 +31,7 @@
#include <storage/File.h> #include <storage/File.h>
#include <unistd.h> #include <unistd.h>
#include "SDL_BApp.h" /* SDL_BApp class definition */ #include "SDL_BApp.h" /* SDL_BLooper class definition */
#include "SDL_BeApp.h" #include "SDL_BeApp.h"
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_error.h" #include "SDL_error.h"
@ -44,12 +44,38 @@ extern "C" {
#include "../../thread/SDL_systhread.h" #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 int SDL_BeAppActive = 0;
static SDL_Thread *SDL_AppThread = NULL; static SDL_Thread *SDL_AppThread = NULL;
SDL_BLooper *SDL_Looper = NULL;
/* Default application signature */ /* 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) static int StartBeApp(void *unused)
{ {
@ -65,48 +91,62 @@ static int StartBeApp(void *unused)
if (app_info.InitCheck() == B_OK) { if (app_info.InitCheck() == B_OK) {
char sig[B_MIME_TYPE_LENGTH]; char sig[B_MIME_TYPE_LENGTH];
if (app_info.GetSignature(sig) == B_OK) { if (app_info.GetSignature(sig) == B_OK) {
signature = strndup(sig, B_MIME_TYPE_LENGTH); SDL_signature = strndup(sig, B_MIME_TYPE_LENGTH);
} }
} }
} }
} }
App = new SDL_BApp(signature); App = new SDL_BApp(SDL_signature);
App->Run(); App->Run();
delete App; delete App;
return 0; 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 */ /* Initialize the Be Application, if it's not already started */
int int
SDL_InitBeApp(void) SDL_InitBeApp(void)
{ {
/* Create the BApplication that handles appserver interaction */ /* Create the BApplication that handles appserver interaction */
if (SDL_BeAppActive <= 0) { if (SDL_BeAppActive <= 0) {
SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL); StartBeLooper();
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());
/* Mark the application active */ /* Mark the application active */
SDL_BeAppActive = 0; SDL_BeAppActive = 0;
@ -128,6 +168,9 @@ SDL_QuitBeApp(void)
/* If the reference count reached zero, clean up the app */ /* If the reference count reached zero, clean up the app */
if (SDL_BeAppActive == 0) { if (SDL_BeAppActive == 0) {
SDL_Looper->Lock();
SDL_Looper->Quit();
SDL_Looper = NULL;
if (SDL_AppThread != NULL) { if (SDL_AppThread != NULL) {
if (be_app != NULL) { /* Not tested */ if (be_app != NULL) { /* Not tested */
be_app->PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(B_QUIT_REQUESTED);
@ -144,7 +187,7 @@ SDL_QuitBeApp(void)
#endif #endif
/* SDL_BApp functions */ /* SDL_BApp functions */
void SDL_BApp::ClearID(SDL_BWin *bwin) { void SDL_BLooper::ClearID(SDL_BWin *bwin) {
_SetSDLWindow(NULL, bwin->GetID()); _SetSDLWindow(NULL, bwin->GetID());
int32 i = _GetNumWindowSlots() - 1; int32 i = _GetNumWindowSlots() - 1;
while (i >= 0 && GetSDLWindow(i) == NULL) { while (i >= 0 && GetSDLWindow(i) == NULL) {

View file

@ -32,7 +32,7 @@ extern int SDL_InitBeApp(void);
extern void SDL_QuitBeApp(void); extern void SDL_QuitBeApp(void);
/* Be Application Signature*/ /* Be Application Signature*/
extern const char *signature; extern const char *SDL_signature;
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View file

@ -49,6 +49,7 @@ extern "C" {
#include <vector> #include <vector>
/* Forward declarations */ /* Forward declarations */
class SDL_BLooper;
class SDL_BWin; class SDL_BWin;
/* Message constants */ /* Message constants */
@ -74,32 +75,25 @@ enum ToSDL
BAPP_SCREEN_CHANGED BAPP_SCREEN_CHANGED
}; };
/* Create a descendant of BApplication */
class SDL_BApp : public BApplication extern "C" SDL_BLooper *SDL_Looper;
/* Create a descendant of BLooper */
class SDL_BLooper : public BLooper
{ {
public: public:
SDL_BApp(const char *signature) : BApplication(signature) SDL_BLooper(const char* name) : BLooper(name)
{ {
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL
_current_context = NULL; _current_context = NULL;
#endif #endif
} }
virtual ~SDL_BApp() virtual ~SDL_BLooper()
{ {
} }
virtual void RefsReceived(BMessage *message)
{
char filePath[512];
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;
}
/* Event-handling functions */ /* Event-handling functions */
virtual void MessageReceived(BMessage *message) virtual void MessageReceived(BMessage *message)
{ {
@ -170,7 +164,7 @@ class SDL_BApp : public BApplication
break; break;
default: default:
BApplication::MessageReceived(message); BLooper::MessageReceived(message);
break; break;
} }
} }

View file

@ -125,8 +125,8 @@ class SDL_BWin : public BWindow
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL
if (_SDL_GLView) { if (_SDL_GLView) {
if (((SDL_BApp *)be_app)->GetCurrentContext() == _SDL_GLView) if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
((SDL_BApp *)be_app)->SetCurrentContext(NULL); SDL_Looper->SetCurrentContext(NULL);
if (_SDL_GLView == _cur_view) if (_SDL_GLView == _cur_view)
RemoveChild(_SDL_GLView); RemoveChild(_SDL_GLView);
_SDL_GLView = NULL; _SDL_GLView = NULL;
@ -209,8 +209,8 @@ class SDL_BWin : public BWindow
{ {
Lock(); Lock();
if (_SDL_GLView != NULL) { if (_SDL_GLView != NULL) {
if (((SDL_BApp *)be_app)->GetCurrentContext() == _SDL_GLView) if (SDL_Looper->GetCurrentContext() == _SDL_GLView)
((SDL_BApp *)be_app)->SetCurrentContext(NULL); SDL_Looper->SetCurrentContext(NULL);
_SDL_GLView = NULL; _SDL_GLView = NULL;
UpdateCurrentView(); UpdateCurrentView();
// _SDL_GLView deleted by HAIKU_GL_DeleteContext // _SDL_GLView deleted by HAIKU_GL_DeleteContext
@ -572,7 +572,7 @@ class SDL_BWin : public BWindow
if (keyUtf8 != NULL) { if (keyUtf8 != NULL) {
msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len); msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len);
} }
be_app->PostMessage(&msg); SDL_Looper->PostMessage(&msg);
} }
void _RepaintEvent() void _RepaintEvent()
@ -584,7 +584,7 @@ class SDL_BWin : public BWindow
void _PostWindowEvent(BMessage &msg) void _PostWindowEvent(BMessage &msg)
{ {
msg.AddInt32("window-id", _id); msg.AddInt32("window-id", _id);
be_app->PostMessage(&msg); SDL_Looper->PostMessage(&msg);
} }
/* Command methods (functions called upon by SDL) */ /* Command methods (functions called upon by SDL) */

View file

@ -39,8 +39,8 @@ static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata); return (SDL_BWin *)(window->driverdata);
} }
static SDL_INLINE SDL_BApp *_GetBeApp() { static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return (SDL_BApp *)be_app; return SDL_Looper;
} }
int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window,

View file

@ -358,7 +358,7 @@ HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
// "2 BApplication objects were created. Only one is allowed." // "2 BApplication objects were created. Only one is allowed."
BApplication *application = NULL; BApplication *application = NULL;
if (be_app == NULL) { if (be_app == NULL) {
application = new(std::nothrow) BApplication(signature); application = new(std::nothrow) BApplication(SDL_signature);
if (application == NULL) { if (application == NULL) {
return SDL_SetError("Cannot create the BApplication object. Lack of memory?"); return SDL_SetError("Cannot create the BApplication object. Lack of memory?");
} }

View file

@ -52,8 +52,8 @@ static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata); return (SDL_BWin *)(window->driverdata);
} }
static SDL_INLINE SDL_BApp *_GetBeApp() { static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return (SDL_BApp *)be_app; return SDL_Looper;
} }
static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) { static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) {

View file

@ -39,8 +39,8 @@ static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata); return (SDL_BWin *)(window->driverdata);
} }
static SDL_INLINE SDL_BApp *_GetBeApp() { static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return (SDL_BApp *)be_app; return SDL_Looper;
} }
/* Passing a NULL path means load pointers from the application */ /* Passing a NULL path means load pointers from the application */
@ -97,7 +97,7 @@ int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) {
return SDL_SetError("MakeCurrent failed"); return SDL_SetError("MakeCurrent failed");
} }
} }
_GetBeApp()->SetCurrentContext(glView); _GetBeLooper()->SetCurrentContext(glView);
return 0; return 0;
} }
@ -138,7 +138,7 @@ SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) {
} }
#endif #endif
bwin->CreateGLView(gl_flags); bwin->CreateGLView(gl_flags);
_GetBeApp()->SetCurrentContext(bwin->GetGLView()); _GetBeLooper()->SetCurrentContext(bwin->GetGLView());
return (SDL_GLContext)(bwin->GetGLView()); return (SDL_GLContext)(bwin->GetGLView());
} }

View file

@ -37,8 +37,8 @@ static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) {
return (SDL_BWin *)(window->driverdata); return (SDL_BWin *)(window->driverdata);
} }
static SDL_INLINE SDL_BApp *_GetBeApp() { static SDL_INLINE SDL_BLooper *_GetBeLooper() {
return (SDL_BApp *)be_app; return SDL_Looper;
} }
static int _InitWindow(_THIS, SDL_Window *window) { static int _InitWindow(_THIS, SDL_Window *window) {
@ -72,7 +72,7 @@ static int _InitWindow(_THIS, SDL_Window *window) {
} }
window->driverdata = bwin; window->driverdata = bwin;
int32 winID = _GetBeApp()->GetID(window); int32 winID = _GetBeLooper()->GetID(window);
bwin->SetID(winID); bwin->SetID(winID);
return 0; return 0;
@ -220,7 +220,7 @@ void HAIKU_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) {
void HAIKU_DestroyWindow(_THIS, SDL_Window * window) { void HAIKU_DestroyWindow(_THIS, SDL_Window * window) {
_ToBeWin(window)->LockLooper(); /* This MUST be locked */ _ToBeWin(window)->LockLooper(); /* This MUST be locked */
_GetBeApp()->ClearID(_ToBeWin(window)); _GetBeLooper()->ClearID(_ToBeWin(window));
_ToBeWin(window)->Quit(); _ToBeWin(window)->Quit();
window->driverdata = NULL; window->driverdata = NULL;
} }