diff --git a/src/main/beos/SDL_BApp.h b/src/main/beos/SDL_BApp.h index 5932b9af3..94591e0e5 100644 --- a/src/main/beos/SDL_BApp.h +++ b/src/main/beos/SDL_BApp.h @@ -21,11 +21,14 @@ #ifndef SDL_BAPP_H #define SDL_BAPP_H +#include + #ifdef __cplusplus extern "C" { #endif #include "SDL_config.h" + #include "SDL_video.h" /* Local includes */ @@ -173,6 +176,11 @@ public: } } + /* Modes methods */ + void SetPrevMode(display_mode *prevMode) { saved_mode = prevMode; } + + display_mode* GetPrevMode() { return saved_mode; } + /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here. Is there another way to do this? */ void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ @@ -387,6 +395,8 @@ private: int32 _length; SDL_Window *window_map; #endif + + display_mode *saved_mode; }; #endif diff --git a/src/main/beos/SDL_BeApp.cc b/src/main/beos/SDL_BeApp.cc index 3a7905da4..708109c01 100644 --- a/src/main/beos/SDL_BeApp.cc +++ b/src/main/beos/SDL_BeApp.cc @@ -35,6 +35,9 @@ #include "../../video/bwindow/SDL_BWin.h" +#ifdef __cplusplus +extern "C" { +#endif /* Flag to tell whether or not the Be application is active or not */ int SDL_BeAppActive = 0; static SDL_Thread *SDL_AppThread = NULL; @@ -113,6 +116,12 @@ SDL_QuitBeApp(void) } } + +/* vi: set ts=4 sw=4 expandtab: */ +#ifdef __cplusplus +} +#endif + /* SDL_BApp functions */ void SDL_BApp::ClearID(SDL_BWin *bwin) { _SetSDLWindow(NULL, bwin->GetID()); @@ -122,6 +131,3 @@ void SDL_BApp::ClearID(SDL_BWin *bwin) { --i; } } - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/src/main/beos/SDL_BeApp.h b/src/main/beos/SDL_BeApp.h index f734a90e3..7d95e32be 100644 --- a/src/main/beos/SDL_BeApp.h +++ b/src/main/beos/SDL_BeApp.h @@ -20,6 +20,10 @@ */ #include "SDL_config.h" + +#ifdef __cplusplus +extern "C" { +#endif /* Handle the BeApp specific portions of the application */ /* Initialize the Be Application, if it's not already started */ @@ -31,3 +35,7 @@ extern void SDL_QuitBeApp(void); /* Flag to tell whether the app is active or not */ extern int SDL_BeAppActive; /* vi: set ts=4 sw=4 expandtab: */ + +#ifdef __cplusplus +} +#endif diff --git a/src/video/bwindow/SDL_BWin.h b/src/video/bwindow/SDL_BWin.h index f9139652e..083ea8f70 100644 --- a/src/video/bwindow/SDL_BWin.h +++ b/src/video/bwindow/SDL_BWin.h @@ -76,11 +76,18 @@ printf("SDL_BWin.h: 69\n"); inhibit_resize = false; mouse_focused = false; prev_frame = NULL; printf("SDL_BWin.h: 79\n"); + + /* Handle framebuffer stuff */ + _connected = connection_disabled = false; + buffer_locker = new BLocker(); +// LockBuffer(); /* Unlocked by buffer initialization */ } virtual ~ SDL_BWin() { Lock(); + connection_disabled = false; + if (the_view) { #if SDL_VIDEO_OPENGL if (the_view == SDL_GLView) { @@ -99,6 +106,11 @@ printf("SDL_BWin.h: 69\n"); if (SDL_View) { delete SDL_View; } + + /* Clean up framebuffer stuff */ + buffer_locker->Lock(); + buffer_locker->Unlock(); + delete buffer_locker; } @@ -153,6 +165,41 @@ printf("SDL_BWin.h: 69\n"); /* * * * * Framebuffering* * * * */ virtual void DirectConnected(direct_buffer_info *info) { + if(!_connected && connection_disabled) { + return; + } + LockBuffer(); + + switch(info->buffer_state & B_DIRECT_MODE_MASK) { + case B_DIRECT_START: +printf("SDL_BWin.h: 175 Direct start.\n"); + _connected = true; + + case B_DIRECT_MODIFY: + + if(_clips) { + free(_clips); + _clips = NULL; + } + + num_clips = info->clip_list_count; + _clips = (clipping_rect *)malloc(num_clips*sizeof(clipping_rect)); + if(_clips) { + memcpy(_clips, info->clip_list, + num_clips*sizeof(clipping_rect)); + + _bits = (uint8*) info->bits; + row_bytes = info->bytes_per_row; + _bounds = info->window_bounds; + } + + break; + + case B_DIRECT_STOP: + _connected = false; + break; + } + UnlockBuffer(); } @@ -353,6 +400,18 @@ printf("SDL_BWin.h: 69\n"); /* Accessor methods */ bool IsShown() { return _shown; } int32 GetID() { return _id; } + void LockBuffer() { buffer_locker->Lock(); } + void UnlockBuffer() { buffer_locker->Unlock(); } + uint32 GetRowBytes() { return row_bytes; } + int32 GetFbX() { return _bounds.left; } + int32 GetFbY() { return _bounds.top; } + int32 GetFbHeight() { return _bounds.bottom - _bounds.top + 1; } + int32 GetFbWidth() { return _bounds.right - _bounds.left + 1; } + bool ConnectionEnabled() { return !connection_disabled; } + bool Connected() { return _connected; } + clipping_rect *GetClips() { return _clips; } + int32 GetNumClips() { return num_clips; } + uint8* GetBufferPx() { return _bits; } /* Setter methods */ void SetID(int32 id) { _id = id; } @@ -582,6 +641,15 @@ private: bool inhibit_resize; BRect *prev_frame; /* Previous position and size of the window */ + + /* Framebuffer members */ + bool _connected, connection_disabled; + uint8 *_bits; + uint32 row_bytes; + clipping_rect _bounds; + BLocker *buffer_locker; + clipping_rect *_clips; + int32 num_clips; }; #endif diff --git a/src/video/bwindow/SDL_bmodes.cc b/src/video/bwindow/SDL_bmodes.cc index e1c6015d2..8814f70d0 100644 --- a/src/video/bwindow/SDL_bmodes.cc +++ b/src/video/bwindow/SDL_bmodes.cc @@ -24,6 +24,7 @@ #include #include #include "SDL_bmodes.h" +#include "SDL_BWin.h" #include "../../main/beos/SDL_BApp.h" @@ -31,6 +32,9 @@ extern "C" { #endif +static inline SDL_BWin *_ToBeWin(SDL_Window *window) { + return ((SDL_BWin*)(window->driverdata)); +} static inline SDL_BApp *_GetBeApp() { return ((SDL_BApp*)be_app); @@ -199,6 +203,95 @@ int BE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){ return -1; } + + +int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, + void ** pixels, int *pitch) { + SDL_BWin *bwin = _ToBeWin(window); + BScreen bscreen; + if(!bscreen.IsValid()) { + return -1; + } + + while(!bwin->Connected()) { snooze(1600); } + + /* Make sure we have exclusive access to frame buffer data */ + bwin->LockBuffer(); + + /* format */ + display_mode bmode; + bscreen.GetMode(&bmode); + int32 bpp = ColorSpaceToBitsPerPixel(bmode.space); + *format = BppToSDLPxFormat(bpp); + + /* pitch = width of screen, in bytes */ + *pitch = bpp * bwin->GetFbWidth() / 8; + + /* Create a copy of the pixel buffer */ + printf("SDL_bmodes.cc: 230; fbh: %i, pitch: %i; (x,y) = (%i, %i)\n", bwin->GetFbHeight(), (*pitch), bwin->GetFbX(), bwin->GetFbY()); + *pixels = SDL_calloc((*pitch) * bwin->GetFbHeight() * bpp / 8, sizeof(uint8)); + + bwin->UnlockBuffer(); + return 0; +} + + + +int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + SDL_Rect * rects, int numrects) { + SDL_BWin *bwin = _ToBeWin(window); + BScreen bscreen; + if(!bscreen.IsValid()) { + return -1; + } + + if(bwin->ConnectionEnabled() && bwin->Connected()) { + bwin->LockBuffer(); + int32 windowPitch = window->surface->pitch; + int32 bufferPitch = bwin->GetRowBytes(); + uint8 *windowpx; + uint8 *bufferpx; + + int32 bpp = window->surface->format->BitsPerPixel; + uint8 *windowBaseAddress = (uint8*)window->surface->pixels; + int32 windowSub = bwin->GetFbX() * bpp / 8 + + bwin->GetFbY() * windowPitch; + clipping_rect *clips = bwin->GetClips(); + int32 numClips = bwin->GetNumClips(); + int i, y; + + /* Blit each clipping rectangle */ + bscreen.WaitForRetrace(); + for(i = 0; i < numClips; ++i) { + /* Get addresses of the start of each clipping rectangle */ + int32 width = clips[i].right - clips[i].left + 1; + int32 height = clips[i].bottom - clips[i].top + 1; + bufferpx = bwin->GetBufferPx() + + clips[i].top * bufferPitch + clips[i].left * bpp / 8; + windowpx = windowBaseAddress + + clips[i].top * windowPitch + clips[i].left * bpp / 8 + - windowSub; + + /* Copy each row of pixels from the window buffer into the frame + buffer */ + for(y = 0; y < height; ++y) + { + memcpy(bufferpx, windowpx, width * bpp / 8); + bufferpx += bufferPitch; + windowpx += windowPitch; + } + } + bwin->UnlockBuffer(); + } + return 0; +} + +void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { + /* FIXME: FINISH! */ + printf("ERROR: Attempted to destroy the window frame buffer\n"); +} + #ifdef __cplusplus } #endif diff --git a/src/video/bwindow/SDL_bmodes.h b/src/video/bwindow/SDL_bmodes.h index aeecfe1cb..af080c524 100644 --- a/src/video/bwindow/SDL_bmodes.h +++ b/src/video/bwindow/SDL_bmodes.h @@ -36,6 +36,14 @@ extern void BE_GetDisplayModes(_THIS, SDL_VideoDisplay *display); extern int BE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, + void ** pixels, int *pitch); +extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + SDL_Rect * rects, int numrects); +extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + + #ifdef __cplusplus } #endif diff --git a/src/video/bwindow/SDL_bwindow.cc b/src/video/bwindow/SDL_bwindow.cc index 8181a18b1..4cb92ece1 100644 --- a/src/video/bwindow/SDL_bwindow.cc +++ b/src/video/bwindow/SDL_bwindow.cc @@ -180,27 +180,6 @@ SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window, -int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, - Uint32 * format, - void ** pixels, int *pitch) { - /* pitch = width of screen, in bytes */ - BScreen bscreen; - *pitch = (bscreen->Frame().right - bscreen->Frame().left + 1) * /*screen w*/ - SDL_BYTESPERPIXEL(*format); - - /* FIXME: FINISH! */ - return -1; -} - -int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, - SDL_Rect * rects, int numrects) { - - return -1; -} - -void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { - /* FIXME: FINISH! */ -} #ifdef __cplusplus diff --git a/src/video/bwindow/SDL_bwindow.h b/src/video/bwindow/SDL_bwindow.h index 26f800b7f..8e6959851 100644 --- a/src/video/bwindow/SDL_bwindow.h +++ b/src/video/bwindow/SDL_bwindow.h @@ -45,12 +45,7 @@ extern void BE_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); -extern int BE_CreateWindowFramebuffer(_THIS, SDL_Window * window, - Uint32 * format, - void ** pixels, int *pitch); -extern int BE_UpdateWindowFramebuffer(_THIS, SDL_Window * window, - SDL_Rect * rects, int numrects); -extern void BE_DestroyWindowFramebuffer(_THIS, SDL_Window * window); + #endif