From 423feac69b7db9b8eaca486c766a75bccea8353a Mon Sep 17 00:00:00 2001
From: waddlesplash <[EMAIL REDACTED]>
Date: Sat, 5 Feb 2022 21:23:40 -0500
Subject: [PATCH] haiku: Actually remove BDirectWindow and fix OpenGL handling.
This provides the other half of 05c72b113c830392f8b08532317ef07972b29a2e.
---
src/video/haiku/SDL_BWin.h | 416 +++++++++++++++++++++----------------
1 file changed, 234 insertions(+), 182 deletions(-)
diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h
index dc6e442a86d..1ac517164e2 100644
--- a/src/video/haiku/SDL_BWin.h
+++ b/src/video/haiku/SDL_BWin.h
@@ -39,7 +39,6 @@ extern "C" {
#include <AppKit.h>
#include <Cursor.h>
#include <InterfaceKit.h>
-#include <game/DirectWindow.h>
#if SDL_VIDEO_OPENGL
#include <opengl/GLView.h>
#endif
@@ -58,19 +57,48 @@ enum WinCommands {
BWIN_SET_TITLE,
BWIN_SET_BORDERED,
BWIN_SET_RESIZABLE,
- BWIN_FULLSCREEN
+ BWIN_FULLSCREEN,
+ BWIN_UPDATE_FRAMEBUFFER,
+ BWIN_MINIMUM_SIZE_WINDOW
};
+// non-OpenGL framebuffer view
+class SDL_BView: public BView
+{
+public:
+ SDL_BView(BRect frame, const char* name, uint32 resizingMode)
+ : BView(frame, name, resizingMode, B_WILL_DRAW),
+ fBitmap(NULL)
+ {
+ }
+
+ void Draw(BRect dirty)
+ {
+ if (fBitmap != NULL)
+ DrawBitmap(fBitmap, B_ORIGIN);
+ }
+
+ void SetBitmap(BBitmap *bitmap)
+ {
+ fBitmap = bitmap;
+ }
+
+private:
+ BBitmap *fBitmap;
+};
-class SDL_BWin:public BDirectWindow
+class SDL_BWin: public BWindow
{
public:
/* Constructor/Destructor */
SDL_BWin(BRect bounds, window_look look, uint32 flags)
- : BDirectWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
+ : BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags)
{
_last_buttons = 0;
+ _cur_view = NULL;
+ _SDL_View = NULL;
+
#if SDL_VIDEO_OPENGL
_SDL_GLView = NULL;
_gl_type = 0;
@@ -79,59 +107,88 @@ class SDL_BWin:public BDirectWindow
_inhibit_resize = false;
_mouse_focused = false;
_prev_frame = NULL;
+ _fullscreen = NULL;
/* Handle framebuffer stuff */
- _connected = _connection_disabled = false;
- _buffer_created = _buffer_dirty = false;
- _trash_window_buffer = false;
_buffer_locker = new BLocker();
_bitmap = NULL;
- _clips = NULL;
- _num_clips = 0;
-
-#ifdef DRAWTHREAD
- _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread",
- B_NORMAL_PRIORITY, (void*) this);
- resume_thread(_draw_thread_id);
-#endif
}
virtual ~ SDL_BWin()
{
Lock();
- _connection_disabled = true;
- int32 result;
+
+ if (_SDL_View != NULL && _SDL_View != _cur_view) {
+ delete _SDL_View;
+ _SDL_View = NULL;
+ }
#if SDL_VIDEO_OPENGL
if (_SDL_GLView) {
- _SDL_GLView->UnlockGL();
- RemoveChild(_SDL_GLView); /* Why was this outside the if
- statement before? */
+ if (((SDL_BApp*)be_app)->GetCurrentContext() == _SDL_GLView)
+ ((SDL_BApp*)be_app)->SetCurrentContext(NULL);
+ if (_SDL_GLView == _cur_view)
+ RemoveChild(_SDL_GLView);
+ _SDL_GLView = NULL;
+ // _SDL_GLView deleted by HAIKU_GL_DeleteContext
}
#endif
Unlock();
-#if SDL_VIDEO_OPENGL
- if (_SDL_GLView) {
- delete _SDL_GLView;
- }
-#endif
delete _prev_frame;
/* Clean up framebuffer stuff */
_buffer_locker->Lock();
-#ifdef DRAWTHREAD
- wait_for_thread(_draw_thread_id, &result);
-#endif
- SDL_free(_clips);
delete _buffer_locker;
}
+
+ void SetCurrentView(BView *view)
+ {
+ if (_cur_view != view) {
+ if (_cur_view != NULL)
+ RemoveChild(_cur_view);
+ _cur_view = view;
+ if (_cur_view != NULL)
+ AddChild(_cur_view);
+ }
+ }
+
+ void UpdateCurrentView()
+ {
+ if (_SDL_GLView != NULL) {
+ SetCurrentView(_SDL_GLView);
+ } else if (_SDL_View != NULL) {
+ SetCurrentView(_SDL_View);
+ } else {
+ SetCurrentView(NULL);
+ }
+ }
+ SDL_BView *CreateView() {
+ Lock();
+ if (_SDL_View == NULL) {
+ _SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES);
+ UpdateCurrentView();
+ }
+ Unlock();
+ return _SDL_View;
+ }
+
+ void RemoveView() {
+ Lock();
+ if(_SDL_View != NULL) {
+ SDL_BView *oldView = _SDL_View;
+ _SDL_View = NULL;
+ UpdateCurrentView();
+ delete oldView;
+ }
+ Unlock();
+ }
/* * * * * OpenGL functionality * * * * */
#if SDL_VIDEO_OPENGL
- virtual BGLView *CreateGLView(Uint32 gl_flags) {
+ BGLView *CreateGLView(Uint32 gl_flags) {
Lock();
if (_SDL_GLView == NULL) {
_SDL_GLView = new BGLView(Bounds(), "SDL GLView",
@@ -139,92 +196,29 @@ class SDL_BWin:public BDirectWindow
(B_WILL_DRAW | B_FRAME_EVENTS),
gl_flags);
_gl_type = gl_flags;
+ UpdateCurrentView();
}
- AddChild(_SDL_GLView);
- _SDL_GLView->EnableDirectMode(false); /* Disable direct mode */
- _SDL_GLView->LockGL(); /* "New" GLViews are created */
Unlock();
- return (_SDL_GLView);
+ return _SDL_GLView;
}
- virtual void RemoveGLView() {
+ void RemoveGLView() {
Lock();
- if(_SDL_GLView) {
- _SDL_GLView->UnlockGL();
- RemoveChild(_SDL_GLView);
+ if(_SDL_GLView != NULL) {
+ if (((SDL_BApp*)be_app)->GetCurrentContext() == _SDL_GLView)
+ ((SDL_BApp*)be_app)->SetCurrentContext(NULL);
+ _SDL_GLView = NULL;
+ UpdateCurrentView();
+ // _SDL_GLView deleted by HAIKU_GL_DeleteContext
}
Unlock();
}
- virtual void SwapBuffers(void) {
- _SDL_GLView->UnlockGL();
- _SDL_GLView->LockGL();
+ void SwapBuffers(void) {
_SDL_GLView->SwapBuffers();
}
#endif
- /* * * * * Framebuffering* * * * */
- virtual void DirectConnected(direct_buffer_info *info) {
- if(!_connected && _connection_disabled) {
- return;
- }
-
- /* Determine if the pixel buffer is usable after this update */
- _trash_window_buffer = _trash_window_buffer
- || ((info->buffer_state & B_BUFFER_RESIZED)
- || (info->buffer_state & B_BUFFER_RESET)
- || (info->driver_state == B_MODE_CHANGED));
- LockBuffer();
-
- switch(info->buffer_state & B_DIRECT_MODE_MASK) {
- case B_DIRECT_START:
- _connected = true;
-
- case B_DIRECT_MODIFY:
- if (info->clip_list_count > _num_clips)
- {
- if(_clips) {
- SDL_free(_clips);
- _clips = NULL;
- }
- }
-
- _num_clips = info->clip_list_count;
- if (_clips == NULL)
- _clips = (clipping_rect *)SDL_malloc(_num_clips*sizeof(clipping_rect));
- if(_clips) {
- SDL_memcpy(_clips, info->clip_list,
- _num_clips*sizeof(clipping_rect));
-
- _bits = (uint8*) info->bits;
- _row_bytes = info->bytes_per_row;
- _bounds = info->window_bounds;
- _bytes_per_px = info->bits_per_pixel / 8;
- _buffer_dirty = true;
- }
- break;
-
- case B_DIRECT_STOP:
- _connected = false;
- break;
- }
-#if SDL_VIDEO_OPENGL
- if(_SDL_GLView) {
- _SDL_GLView->DirectConnected(info);
- }
-#endif
-
-
- /* Call the base object directconnected */
- BDirectWindow::DirectConnected(info);
-
- UnlockBuffer();
-
- }
-
-
-
-
/* * * * * Event sending * * * * */
/* Hook functions */
virtual void FrameMoved(BPoint origin) {
@@ -235,10 +229,10 @@ class SDL_BWin:public BDirectWindow
_PostWindowEvent(msg);
/* Perform normal hook operations */
- BDirectWindow::FrameMoved(origin);
+ BWindow::FrameMoved(origin);
}
- virtual void FrameResized(float width, float height) {
+ void FrameResized(float width, float height) {
/* Post a message to the BApp so that it can handle the window event */
BMessage msg(BAPP_WINDOW_RESIZED);
@@ -247,10 +241,10 @@ class SDL_BWin:public BDirectWindow
_PostWindowEvent(msg);
/* Perform normal hook operations */
- BDirectWindow::FrameResized(width, height);
+ BWindow::FrameResized(width, height);
}
- virtual bool QuitRequested() {
+ bool QuitRequested() {
BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED);
_PostWindowEvent(msg);
@@ -258,13 +252,13 @@ class SDL_BWin:public BDirectWindow
return false;
}
- virtual void WindowActivated(bool active) {
+ void WindowActivated(bool active) {
BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */
msg.AddBool("focusGained", active);
_PostWindowEvent(msg);
}
- virtual void Zoom(BPoint origin,
+ void Zoom(BPoint origin,
float width,
float height) {
BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */
@@ -275,13 +269,13 @@ class SDL_BWin:public BDirectWindow
_prev_frame = new BRect(Frame());
/* Perform normal hook operations */
- BDirectWindow::Zoom(origin, width, height);
+ BWindow::Zoom(origin, width, height);
}
/* Member functions */
- virtual void Show() {
+ void Show() {
while(IsHidden()) {
- BDirectWindow::Show();
+ BWindow::Show();
}
_shown = true;
@@ -289,25 +283,33 @@ class SDL_BWin:public BDirectWindow
_PostWindowEvent(msg);
}
- virtual void Hide() {
- BDirectWindow::Hide();
+ void Hide() {
+ BWindow::Hide();
_shown = false;
BMessage msg(BAPP_HIDE);
_PostWindowEvent(msg);
}
- virtual void Minimize(bool minimize) {
- BDirectWindow::Minimize(minimize);
+ void Minimize(bool minimize) {
+ BWindow::Minimize(minimize);
int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE);
BMessage msg(minState);
_PostWindowEvent(msg);
}
+ void ScreenChanged(BRect screenFrame, color_space depth)
+ {
+ if (_fullscreen) {
+ MoveTo(screenFrame.left, screenFrame.top);
+ ResizeTo(screenFrame.Width(), screenFrame.Height());
+ }
+ }
+
/* BView message interruption */
- virtual void DispatchMessage(BMessage * msg, BHandler * target)
+ void DispatchMessage(BMessage * msg, BHandler * target)
{
BPoint where; /* Used by mouse moved */
int32 buttons; /* Used for mouse button events */
@@ -356,7 +358,7 @@ class SDL_BWin:public BDirectWindow
}
}
break;
-
+
case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
if (msg->FindInt32("key", &key) == B_OK) {
_KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
@@ -376,15 +378,15 @@ class SDL_BWin:public BDirectWindow
- CTRL+Q to close window (and other shortcuts)
- PrintScreen to make screenshot into /boot/home
- etc.. */
- /* BDirectWindow::DispatchMessage(msg, target); */
+ /* BWindow::DispatchMessage(msg, target); */
break;
}
- BDirectWindow::DispatchMessage(msg, target);
+ BWindow::DispatchMessage(msg, target);
}
/* Handle command messages */
- virtual void MessageReceived(BMessage* message) {
+ void MessageReceived(BMessage* message) {
switch (message->what) {
/* Handle commands from SDL */
case BWIN_SET_TITLE:
@@ -396,12 +398,18 @@ class SDL_BWin:public BDirectWindow
case BWIN_RESIZE_WINDOW:
_ResizeTo(message);
break;
- case BWIN_SET_BORDERED:
- _SetBordered(message);
+ case BWIN_SET_BORDERED: {
+ bool bEnabled;
+ if (message->FindBool("window-border", &bEnabled) == B_OK)
+ _SetBordered(bEnabled);
break;
- case BWIN_SET_RESIZABLE:
- _SetResizable(message);
+ }
+ case BWIN_SET_RESIZABLE: {
+ bool bEnabled;
+ if (message->FindBool("window-resizable", &bEnabled) == B_OK)
+ _SetResizable(bEnabled);
break;
+ }
case BWIN_SHOW_WINDOW:
Show();
break;
@@ -417,12 +425,34 @@ class SDL_BWin:public BDirectWindow
case BWIN_RESTORE_WINDOW:
_Restore();
break;
- case BWIN_FULLSCREEN:
- _SetFullScreen(message);
+ case BWIN_FULLSCREEN: {
+ bool fullscreen;
+ if (message->FindBool("fullscreen", &fullscreen) == B_OK)
+ _SetFullScreen(fullscreen);
+ break;
+ }
+ case BWIN_MINIMUM_SIZE_WINDOW:
+ _SetMinimumSize(message);
break;
+ case BWIN_UPDATE_FRAMEBUFFER: {
+ BMessage* pendingMessage;
+ while ((pendingMessage
+ = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) {
+ MessageQueue()->RemoveMessage(pendingMessage);
+ delete pendingMessage;
+ }
+ if (_bitmap != NULL) {
+ if (_SDL_View != NULL && _cur_view == _SDL_View)
+ _SDL_View->Draw(Bounds());
+ else if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) {
+ _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN);
+ }
+ }
+ break;
+ }
default:
/* Perform normal message handling */
- BDirectWindow::MessageReceived(message);
+ BWindow::MessageReceived(message);
break;
}
@@ -433,19 +463,9 @@ class SDL_BWin:public BDirectWindow
/* Accessor methods */
bool IsShown() { return _shown; }
int32 GetID() { return _id; }
- uint32 GetRowBytes() { return _row_bytes; }
- int32 GetFbX() { return _bounds.left; }
- int32 GetFbY() { return _bounds.top; }
- bool ConnectionEnabled() { return !_connection_disabled; }
- bool Connected() { return _connected; }
- clipping_rect *GetClips() { return _clips; }
- int32 GetNumClips() { return _num_clips; }
- uint8* GetBufferPx() { return _bits; }
- int32 GetBytesPerPx() { return _bytes_per_px; }
- bool CanTrashWindowBuffer() { return _trash_window_buffer; }
- bool BufferExists() { return _buffer_created; }
- bool BufferIsDirty() { return _buffer_dirty; }
BBitmap *GetBitmap() { return _bitmap; }
+ BView *GetCurView() { return _cur_view; }
+ SDL_BView *GetView() { return _SDL_View; }
#if SDL_VIDEO_OPENGL
BGLView *GetGLView() { return _SDL_GLView; }
Uint32 GetGLType() { return _gl_type; }
@@ -453,12 +473,9 @@ class SDL_BWin:public BDirectWindow
/* Setter methods */
void SetID(int32 id) { _id = id; }
- void SetBufferExists(bool bufferExists) { _buffer_created = bufferExists; }
void LockBuffer() { _buffer_locker->Lock(); }
void UnlockBuffer() { _buffer_locker->Unlock(); }
- void SetBufferDirty(bool bufferDirty) { _buffer_dirty = bufferDirty; }
- void SetTrashBuffer(bool trash) { _trash_window_buffer = trash; }
- void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; }
+ void SetBitmap(BBitmap *bitmap) { _bitmap = bitmap; if (_SDL_View != NULL) _SDL_View->SetBitmap(bitmap); }
private:
@@ -564,7 +581,10 @@ class SDL_BWin:public BDirectWindow
) {
return;
}
- MoveTo(x, y);
+ if (_fullscreen)
+ _non_fullscreen_frame.OffsetTo(x, y);
+ else
+ MoveTo(x, y);
}
void _ResizeTo(BMessage *msg) {
@@ -575,27 +595,48 @@ class SDL_BWin:public BDirectWindow
) {
return;
}
- ResizeTo(w, h);
+ if (_fullscreen) {
+ _non_fullscreen_frame.right = _non_fullscreen_frame.left + w;
+ _non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h;
+ } else
+ ResizeTo(w, h);
}
- void _SetBordered(BMessage *msg) {
- bool bEnabled;
- if(msg->FindBool("window-border", &bEnabled) != B_OK) {
- return;
+ void _SetBordered(bool bEnabled) {
+ if (_fullscreen)
+ _bordered = bEnabled;
+ else
+ SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
+ }
+
+ void _SetResizable(bool bEnabled) {
+ if (_fullscreen)
+ _resizable = bEnabled;
+ else {
+ if (bEnabled) {
+ SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
+ } else {
+ SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
+ }
}
- SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
}
- void _SetResizable(BMessage *msg) {
- bool bEnabled;
- if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
+ void _SetMinimumSize(BMessage *msg) {
+ float maxHeight;
+ float maxWidth;
+ float _;
+ int32 minHeight;
+ int32 minWidth;
+
+ // This is a bit convoluted, we only want to set the minimum not the maximum
+ // But there is no direct call to do that, so store the maximum size beforehand
+ GetSizeLimits(&_, &maxWidth, &_, &maxHeight);
+ if (msg->FindInt32("window-w", &minWidth) != B_OK)
return;
- }
- if (bEnabled) {
- SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
- } else {
- SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
- }
+ if (msg->FindInt32("window-h", &minHeight) != B_OK)
+ return;
+ SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight);
+ UpdateSizeLimits();
}
void _Restore() {
@@ -603,23 +644,42 @@ class SDL_BWin:public BDirectWindow
Minimize(false);
} else if(IsHidden()) {
Show();
+ } else if (_fullscreen) {
+
} else if(_prev_frame != NULL) { /* Zoomed */
MoveTo(_prev_frame->left, _prev_frame->top);
ResizeTo(_prev_frame->Width(), _prev_frame->Height());
}
}
- void _SetFullScreen(BMessage *msg) {
- bool fullscreen;
- if(
- msg->FindBool("fullscreen", &fullscreen) != B_OK
- ) {
- return;
+ void _SetFullScreen(bool fullscreen) {
+ if (fullscreen != _fullscreen) {
+ if (fullscreen) {
+ BScreen screen(this);
+ BRect screenFrame = screen.Frame();
+ printf("screen frame: "); screenFrame.PrintToStream(); printf("\n");
+ _bordered = Look() != B_NO_BORDER_WINDOW_LOOK;
+ _resizable = !(Flags() & B_NOT_RESIZABLE);
+ _non_fullscreen_frame = Frame();
+ _SetBordered(false);
+ _SetResizable(false);
+ MoveTo(screenFrame.left, screenFrame.top);
+ ResizeTo(screenFrame.Width(), screenFrame.Height());
+ _fullscreen = fullscreen;
+ } else {
+ _fullscreen = fullscreen;
+ MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top);
+ ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height());
+ _SetBordered(_bordered);
+ _SetResizable(_resizable);
+ }
}
- SetFullScreen(fullscreen);
}
/* Members */
+
+ BView* _cur_view;
+ SDL_BView* _SDL_View;
#if SDL_VIDEO_OPENGL
BGLView * _SDL_GLView;
Uint32 _gl_type;
@@ -632,23 +692,15 @@ class SDL_BWin:public BDirectWindow
bool _inhibit_resize;
BRect *_prev_frame; /* Previous position and size of the window */
+ bool _fullscreen;
+ // valid only if fullscreen
+ BRect _non_fullscreen_frame;
+ bool _bordered;
+ bool _resizable;
/* Framebuffer members */
- bool _connected,
- _connection_disabled,
- _buffer_created,
- _buffer_dirty,
- _trash_window_buffer;
- uint8 *_bits;
- uint32 _row_bytes;
- clipping_rect _bounds;
- BLocker *_buffer_locker;
- clipping_rect *_clips;
- uint32 _num_clips;
- int32 _bytes_per_px;
- thread_id _draw_thread_id;
-
- BBitmap *_bitmap;
+ BLocker *_buffer_locker;
+ BBitmap *_bitmap;
};