From 85b226041acb76fa52d823f0a68074d9a7df8687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 25 May 2005 18:10:20 +0000 Subject: [PATCH] Added B_BITMAP_NO_SERVER_LINK to the BBitmap flags. It constructs a BBitmap without a server link, which consequently cannot be drawn by the app_server, but which is nevertheless very useful. It essentially does the same thing as RUN_WITHOUT_APP_SERVER. I also added a CleanUp() function and moved the cleanup code from InitObject() there. CleanUp() is now called in the destructor, which means that the app_server now knows when to free the server side bitmap. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12814 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Bitmap.h | 25 +--- src/kits/interface/Bitmap.cpp | 258 ++++++++++++++++++---------------- 2 files changed, 141 insertions(+), 142 deletions(-) diff --git a/headers/os/interface/Bitmap.h b/headers/os/interface/Bitmap.h index 482fe3e8c2..e41f71a1f5 100644 --- a/headers/os/interface/Bitmap.h +++ b/headers/os/interface/Bitmap.h @@ -1,23 +1,7 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS +// Copyright (c) 2001-2005, Haiku, Inc. // -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +// Distributed under the terms of the MIT license. // // File Name: Bitmap.h // Author: Ingo Weinhold (bonefish@users.sf.net) @@ -42,7 +26,8 @@ enum { B_BITMAP_IS_CONTIGUOUS = 0x00000010 | B_BITMAP_IS_LOCKED, B_BITMAP_IS_OFFSCREEN = 0x00000020, B_BITMAP_WILL_OVERLAY = 0x00000040 | B_BITMAP_IS_OFFSCREEN, - B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080 + B_BITMAP_RESERVE_OVERLAY_CHANNEL = 0x00000080, + B_BITMAP_NO_SERVER_LINK = 0x00000100 }; #define B_ANY_BYTES_PER_ROW -1 @@ -120,6 +105,8 @@ private: int32 get_server_token() const; void InitObject(BRect bounds, color_space colorSpace, uint32 flags, int32 bytesPerRow, screen_id screenID); + void CleanUp(); + void AssertPtr(); void *fBasePtr; diff --git a/src/kits/interface/Bitmap.cpp b/src/kits/interface/Bitmap.cpp index 6b86824c11..a00d16471b 100644 --- a/src/kits/interface/Bitmap.cpp +++ b/src/kits/interface/Bitmap.cpp @@ -1,27 +1,12 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2001-2004, OpenBeOS +// Copyright (c) 2001-2005, Haiku, Inc. // -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. +// Distributed under the terms of the MIT license. // // File Name: Bitmap.cpp // Author: Ingo Weinhold (bonefish@users.sf.net) // DarkWyrm +// Stephan Aßmus // Description: BBitmap objects represent off-screen windows that // contain bitmap data. //------------------------------------------------------------------------------ @@ -825,12 +810,7 @@ BBitmap::BBitmap(const BBitmap *source, bool acceptsViews, */ BBitmap::~BBitmap() { - // TODO: don't free fBasePtr, as it's owned by the app_server - // should probably decrement an associated reference count, though, - // so the app_server knows this bitmap isn't used anymore -#ifdef RUN_WITHOUT_APP_SERVER - free(fBasePtr); -#endif // RUN_WITHOUT_APP_SERVER + CleanUp(); } // unarchiving constructor @@ -2226,40 +2206,21 @@ void BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags, int32 bytesPerRow, screen_id screenID) { +//printf("BBitmap::InitObject(bounds: BRect(%.1f, %.1f, %.1f, %.1f), format: %ld, flags: %ld, bpr: %ld\n", +// bounds.left, bounds.top, bounds.right, bounds.bottom, colorSpace, flags, bytesPerRow); + + // TODO: Hanlde setting up the offscreen window if we're such a bitmap! + + // TODO: Should we handle rounding of the "bounds" here? How does R5 behave? + status_t error = B_OK; -#ifndef RUN_WITHOUT_APP_SERVER - BPrivate::BAppServerLink link; -#endif // RUN_WITHOUT_APP_SERVER - - // clean up - if (fBasePtr) { #ifdef RUN_WITHOUT_APP_SERVER - free(fBasePtr); + flags |= B_BITMAP_NO_SERVER_LINK; #endif // RUN_WITHOUT_APP_SERVER - fBasePtr = NULL; -#ifndef RUN_WITHOUT_APP_SERVER - // AS_DELETE_BITMAP: - // Attached Data: - // 1) int32 server token - - // Reply Code: SERVER_TRUE if successful, - // SERVER_FALSE if the buffer was already deleted - // Reply Data: - // none -// status_t freestat; - int32 code = SERVER_FALSE; - link.StartMessage(AS_DELETE_BITMAP); - link.Attach(fServerToken); - error=link.FlushWithReply(&code); - if(code==SERVER_FALSE) - error=B_NO_MEMORY; - fBasePtr=NULL; - fArea=-1; - fServerToken=-1; -#endif // RUN_WITHOUT_APP_SERVER - } + CleanUp(); + // check params if (!bounds.IsValid() || !is_supported(colorSpace)) error = B_BAD_VALUE; @@ -2268,93 +2229,144 @@ BBitmap::InitObject(BRect bounds, color_space colorSpace, uint32 flags, if (bytesPerRow < 0) bytesPerRow = bpr; else if (bytesPerRow < bpr) +// NOTE: How does R5 behave? error = B_BAD_VALUE; } // allocate the bitmap buffer if (error == B_OK) { + // NOTE: Maybe the code would look more robust if the + // "size" was not calculated here when we ask the server + // to allocate the bitmap. -Stephan int32 size = bytesPerRow * (bounds.IntegerHeight() + 1); -#ifdef RUN_WITHOUT_APP_SERVER - fBasePtr = malloc(size); - if (fBasePtr) { - fSize = size; - fColorSpace = colorSpace; - fBounds = bounds; - fBytesPerRow = bytesPerRow; - fFlags = flags; - } else - error = B_NO_MEMORY; -#else - // Ask the server (via our owning application) to create a bitmap. - // Attach Data: - // 1) BRect bounds - // 2) color_space space - // 3) int32 bitmap_flags - // 4) int32 bytes_per_row - // 5) int32 screen_id::id - link.StartMessage(AS_CREATE_BITMAP); - link.Attach(bounds); - link.Attach(colorSpace); - link.Attach((int32)flags); - link.Attach(bytesPerRow); - link.Attach(screenID.id); - - // Reply Code: SERVER_TRUE - // Reply Data: - // 1) int32 server token - // 2) area_id id of the area in which the bitmap data resides - // 3) int32 area pointer offset used to calculate fBasePtr - - // alternatively, if something went wrong - // Reply Code: SERVER_FALSE - // Reply Data: - // None - int32 code = SERVER_FALSE; - error=link.FlushWithReply(&code); - - // We shouldn't ever have to execute this block, but just in case... - if(error!=B_OK) - fBasePtr=NULL; - - if(code==SERVER_TRUE) - { - // Get token - area_id bmparea; - int32 areaoffset; + if (flags & B_BITMAP_NO_SERVER_LINK) { + fBasePtr = malloc(size); + if (fBasePtr) { + fSize = size; + fColorSpace = colorSpace; + fBounds = bounds; + fBytesPerRow = bytesPerRow; + fFlags = flags; + } else + error = B_NO_MEMORY; + } else { + // Ask the server (via our owning application) to create a bitmap. + BPrivate::BAppServerLink link; + + // Attach Data: + // 1) BRect bounds + // 2) color_space space + // 3) int32 bitmap_flags + // 4) int32 bytes_per_row + // 5) int32 screen_id::id + link.StartMessage(AS_CREATE_BITMAP); + link.Attach(bounds); + link.Attach(colorSpace); + link.Attach((int32)flags); + link.Attach(bytesPerRow); + link.Attach(screenID.id); - link.Read(&fServerToken); - link.Read(&bmparea); - link.Read(&areaoffset); + // Reply Code: SERVER_TRUE + // Reply Data: + // 1) int32 server token + // 2) area_id id of the area in which the bitmap data resides + // 3) int32 area pointer offset used to calculate fBasePtr - // Get the area in which the data resides - fArea=clone_area("shared bitmap area",(void**)&fBasePtr,B_ANY_ADDRESS, - B_READ_AREA | B_WRITE_AREA,bmparea); + // alternatively, if something went wrong + // Reply Code: SERVER_FALSE + // Reply Data: + // None + int32 code = SERVER_FALSE; + error = link.FlushWithReply(&code); - // Jump to the location in the area - fBasePtr=(int8*)fBasePtr + areaoffset; - - fSize = size; - fColorSpace = colorSpace; - fBounds = bounds; - fBytesPerRow = bytesPerRow; - fFlags = flags; + if (error >= B_OK) { + // *communication* with server successful + if (code == SERVER_TRUE) { + // server side success + // Get token + area_id bmparea; + int32 areaoffset; + + link.Read(&fServerToken); + link.Read(&bmparea); + link.Read(&areaoffset); + + // Get the area in which the data resides + fArea = clone_area("shared bitmap area", + (void**)&fBasePtr, + B_ANY_ADDRESS, + B_READ_AREA | B_WRITE_AREA, + bmparea); + + // Jump to the location in the area + fBasePtr = (int8*)fBasePtr + areaoffset; + + fSize = size; + fColorSpace = colorSpace; + fBounds = bounds; + fBytesPerRow = bytesPerRow; + fFlags = flags; + } else { + // server side error, we assume: + error = B_NO_MEMORY; + } + } + // NOTE: not "else" to handle B_NO_MEMORY on server side! + if (error < B_OK) { + fBasePtr = NULL; + fServerToken = -1; + fArea = -1; + // NOTE: why not "0" in case of error? + fFlags = flags; + } } - else - { - fServerToken = -1; - fArea = -1; - fFlags = flags; - - error = B_NO_MEMORY; - } -#endif // RUN_WITHOUT_APP_SERVER fWindow = NULL; fToken = -1; fOrigArea = -1; } + + // TODO: on success, handle clearing to white if the flags say so. Needs to be + // dependent on color space. + fInitError = error; } +// CleanUp +/*! \brief Cleans up any memory allocated by the bitmap or + informs the server to do so. +*/ +void +BBitmap::CleanUp() +{ + if (fBasePtr) { + if (fFlags & B_BITMAP_NO_SERVER_LINK) { + free(fBasePtr); + } else { + BPrivate::BAppServerLink link; + // AS_DELETE_BITMAP: + // Attached Data: + // 1) int32 server token + + // Reply Code: SERVER_TRUE if successful, + // SERVER_FALSE if the buffer was already deleted + // Reply Data: none +// status_t freestat; + int32 code = SERVER_FALSE; + link.StartMessage(AS_DELETE_BITMAP); + link.Attach(fServerToken); + link.FlushWithReply(&code); + if (code == SERVER_FALSE) { + // TODO: Find out if "SERVER_FALSE if the buffer + // was already deleted" is true. If not, maybe we + // need to take additional action. + } + fArea = -1; + fServerToken = -1; + } + fBasePtr = NULL; + } +} + // AssertPtr /*! \brief ??? */