From 423feac69b7db9b8eaca486c766a75bccea8353a Mon Sep 17 00:00:00 2001 From: waddlesplash 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 | 418 +++++++++++++++++++++---------------- 1 file changed, 235 insertions(+), 183 deletions(-) diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index dc6e442a8..1ac517164 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -39,7 +39,6 @@ extern "C" { #include #include #include -#include #if SDL_VIDEO_OPENGL #include #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) + { + } -class SDL_BWin:public BDirectWindow + void Draw(BRect dirty) + { + if (fBitmap != NULL) + DrawBitmap(fBitmap, B_ORIGIN); + } + + void SetBitmap(BBitmap *bitmap) + { + fBitmap = bitmap; + } + +private: + BBitmap *fBitmap; +}; + +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 @@ private: ) { return; } - MoveTo(x, y); + if (_fullscreen) + _non_fullscreen_frame.OffsetTo(x, y); + else + MoveTo(x, y); } void _ResizeTo(BMessage *msg) { @@ -575,27 +595,48 @@ private: ) { 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; - } - SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); + void _SetBordered(bool bEnabled) { + if (_fullscreen) + _bordered = bEnabled; + else + 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 _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)); + } + } + } + + 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 @@ private: 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 @@ private: 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; };