Merged app_server_new_clipping branch changes r15290 to 15418 back into trunk.

Also fixed Jamfile for the test environment.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15419 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-12-08 12:41:19 +00:00
parent af43bb3c94
commit e83820ed57
41 changed files with 5348 additions and 5375 deletions
+6 -7
View File
@@ -80,16 +80,15 @@ class Decorator {
bool GetMinimize(); bool GetMinimize();
bool GetZoom(); bool GetZoom();
virtual void GetSizeLimits(float* minWidth, float* minHeight, virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
float* maxWidth, float* maxHeight) const; int32* maxWidth, int32* maxHeight) const;
void SetFocus(bool focussed);
void SetFocus(bool is_active); bool IsFocus()
bool GetFocus()
{ return fIsFocused; }; { return fIsFocused; };
ColorSet GetColors() ColorSet Colors()
{ return (_colors) ? *_colors : ColorSet(); } { return (_colors) ? *_colors : ColorSet(); }
virtual void GetFootprint(BRegion *region); virtual void GetFootprint(BRegion *region);
virtual click_type Clicked(BPoint pt, int32 buttons, virtual click_type Clicked(BPoint pt, int32 buttons,
+80 -123
View File
@@ -28,8 +28,7 @@ class ServerBitmap;
class ServerCursor; class ServerCursor;
class ServerFont; class ServerFont;
typedef struct typedef struct {
{
BPoint pt1; BPoint pt1;
BPoint pt2; BPoint pt2;
rgb_color color; rgb_color color;
@@ -38,176 +37,134 @@ typedef struct
class DrawingEngine { class DrawingEngine {
public: public:
DrawingEngine(HWInterface* interface = NULL); DrawingEngine(HWInterface* interface = NULL);
virtual ~DrawingEngine(); virtual ~DrawingEngine();
// when implementing, be sure to call the inherited version // when implementing, be sure to call the inherited version
status_t Initialize(); status_t Initialize();
void Shutdown(); void Shutdown();
// locking // locking
bool Lock(); bool Lock();
void Unlock(); void Unlock();
bool WriteLock(); bool WriteLock();
void WriteUnlock(); void WriteUnlock();
// for "changing" hardware // for "changing" hardware
void Update(); void Update();
void SetHWInterface(HWInterface* interface); void SetHWInterface(HWInterface* interface);
// for screen shots // for screen shots
bool DumpToFile( const char *path); bool DumpToFile(const char *path);
ServerBitmap* DumpToBitmap(); ServerBitmap* DumpToBitmap();
// clipping for all drawing functions, passing a NULL region // clipping for all drawing functions, passing a NULL region
// will remove any clipping (drawing allowed everywhere) // will remove any clipping (drawing allowed everywhere)
void ConstrainClippingRegion(BRegion* region); void ConstrainClippingRegion(const BRegion* region);
// drawing functions // drawing functions
void CopyRegion( /*const*/ BRegion* region, void CopyRegion(/*const*/ BRegion* region,
int32 xOffset, int32 xOffset, int32 yOffset);
int32 yOffset);
void CopyRegionList( BList* list, void CopyRegionList(BList* list, BList* pList,
BList* pList, int32 rCount, BRegion* clipReg);
int32 rCount,
BRegion* clipReg);
void InvertRect( BRect r); void InvertRect(BRect r);
void DrawBitmap( ServerBitmap *bitmap, void DrawBitmap(ServerBitmap *bitmap,
const BRect &source, const BRect &source, const BRect &dest,
const BRect &dest, const DrawState *d);
const DrawState *d);
// drawing primitives // drawing primitives
void DrawArc( BRect r, void DrawArc(BRect r, const float &angle,
const float &angle, const float &span,
const float &span, const DrawState *d,
const DrawState *d, bool filled);
bool filled);
void DrawBezier( BPoint *pts, void DrawBezier(BPoint *pts, const DrawState *d,
const DrawState *d, bool filled);
bool filled);
void DrawEllipse( BRect r, void DrawEllipse(BRect r, const DrawState *d,
const DrawState *d, bool filled);
bool filled);
void DrawPolygon( BPoint *ptlist, void DrawPolygon(BPoint *ptlist, int32 numpts,
int32 numpts, BRect bounds, const DrawState *d,
BRect bounds, bool filled, bool closed);
const DrawState *d,
bool filled,
bool closed);
// this version used by Decorator // this version used by Decorator
void StrokeRect( BRect r, void StrokeRect(BRect r, const RGBColor &color);
const RGBColor &color); void FillRect(BRect r, const RGBColor &color);
void FillRect( BRect r, void StrokeRect(BRect r, const DrawState *d);
const RGBColor &color); void FillRect(BRect r, const DrawState *d);
void StrokeRect( BRect r,
const DrawState *d);
void FillRect( BRect r,
const DrawState *d);
// for debugging purposes? // for debugging purposes?
void StrokeRegion( BRegion &r, void StrokeRegion(BRegion &r, const DrawState *d);
const DrawState *d); void FillRegion(BRegion &r, const DrawState *d);
void FillRegion(BRegion &r, const RGBColor& color);
void FillRegion( BRegion &r, void DrawRoundRect(BRect r, float xrad,
const DrawState *d); float yrad, const DrawState *d,
bool filled);
void DrawRoundRect( BRect r, void DrawShape(const BRect &bounds,
const float &xrad, int32 opcount, const uint32 *oplist,
const float &yrad, int32 ptcount, const BPoint *ptlist,
const DrawState *d, const DrawState *d, bool filled);
bool filled);
void DrawShape( const BRect &bounds, void DrawTriangle(BPoint *pts, const BRect &bounds,
const int32 &opcount, const DrawState *d, bool filled);
const uint32 *oplist,
const int32 &ptcount,
const BPoint *ptlist,
const DrawState *d,
bool filled);
void DrawTriangle( BPoint *pts,
const BRect &bounds,
const DrawState *d,
bool filled);
// this version used by Decorator // this version used by Decorator
void StrokeLine( const BPoint &start, void StrokeLine(const BPoint &start,
const BPoint &end, const BPoint &end, const RGBColor &color);
const RGBColor &color);
void StrokeLine( const BPoint &start, void StrokeLine(const BPoint &start,
const BPoint &end, const BPoint &end, DrawState *d);
DrawState *d);
void StrokeLineArray(const int32 &numlines, void StrokeLineArray(int32 numlines,
const LineArrayData *data, const LineArrayData *data,
const DrawState *d); const DrawState *d);
// this version used by Decorator // this version used by Decorator
void StrokePoint( const BPoint &pt, void StrokePoint(const BPoint &pt,
const RGBColor &color); const RGBColor &color);
void StrokePoint( const BPoint &pt, void StrokePoint(const BPoint &pt,
DrawState *d); DrawState *d);
// -------- text related calls // -------- text related calls
// DrawState is NOT const because this call updates the pen position in the passed DrawState // DrawState is NOT const because this call updates the pen position in the passed DrawState
BPoint DrawString( const char* string, BPoint DrawString(const char* string, int32 length,
int32 length, const BPoint& pt, DrawState* d,
const BPoint& pt, escapement_delta* delta = NULL);
DrawState* d,
escapement_delta* delta = NULL);
/* void DrawString( const char *string, float StringWidth(const char* string, int32 length,
const int32 &length, const DrawState* d,
const BPoint &pt, escapement_delta* delta = NULL);
const RGBColor &color,
escapement_delta *delta=NULL);*/
float StringWidth( const char* string, float StringWidth(const char* string,
int32 length, int32 length, const ServerFont& font,
const DrawState* d, escapement_delta* delta = NULL);
escapement_delta* delta = NULL);
float StringWidth( const char* string, float StringHeight(const char* string,
int32 length, int32 length, const DrawState* d);
const ServerFont& font,
escapement_delta* delta = NULL);
float StringHeight( const char* string,
int32 length,
const DrawState* d);
private: private:
BRect _CopyRect( BRect r, BRect _CopyRect(BRect r, int32 xOffset,
int32 xOffset, int32 yOffset) const;
int32 yOffset) const;
void _CopyRect( uint8* bits, void _CopyRect(uint8* bits, uint32 width,
uint32 width, uint32 height, uint32 bytesPerRow,
uint32 height, int32 xOffset, int32 yOffset) const;
uint32 bpr,
int32 xOffset,
int32 yOffset) const;
Painter* fPainter; Painter* fPainter;
HWInterface* fGraphicsCard; HWInterface* fGraphicsCard;
uint32 fAvailableHWAccleration; uint32 fAvailableHWAccleration;
}; };
#endif // DRAWING_ENGINE_H_ #endif // DRAWING_ENGINE_H_
+2 -2
View File
@@ -20,10 +20,10 @@
#include "FontManager.h" #include "FontManager.h"
#include "HWInterface.h" #include "HWInterface.h"
#include "InputManager.h" #include "InputManager.h"
#include "Layer.h" //#include "Layer.h"
#include "RGBColor.h" #include "RGBColor.h"
#include "RegistrarDefs.h" #include "RegistrarDefs.h"
#include "RootLayer.h" //#include "RootLayer.h"
#include "ScreenManager.h" #include "ScreenManager.h"
#include "ServerApp.h" #include "ServerApp.h"
#include "ServerConfig.h" #include "ServerConfig.h"
+253 -311
View File
@@ -6,11 +6,11 @@
* John Walker <[email protected]> * John Walker <[email protected]>
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Stephan Aßmus <[email protected]> * Stephan Aßmus <[email protected]>
*
* BGET pool allocator
*/ */
/* /*
BGET pool allocator
This class is based on the BGET pool allocator. Original code was in standard This class is based on the BGET pool allocator. Original code was in standard
ANSI C with a bunch of static variables. The original code was placed into the ANSI C with a bunch of static variables. The original code was placed into the
MemPool class and the original allocation, release, and compacting functions MemPool class and the original allocation, release, and compacting functions
@@ -49,8 +49,8 @@
#define ESent ((ssize_t) (-(((1L << (sizeof(ssize_t) * 8 - 2)) - 1) * 2) - 2)) #define ESent ((ssize_t) (-(((1L << (sizeof(ssize_t) * 8 - 2)) - 1) * 2) - 2))
MemPool::MemPool() MemPool::MemPool(int32 incrementSize)
: fTotalAlloced(0), : fTotalAllocated(0),
fGetCount(0), fGetCount(0),
fReleaseCount(0), fReleaseCount(0),
fNumpblk(0), fNumpblk(0),
@@ -58,7 +58,7 @@ MemPool::MemPool()
fNumprel(0), fNumprel(0),
fNumdget(0), fNumdget(0),
fNumdrel(0), fNumdrel(0),
fExpIncr(0), fIncrementSize(incrementSize),
fPoolLength(0) fPoolLength(0)
{ {
fFreeList.bh = (bhead){ 0, 0 }; fFreeList.bh = (bhead){ 0, 0 };
@@ -70,19 +70,17 @@ MemPool::~MemPool()
{ {
} }
// Allocate a buffer from the available space in the memory pool
void*
MemPool::GetBuffer(ssize_t requested_size, bool zero)
{
ssize_t size = requested_size;
void *buf;
//! Allocate a buffer from the available space in the memory pool
void*
MemPool::GetBuffer(ssize_t requestedSize, bool zero)
{
ssize_t size = requestedSize;
int compactseq = 0; int compactseq = 0;
assert(size > 0); assert(size > 0);
if (size < (ssize_t)SizeQ) if (size < (ssize_t)SizeQ) {
{
// Need at least room for the queue links. // Need at least room for the queue links.
size = SizeQ; size = SizeQ;
} }
@@ -99,158 +97,134 @@ MemPool::GetBuffer(ssize_t requested_size, bool zero)
// If a compact function was provided in the call to bectl(), wrap // If a compact function was provided in the call to bectl(), wrap
// a loop around the allocation process to allow compaction to // a loop around the allocation process to allow compaction to
// intervene in case we don't find a suitable buffer in the chain. // intervene in case we don't find a suitable buffer in the chain.
while (1) while (1) {
{
b = fFreeList.ql.flink; b = fFreeList.ql.flink;
best = &fFreeList; best = &fFreeList;
// Scan the free list searching for the first buffer big enough // Scan the free list searching for the first buffer big enough
// to hold the requested size buffer. // to hold the requested size buffer.
while (b != &fFreeList) while (b != &fFreeList) {
{ if (b->bh.bsize >= size) {
if (b->bh.bsize >= size) if ((best == &fFreeList) || (b->bh.bsize < best->bh.bsize)) {
{
if ((best == &fFreeList) || (b->bh.bsize < best->bh.bsize))
{
best = b; best = b;
} }
} }
b = b->ql.flink; // Link to next buffer b = b->ql.flink; // Link to next buffer
} }
b = best; b = best;
while (b != &fFreeList) while (b != &fFreeList) {
{ if ((ssize_t) b->bh.bsize >= size) {
if ((ssize_t) b->bh.bsize >= size)
{
// Buffer is big enough to satisfy the request. Allocate it to the caller. // Buffer is big enough to satisfy the request. Allocate it to the caller.
// We must decide whether the buffer is large enough to split into the part // We must decide whether the buffer is large enough to split into the part
// given to the caller and a free buffer that remains on the free list, or // given to the caller and a free buffer that remains on the free list, or
// whether the entire buffer should be removed from the free list and given // whether the entire buffer should be removed from the free list and given
// to the caller in its entirety. We only split the buffer if enough room // to the caller in its entirety. We only split the buffer if enough room
// remains for a header plus the minimum quantum of allocation. // remains for a header plus the minimum quantum of allocation.
if ((b->bh.bsize - size) > (ssize_t)(SizeQ + (sizeof(struct bhead)))) if ((b->bh.bsize - size) > (ssize_t)(SizeQ + (sizeof(struct bhead)))) {
{
struct bhead *ba, *bn; struct bhead *ba, *bn;
ba = BH(((char *) b) + (b->bh.bsize - size)); ba = BH(((char *) b) + (b->bh.bsize - size));
bn = BH(((char *) ba) + size); bn = BH(((char *) ba) + size);
assert(bn->prevfree == b->bh.bsize); assert(bn->prevfree == b->bh.bsize);
// Subtract size from length of free block. // Subtract size from length of free block.
b->bh.bsize -= size; b->bh.bsize -= size;
// Link allocated buffer to the previous free buffer. // Link allocated buffer to the previous free buffer.
ba->prevfree = b->bh.bsize; ba->prevfree = b->bh.bsize;
// Plug negative size into user buffer. // Plug negative size into user buffer.
ba->bsize = -(ssize_t) size; ba->bsize = -(ssize_t) size;
// Mark buffer after this one not preceded by free block. // Mark buffer after this one not preceded by free block.
bn->prevfree = 0; bn->prevfree = 0;
fTotalAlloced += size; fTotalAllocated += size;
fGetCount++; // Increment number of GetBuffer() calls fGetCount++; // Increment number of GetBuffer() calls
buf = (void *) ((((char *) ba) + sizeof(struct bhead))); return (void *)((((char *)ba) + sizeof(struct bhead)));
return buf; } else {
}
else
{
struct bhead *ba; struct bhead *ba;
ba = BH(((char *) b) + b->bh.bsize); ba = BH(((char *) b) + b->bh.bsize);
assert(ba->prevfree == b->bh.bsize); assert(ba->prevfree == b->bh.bsize);
// The buffer isn't big enough to split. Give the whole // The buffer isn't big enough to split. Give the whole
// shebang to the caller and remove it from the free list. // shebang to the caller and remove it from the free list.
assert(b->ql.blink->ql.flink == b); assert(b->ql.blink->ql.flink == b);
assert(b->ql.flink->ql.blink == b); assert(b->ql.flink->ql.blink == b);
b->ql.blink->ql.flink = b->ql.flink; b->ql.blink->ql.flink = b->ql.flink;
b->ql.flink->ql.blink = b->ql.blink; b->ql.flink->ql.blink = b->ql.blink;
fTotalAlloced += b->bh.bsize; fTotalAllocated += b->bh.bsize;
fGetCount++; // Increment number of GetBuffer() calls fGetCount++; // Increment number of GetBuffer() calls
// Negate size to mark buffer allocated. // Negate size to mark buffer allocated.
b->bh.bsize = -(b->bh.bsize); b->bh.bsize = -(b->bh.bsize);
// Zero the back pointer in the next buffer in memory // Zero the back pointer in the next buffer in memory
// to indicate that this buffer is allocated. // to indicate that this buffer is allocated.
ba->prevfree = 0; ba->prevfree = 0;
// Give user buffer starting at queue links. // Give user buffer starting at queue links.
buf = (void *) &(b->ql); return (void *)&(b->ql);
return buf;
} }
} }
b = b->ql.flink; // Link to next buffer b = b->ql.flink; // Link to next buffer
} }
// We failed to find a buffer. If there's a compact function // We failed to find a buffer. If there's a compact function
// defined, notify it of the size requested. If it returns // defined, notify it of the size requested. If it returns
// TRUE, try the allocation again. // TRUE, try the allocation again.
if(!CompactMem(size, ++compactseq)) if (!CompactMem(size, ++compactseq))
break; break;
} }
// No buffer available with requested size free. // No buffer available with requested size free.
// Don't give up yet -- look in the reserve supply. // Don't give up yet -- look in the reserve supply.
if (size > (ssize_t)(fExpIncr - sizeof(struct bhead))) if (size > (ssize_t)(fIncrementSize - sizeof(struct bhead))) {
{
// Request is too large to fit in a single expansion // Request is too large to fit in a single expansion
// block. Try to satisy it by a direct buffer acquisition. // block. Try to satisy it by a direct buffer acquisition.
struct bdhead *bdh; struct bdhead *bdh;
size += sizeof(struct bdhead) - sizeof(struct bhead); size += sizeof(struct bdhead) - sizeof(struct bhead);
if ((bdh = BDH(AcquireMem((ssize_t) size))) != NULL) if ((bdh = BDH(AcquireMem((ssize_t) size))) != NULL) {
{
// Mark the buffer special by setting the size field // Mark the buffer special by setting the size field
// of its header to zero. // of its header to zero.
bdh->bh.bsize = 0; bdh->bh.bsize = 0;
bdh->bh.prevfree = 0; bdh->bh.prevfree = 0;
bdh->tsize = size; bdh->tsize = size;
fTotalAlloced += size; fTotalAllocated += size;
// Increment number of GetBuffer() calls // Increment number of GetBuffer() calls
fGetCount++; fGetCount++;
// Direct GetBuffer() call count // Direct GetBuffer() call count
fNumdget++; fNumdget++;
buf = (void *) (bdh + 1); return (void *)(bdh + 1);
return buf;
} }
} else {
} // Try to obtain a new expansion block
else
{
// Try to obtain a new expansion block
void *newpool; void *newpool;
if ((newpool = AcquireMem((ssize_t) fExpIncr)) != NULL) if ((newpool = AcquireMem((ssize_t)fIncrementSize)) != NULL) {
{ AddToPool(newpool, fIncrementSize);
AddToPool(newpool, fExpIncr);
// This can't, I say, can't get into a loop
buf = GetBuffer(requested_size);
return buf; // This can't, I say, can't get into a loop
return GetBuffer(requestedSize);
} }
} }
// Still no buffer available // Still no buffer available
return NULL; return NULL;
// Code from bgetz -- zeroing code // Code from bgetz -- zeroing code
@@ -285,116 +259,110 @@ MemPool::GetBuffer(ssize_t requested_size, bool zero)
} }
// Reallocate a buffer. This is a minimal implementation, simply in terms /*!
// of ReleaseBuffer() and GetBuffer(). It could be enhanced to allow the Reallocate a buffer. This is a minimal implementation, simply in terms
// buffer to grow into adjacent free blocks and to avoid moving data unnecessarily. of ReleaseBuffer() and GetBuffer(). It could be enhanced to allow the
buffer to grow into adjacent free blocks and to avoid moving data
unnecessarily.
*/
void* void*
MemPool::ReallocateBuffer(void *buf, ssize_t size) MemPool::ReallocateBuffer(void *buf, ssize_t size)
{ {
void *nbuf; void *nbuf;
// Old size of buffer
ssize_t osize;
struct bhead *b;
if ((nbuf = GetBuffer(size)) == NULL) // Old size of buffer
{ ssize_t osize;
// Acquire new buffer struct bhead *b;
if ((nbuf = GetBuffer(size)) == NULL) {
// Acquire new buffer
return NULL; return NULL;
} }
if (buf == NULL)
{
return nbuf;
}
b = BH(((char *) buf) - sizeof(struct bhead));
osize = -b->bsize;
if (osize == 0) if (buf == NULL)
{ return nbuf;
b = BH(((char *) buf) - sizeof(struct bhead));
osize = -b->bsize;
if (osize == 0) {
// Buffer acquired directly through acqfcn. // Buffer acquired directly through acqfcn.
struct bdhead *bd; struct bdhead *bd;
bd = BDH(((char *) buf) - sizeof(struct bdhead)); bd = BDH(((char *) buf) - sizeof(struct bdhead));
osize = bd->tsize - sizeof(struct bdhead); osize = bd->tsize - sizeof(struct bdhead);
} } else
else
osize -= sizeof(struct bhead); osize -= sizeof(struct bhead);
assert(osize > 0);
assert(osize > 0);
// Copy the data
memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize)); // Copy the data
ReleaseBuffer(buf); memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize));
return nbuf; ReleaseBuffer(buf);
return nbuf;
} }
// BREL -- Release a buffer.
//! Release a buffer.
void void
MemPool::ReleaseBuffer(void *buf) MemPool::ReleaseBuffer(void *buf)
{ {
struct bfhead *b, *bn; struct bfhead *b, *bn;
b = BFH(((char *) buf) - sizeof(struct bhead)); b = BFH(((char *)buf) - sizeof(struct bhead));
// Increment number of ReleaseBuffer() calls // Increment number of ReleaseBuffer() calls
fReleaseCount++; fReleaseCount++;
assert(buf != NULL);
assert(buf != NULL);
// Directly-acquired buffer? // Directly-acquired buffer?
if (b->bh.bsize == 0) if (b->bh.bsize == 0) {
{
struct bdhead *bdh; struct bdhead *bdh;
bdh = BDH(((char *) buf) - sizeof(struct bdhead)); bdh = BDH(((char *)buf) - sizeof(struct bdhead));
assert(b->bh.prevfree == 0); assert(b->bh.prevfree == 0);
fTotalAlloced -= bdh->tsize; fTotalAllocated -= bdh->tsize;
assert(fTotalAlloced >= 0); assert(fTotalAllocated >= 0);
// Number of direct releases // Number of direct releases
fNumdrel++; fNumdrel++;
memset((char *) buf, 0x55, (int) (bdh->tsize - sizeof(struct bdhead))); memset((char *)buf, 0x55, (int)(bdh->tsize - sizeof(struct bdhead)));
// Release it directly. // Release it directly.
ReleaseMem((void *) bdh); ReleaseMem((void *)bdh);
return; return;
} }
// Buffer size must be negative, indicating that the buffer is allocated.
// Buffer size must be negative, indicating that the buffer is allocated. if (b->bh.bsize >= 0)
if (b->bh.bsize >= 0)
{
bn = NULL; bn = NULL;
}
assert(b->bh.bsize < 0);
// Back pointer in next buffer must be zero, indicating the same thing: assert(b->bh.bsize < 0);
assert(BH((char *) b - b->bh.bsize)->prevfree == 0);
fTotalAlloced += b->bh.bsize; // Back pointer in next buffer must be zero, indicating the same thing:
assert(fTotalAlloced >= 0); assert(BH((char *)b - b->bh.bsize)->prevfree == 0);
fTotalAllocated += b->bh.bsize;
assert(fTotalAllocated >= 0);
// If the back link is nonzero, the previous buffer is free. // If the back link is nonzero, the previous buffer is free.
if (b->bh.prevfree != 0) if (b->bh.prevfree != 0) {
{
// The previous buffer is free. Consolidate this buffer with it // The previous buffer is free. Consolidate this buffer with it
// by adding the length of this buffer to the previous free // by adding the length of this buffer to the previous free
// buffer. Note that we subtract the size in the buffer being // buffer. Note that we subtract the size in the buffer being
// released, since it's negative to indicate that the buffer is allocated. // released, since it's negative to indicate that the buffer is allocated.
register ssize_t size = b->bh.bsize; register ssize_t size = b->bh.bsize;
// Make the previous buffer the one we're working on. // Make the previous buffer the one we're working on.
assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree); assert(BH((char *) b - b->bh.prevfree)->bsize == b->bh.prevfree);
b = BFH(((char *) b) - b->bh.prevfree); b = BFH(((char *) b) - b->bh.prevfree);
b->bh.bsize -= size; b->bh.bsize -= size;
} } else {
else
{
// The previous buffer isn't allocated. Insert this buffer on the // The previous buffer isn't allocated. Insert this buffer on the
// free list as an isolated free block. // free list as an isolated free block.
assert(fFreeList.ql.blink->ql.flink == &fFreeList); assert(fFreeList.ql.blink->ql.flink == &fFreeList);
@@ -404,16 +372,15 @@ MemPool::ReleaseBuffer(void *buf)
fFreeList.ql.blink = b; fFreeList.ql.blink = b;
b->ql.blink->ql.flink = b; b->ql.blink->ql.flink = b;
b->bh.bsize = -b->bh.bsize; b->bh.bsize = -b->bh.bsize;
} }
// Now we look at the next buffer in memory, located by advancing from // Now we look at the next buffer in memory, located by advancing from
// the start of this buffer by its size, to see if that buffer is // the start of this buffer by its size, to see if that buffer is
// free. If it is, we combine this buffer with the next one in // free. If it is, we combine this buffer with the next one in
// memory, dechaining the second buffer from the free list. // memory, dechaining the second buffer from the free list.
bn = BFH(((char *) b) + b->bh.bsize); bn = BFH(((char *) b) + b->bh.bsize);
if (bn->bh.bsize > 0) if (bn->bh.bsize > 0) {
{
// The buffer is free. Remove it from the free list and add // The buffer is free. Remove it from the free list and add
// its size to that of our buffer. // its size to that of our buffer.
assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize); assert(BH((char *) bn + bn->bh.bsize)->prevfree == bn->bh.bsize);
@@ -422,7 +389,7 @@ MemPool::ReleaseBuffer(void *buf)
bn->ql.blink->ql.flink = bn->ql.flink; bn->ql.blink->ql.flink = bn->ql.flink;
bn->ql.flink->ql.blink = bn->ql.blink; bn->ql.flink->ql.blink = bn->ql.blink;
b->bh.bsize += bn->bh.bsize; b->bh.bsize += bn->bh.bsize;
// Finally, advance to the buffer that follows the newly // Finally, advance to the buffer that follows the newly
// consolidated free block. We must set its backpointer to the // consolidated free block. We must set its backpointer to the
// head of the consolidated free block. We know the next block // head of the consolidated free block. We know the next block
@@ -430,43 +397,44 @@ MemPool::ReleaseBuffer(void *buf)
// guarantees that two free blocks will never be contiguous in // guarantees that two free blocks will never be contiguous in
// memory. // memory.
bn = BFH(((char *) b) + b->bh.bsize); bn = BFH(((char *) b) + b->bh.bsize);
} }
memset(((char *) b) + sizeof(struct bfhead), 0x55,(int) (b->bh.bsize - sizeof(struct bfhead))); memset(((char *) b) + sizeof(struct bfhead), 0x55,
(int)(b->bh.bsize - sizeof(struct bfhead)));
assert(bn->bh.bsize < 0); assert(bn->bh.bsize < 0);
// The next buffer is allocated. Set the backpointer in it to point // The next buffer is allocated. Set the backpointer in it to point
// to this buffer; the previous free buffer in memory. // to this buffer; the previous free buffer in memory.
bn->bh.prevfree = b->bh.bsize; bn->bh.prevfree = b->bh.bsize;
// If a block-release function is defined, and this free buffer // If a block-release function is defined, and this free buffer
// constitutes the entire block, release it. Note that fPoolLength // constitutes the entire block, release it. Note that fPoolLength
// is defined in such a way that the test will fail unless all // is defined in such a way that the test will fail unless all
// pool blocks are the same size. // pool blocks are the same size.
if (((ssize_t) b->bh.bsize) == (ssize_t)(fPoolLength - sizeof(struct bhead))) if (((ssize_t) b->bh.bsize) == (ssize_t)(fPoolLength - sizeof(struct bhead))) {
{
assert(b->bh.prevfree == 0); assert(b->bh.prevfree == 0);
assert(BH((char *) b + b->bh.bsize)->bsize == ESent); assert(BH((char *) b + b->bh.bsize)->bsize == ESent);
assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize); assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);
// Unlink the buffer from the free list // Unlink the buffer from the free list
b->ql.blink->ql.flink = b->ql.flink; b->ql.blink->ql.flink = b->ql.flink;
b->ql.flink->ql.blink = b->ql.blink; b->ql.flink->ql.blink = b->ql.blink;
ReleaseMem(b); ReleaseMem(b);
// Nr of expansion block releases // Nr of expansion block releases
fNumprel++; fNumprel++;
// Total number of blocks // Total number of blocks
fNumpblk--; fNumpblk--;
assert(fNumpblk == fNumpget - fNumprel); assert(fNumpblk == fNumpget - fNumprel);
} }
} }
// Add a region of memory to the buffer pool.
//! Add a region of memory to the buffer pool.
void void
MemPool::AddToPool(void *buffer, ssize_t length) MemPool::AddToPool(void *buffer, ssize_t length)
{ {
@@ -518,7 +486,8 @@ MemPool::AddToPool(void *buffer, ssize_t length)
length -= sizeof(struct bhead); length -= sizeof(struct bhead);
b->bh.bsize = length; b->bh.bsize = length;
memset(((char *)b) + sizeof(struct bfhead), 0x55, (int)(length - sizeof(struct bfhead))); memset(((char *)b) + sizeof(struct bfhead), 0x55,
(int)(length - sizeof(struct bfhead)));
struct bhead *bn = BH(((char *) b) + length); struct bhead *bn = BH(((char *) b) + length);
bn->prevfree = length; bn->prevfree = length;
@@ -529,212 +498,185 @@ MemPool::AddToPool(void *buffer, ssize_t length)
} }
// Return buffer allocation free space statistics. //! Return buffer allocation free space statistics.
void void
MemPool::Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree, MemPool::Stats(ssize_t *curalloc, ssize_t *totfree, ssize_t *maxfree,
long *nget, long *nrel) long *nget, long *nrel)
{ {
struct bfhead *b = fFreeList.ql.flink; struct bfhead *b = fFreeList.ql.flink;
*nget = fGetCount; *nget = fGetCount;
*nrel = fReleaseCount; *nrel = fReleaseCount;
*curalloc = fTotalAlloced; *curalloc = fTotalAllocated;
*totfree = 0; *totfree = 0;
*maxfree = -1; *maxfree = -1;
while (b != &fFreeList)
{ while (b != &fFreeList) {
assert(b->bh.bsize > 0); assert(b->bh.bsize > 0);
*totfree += b->bh.bsize; *totfree += b->bh.bsize;
if (b->bh.bsize > *maxfree) if (b->bh.bsize > *maxfree)
{
*maxfree = b->bh.bsize; *maxfree = b->bh.bsize;
}
// Link to next buffer // Link to next buffer
b = b->ql.flink; b = b->ql.flink;
} }
} }
// Return extended statistics // !Return extended statistics
void void
MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget, long *nprel, MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget,
long *ndget, long *ndrel) long *nprel, long *ndget, long *ndrel)
{ {
*pool_incr = (fPoolLength < 0) ? -fExpIncr : fExpIncr; *pool_incr = (fPoolLength < 0) ? -fIncrementSize : fIncrementSize;
*npool = fNumpblk; *npool = fNumpblk;
*npget = fNumpget; *npget = fNumpget;
*nprel = fNumprel; *nprel = fNumprel;
*ndget = fNumdget; *ndget = fNumdget;
*ndrel = fNumdrel; *ndrel = fNumdrel;
} }
// Dump the data in a buffer. This is called with the user data pointer, /*!
// and backs up to the buffer header. It will dump either a free block Dump the data in a buffer. This is called with the user data pointer,
// or an allocated one. and backs up to the buffer header. It will dump either a free block
or an allocated one.
*/
void void
MemPool::BufferDump(void *buf) MemPool::BufferDump(void *buf)
{ {
struct bfhead *b; struct bfhead *b;
unsigned char *bdump; unsigned char *bdump;
ssize_t bdlen; ssize_t bdlen;
b = BFH(((char *) buf) - sizeof(struct bhead)); b = BFH(((char *) buf) - sizeof(struct bhead));
assert(b->bh.bsize != 0); assert(b->bh.bsize != 0);
if (b->bh.bsize < 0) if (b->bh.bsize < 0) {
{
bdump = (unsigned char *) buf; bdump = (unsigned char *) buf;
bdlen = (-b->bh.bsize) - sizeof(struct bhead); bdlen = (-b->bh.bsize) - sizeof(struct bhead);
} } else {
else
{
bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead)); bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));
bdlen = b->bh.bsize - sizeof(struct bfhead); bdlen = b->bh.bsize - sizeof(struct bfhead);
} }
while (bdlen > 0) while (bdlen > 0) {
{
int i, dupes = 0; int i, dupes = 0;
ssize_t l = bdlen; ssize_t l = bdlen;
char bhex[50], bascii[20]; char bhex[50], bascii[20];
if (l > 16) if (l > 16)
{ l = 16;
l = 16;
} for (i = 0; i < l; i++) {
sprintf(bhex + i * 3, "%02X ", bdump[i]);
for (i = 0; i < l; i++) bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
{
sprintf(bhex + i * 3, "%02X ", bdump[i]);
bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
} }
bascii[i] = 0; bascii[i] = 0;
printf("%-48s %s\n", bhex, bascii); printf("%-48s %s\n", bhex, bascii);
bdump += l; bdump += l;
bdlen -= l; bdlen -= l;
while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0)) while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0)) {
{ dupes++;
dupes++; bdump += 16;
bdump += 16; bdlen -= 16;
bdlen -= 16;
} }
if (dupes > 1) if (dupes > 1) {
{ printf(" (%d lines [%d bytes] identical to above line skipped)\n",
printf(" (%d lines [%d bytes] identical to above line skipped)\n", dupes, dupes * 16);
dupes, dupes * 16); } else {
} if (dupes == 1) {
else bdump -= 16;
{ bdlen += 16;
if (dupes == 1)
{
bdump -= 16;
bdlen += 16;
} }
} }
} }
} }
// Dump a buffer pool. The buffer headers are always listed. If DUMPALLOC is
// nonzero, the contents of allocated buffers are dumped. If DUMPFREE is /*!
// nonzero, free blocks are dumped as well. If FreeWipe checking is enabled, Dump a buffer pool. The buffer headers are always listed. If DUMPALLOC is
// free blocks which have been clobbered will always be dumped. nonzero, the contents of allocated buffers are dumped. If DUMPFREE is
nonzero, free blocks are dumped as well. If FreeWipe checking is enabled,
free blocks which have been clobbered will always be dumped.
*/
void void
MemPool::PoolDump(void *buf, bool dumpalloc, bool dumpfree) MemPool::PoolDump(void *buf, bool dumpalloc, bool dumpfree)
{ {
struct bfhead *b = BFH(buf); struct bfhead *b = BFH(buf);
while (b->bh.bsize != ESent) while (b->bh.bsize != ESent) {
{
ssize_t bs = b->bh.bsize; ssize_t bs = b->bh.bsize;
if (bs < 0) if (bs < 0) {
{ bs = -bs;
bs = -bs; printf("Allocated buffer: size %6ld bytes.\n", (long) bs);
printf("Allocated buffer: size %6ld bytes.\n", (long) bs); if (dumpalloc)
if (dumpalloc)
{
BufferDump((void *) (((char *) b) + sizeof(struct bhead))); BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
} } else {
}
else
{
char *lerr = ""; char *lerr = "";
assert(bs > 0); assert(bs > 0);
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b)) if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
{ lerr = " (Bad free list links)";
lerr = " (Bad free list links)";
} printf("Free block: size %6ld bytes.%s\n",
printf("Free block: size %6ld bytes.%s\n", (long) bs, lerr);
(long) bs, lerr);
lerr = ((char *) b) + sizeof(struct bfhead);
lerr = ((char *) b) + sizeof(struct bfhead); if (bs > (ssize_t)sizeof(struct bfhead)
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) || && (*lerr != 0x55
(memcmp(lerr, lerr + 1, (int) (bs - (sizeof(struct bfhead) + 1))) != 0))) || memcmp(lerr, lerr + 1, (int)(bs - (sizeof(struct bfhead) + 1))) != 0)) {
{
printf("(Contents of above free block have been overstored.)\n"); printf("(Contents of above free block have been overstored.)\n");
BufferDump((void *) (((char *) b) + sizeof(struct bhead))); BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
} } else {
else if (dumpfree)
{
if (dumpfree)
{
BufferDump((void *) (((char *) b) + sizeof(struct bhead))); BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
} }
}
} }
b = BFH(((char *) b) + bs); b = BFH(((char *) b) + bs);
} }
} }
// Validate a buffer pool.
//! Validate a buffer pool.
int int
MemPool::Validate(void *buf) MemPool::Validate(void *buf)
{ {
struct bfhead *b = BFH(buf); struct bfhead *b = BFH(buf);
while (b->bh.bsize != ESent) while (b->bh.bsize != ESent) {
{
ssize_t bs = b->bh.bsize; ssize_t bs = b->bh.bsize;
if (bs < 0) if (bs < 0)
{ bs = -bs;
bs = -bs; else {
} char *lerr = "";
else
{ assert(bs > 0);
char *lerr = ""; if (bs <= 0)
assert(bs > 0);
if (bs <= 0)
{
return 0; return 0;
}
if (b->ql.blink->ql.flink != b || b->ql.flink->ql.blink != b) {
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b)) printf("Free block: size %6ld bytes. (Bad free list links)\n",
{ (long) bs);
printf("Free block: size %6ld bytes. (Bad free list links)\n",
(long) bs);
assert(0); assert(0);
return 0; return 0;
} }
lerr = ((char *) b) + sizeof(struct bfhead); lerr = ((char *) b) + sizeof(struct bfhead);
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) || if (bs > (ssize_t)sizeof(struct bfhead)
(memcmp(lerr, lerr + 1,(int) (bs - (sizeof(struct bfhead) + 1))) != 0))) && (*lerr != 0x55
{ || memcmp(lerr, lerr + 1, (int)(bs - (sizeof(struct bfhead) + 1))) != 0)) {
printf("(Contents of above free block have been overstored.)\n"); printf("(Contents of above free block have been overstored.)\n");
BufferDump((void *) (((char *) b) + sizeof(struct bhead))); BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
assert(0); assert(0);
return 0; return 0;
} }
} }
b = BFH(((char *) b) + bs); b = BFH(((char *) b) + bs);
} }
return 1; return 1;
} }
@@ -763,7 +705,7 @@ MemPool::ReleaseMem(void *buffer)
AreaPool::AreaPool(const char* name, size_t initialSize) AreaPool::AreaPool(const char* name, size_t initialSize)
: : MemPool(initialSize),
fName(name) fName(name)
{ {
if (initialSize > 0) if (initialSize > 0)
+74 -76
View File
@@ -6,95 +6,93 @@
* John Walker <[email protected]> * John Walker <[email protected]>
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Stephan Aßmus <[email protected]> * Stephan Aßmus <[email protected]>
*
* BGET pool allocator
*/ */
#ifndef MEM_POOL_H #ifndef MEM_POOL_H
#define MEM_POOL_H #define MEM_POOL_H
#include <SupportDefs.h> #include <SupportDefs.h>
class MemPool { class MemPool {
public: public:
MemPool(); MemPool(int32 incrementSize);
virtual ~MemPool(); virtual ~MemPool();
void AddToPool(void* buffer, ssize_t len); void AddToPool(void* buffer, ssize_t len);
void* GetBuffer(ssize_t size, bool zero = false); void* GetBuffer(ssize_t size, bool zero = false);
void* ReallocateBuffer(void* buffer, ssize_t size); void* ReallocateBuffer(void* buffer, ssize_t size);
void ReleaseBuffer(void* buffer); void ReleaseBuffer(void* buffer);
virtual int* CompactMem(ssize_t sizereq, int sequence);
virtual void* AcquireMem(ssize_t size);
virtual void ReleaseMem(void* buffer);
void SetPoolIncrement(ssize_t increment);
ssize_t PoolIncrement();
// debugging
void Stats(ssize_t* curalloc, ssize_t* totfree,
ssize_t* maxfree, long* nget, long* nrel);
void ExtendedStats(ssize_t* pool_incr, long* npool,
long* npget, long* nprel,
long* ndget, long* ndrel);
void BufferDump(void* buf);
void PoolDump(void* pool, bool dumpalloc,
bool dumpfree);
int Validate(void* buffer);
private:
// Header in allocated and free buffers
struct bhead {
// Relative link back to previous free buffer in memory or 0 if previous
// buffer is allocated.
ssize_t prevfree;
// Buffer size: positive if free, negative if allocated.
ssize_t bsize;
};
virtual int* CompactMem(ssize_t sizereq, int sequence); // Header in directly allocated buffers (by acqfcn)
virtual void* AcquireMem(ssize_t size); struct bdhead {
virtual void ReleaseMem(void* buffer); ssize_t tsize; // Total size, including overhead
bhead bh; // Common header
};
// Queue links
struct bfhead;
struct qlinks {
bfhead *flink; // Forward link
bfhead *blink; // Backward link
};
// Header in free buffers
struct bfhead {
// Common allocated/free header
bhead bh;
// Links on free list
qlinks ql;
};
void SetPoolIncrement(ssize_t increment); ssize_t fTotalAllocated;
ssize_t PoolIncrement(); long fGetCount;
long fReleaseCount;
// debugging long fNumpblk;
void Stats(ssize_t* curalloc, ssize_t* totfree, long fNumpget;
ssize_t* maxfree, long* nget, long* nrel); long fNumprel;
long fNumdget;
void ExtendedStats(ssize_t* pool_incr, long* npool, long fNumdrel;
long* npget, long* nprel, ssize_t fIncrementSize;
long* ndget, long* ndrel); ssize_t fPoolLength;
// List of free buffers
void BufferDump(void* buf); bfhead fFreeList;
void PoolDump(void* pool, bool dumpalloc,
bool dumpfree);
int Validate(void* buffer);
private:
// Header in allocated and free buffers
struct bhead {
// Relative link back to previous free buffer in memory or 0 if previous
// buffer is allocated.
ssize_t prevfree;
// Buffer size: positive if free, negative if allocated.
ssize_t bsize;
};
// Header in directly allocated buffers (by acqfcn)
struct bdhead {
ssize_t tsize; // Total size, including overhead
bhead bh; // Common header
};
// Queue links
struct bfhead;
struct qlinks {
bfhead *flink; // Forward link
bfhead *blink; // Backward link
};
// Header in free buffers
struct bfhead {
// Common allocated/free header
bhead bh;
// Links on free list
qlinks ql;
};
ssize_t fTotalAlloced;
long fGetCount;
long fReleaseCount;
long fNumpblk;
long fNumpget;
long fNumprel;
long fNumdget;
long fNumdrel;
ssize_t fExpIncr;
ssize_t fPoolLength;
// List of free buffers
bfhead fFreeList;
}; };
class AreaPool : public MemPool { class AreaPool : public MemPool {
public: public:
AreaPool(const char* name, size_t initialSize = 0); AreaPool(const char* name, size_t initialSize);
virtual ~AreaPool(); virtual ~AreaPool();
virtual void* AcquireMem(ssize_t size); virtual void* AcquireMem(ssize_t size);
@@ -104,4 +102,4 @@ class AreaPool : public MemPool {
const char* fName; const char* fName;
}; };
#endif #endif /* MEM_POOL_H */
+1 -1
View File
@@ -32,7 +32,7 @@ using std::nothrow;
BitmapManager *gBitmapManager = NULL; BitmapManager *gBitmapManager = NULL;
//! Number of bytes to allocate to each area used for bitmap storage //! Number of bytes to allocate to each area used for bitmap storage
#define BITMAP_AREA_SIZE B_PAGE_SIZE * 2 #define BITMAP_AREA_SIZE B_PAGE_SIZE * 16
//! Sets up stuff to be ready to allocate space for bitmaps //! Sets up stuff to be ready to allocate space for bitmaps
+1 -1
View File
@@ -7,7 +7,7 @@
* *
*/ */
#include "RootLayer.h" //#include "RootLayer.h"
#include "DebugInfoManager.h" #include "DebugInfoManager.h"
+2 -2
View File
@@ -288,8 +288,8 @@ Decorator::GetZoom()
// GetSizeLimits // GetSizeLimits
void void
Decorator::GetSizeLimits(float* minWidth, float* minHeight, Decorator::GetSizeLimits(int32* minWidth, int32* minHeight,
float* maxWidth, float* maxHeight) const int32* maxWidth, int32* maxHeight) const
{ {
} }
+15 -17
View File
@@ -184,13 +184,13 @@ DefaultDecorator::MoveBy(BPoint pt)
void void
DefaultDecorator::ResizeBy(float x, float y) DefaultDecorator::ResizeBy(float x, float y)
{ {
ResizeBy(BPoint(x,y)); ResizeBy(BPoint(x, y));
} }
void void
DefaultDecorator::ResizeBy(BPoint pt) DefaultDecorator::ResizeBy(BPoint pt)
{ {
STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n",pt.x,pt.y)); STRACE(("DefaultDecorator: Resize By (%.1f, %.1f)\n", pt.x, pt.y));
// Move all internal rectangles the appropriate amount // Move all internal rectangles the appropriate amount
_frame.right += pt.x; _frame.right += pt.x;
_frame.bottom += pt.y; _frame.bottom += pt.y;
@@ -250,13 +250,13 @@ DefaultDecorator::Draw()
// GetSizeLimits // GetSizeLimits
void void
DefaultDecorator::GetSizeLimits(float* minWidth, float* minHeight, DefaultDecorator::GetSizeLimits(int32* minWidth, int32* minHeight,
float* maxWidth, float* maxHeight) const int32* maxWidth, int32* maxHeight) const
{ {
if (_tabrect.IsValid()) if (_tabrect.IsValid())
*minWidth = max_c(*minWidth, fMinTabWidth - 2 * fBorderWidth); *minWidth = (int32)roundf(max_c(*minWidth, fMinTabWidth - 2 * fBorderWidth));
if (_resizerect.IsValid()) if (_resizerect.IsValid())
*minHeight = max_c(*minHeight, _resizerect.Height() - fBorderWidth); *minHeight = (int32)roundf(max_c(*minHeight, _resizerect.Height() - fBorderWidth));
} }
// GetFootprint // GetFootprint
@@ -309,7 +309,7 @@ DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
if (!(fFlags & B_NOT_ZOOMABLE) && _zoomrect.Contains(pt)) if (!(fFlags & B_NOT_ZOOMABLE) && _zoomrect.Contains(pt))
return DEC_ZOOM; return DEC_ZOOM;
if (fLook == B_DOCUMENT_WINDOW_LOOK && _resizerect.Contains(pt)) if (fLook == B_DOCUMENT_WINDOW_LOOK && _resizerect.Contains(pt))
return DEC_RESIZE; return DEC_RESIZE;
@@ -466,7 +466,7 @@ DefaultDecorator::_DoLayout()
// calculate resize rect // calculate resize rect
_resizerect.Set(fBottomBorder.right - 18.0, fBottomBorder.bottom - 18.0, _resizerect.Set(fBottomBorder.right - 18.0, fBottomBorder.bottom - 18.0,
fBottomBorder.right - 3, fBottomBorder.bottom - 3); fBottomBorder.right, fBottomBorder.bottom);
} }
// _DrawFrame // _DrawFrame
@@ -559,17 +559,15 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top,
// Draw the resize thumb if we're supposed to // Draw the resize thumb if we're supposed to
if (!(fFlags & B_NOT_RESIZABLE)) { if (!(fFlags & B_NOT_RESIZABLE)) {
r = _resizerect; r = _resizerect;
switch (fLook){ switch (fLook){
case B_DOCUMENT_WINDOW_LOOK: { case B_DOCUMENT_WINDOW_LOOK: {
// Explicitly locking the driver is normally unnecessary. However, we
// Explicitly locking the driver is normally unnecessary. However, we need to do // need to do this because we are rapidly drawing a series of calls
// this because we are rapidly drawing a series of calls which would not necessarily // which would not necessarily draw correctly if we didn't do so.
// draw correctly if we didn't do so. float x = r.right - 3;
float x = r.right; float y = r.bottom - 3;
float y = r.bottom;
_driver->Lock(); _driver->Lock();
_driver->FillRect(BRect(x-13, y-13, x, y), fFrameColors[2]); _driver->FillRect(BRect(x-13, y-13, x, y), fFrameColors[2]);
_driver->StrokeLine(BPoint(x-15, y-15), BPoint(x-15, y-2), fFrameColors[0]); _driver->StrokeLine(BPoint(x-15, y-15), BPoint(x-15, y-2), fFrameColors[0]);
@@ -600,7 +598,7 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top,
fFrameColors[0]); fFrameColors[0]);
break; break;
} }
default: { default: {
// don't draw resize corner // don't draw resize corner
break; break;
@@ -715,7 +713,7 @@ DefaultDecorator::_SetFocus()
// SetFocus() performs necessary duties for color swapping and // SetFocus() performs necessary duties for color swapping and
// other things when a window is deactivated or activated. // other things when a window is deactivated or activated.
if (GetFocus()) { if (IsFocus()) {
fButtonHighColor.SetColor(tint_color(_colors->window_tab,B_LIGHTEN_2_TINT)); fButtonHighColor.SetColor(tint_color(_colors->window_tab,B_LIGHTEN_2_TINT));
fButtonLowColor.SetColor(tint_color(_colors->window_tab,B_DARKEN_1_TINT)); fButtonLowColor.SetColor(tint_color(_colors->window_tab,B_DARKEN_1_TINT));
fTextColor = _colors->window_tab_text; fTextColor = _colors->window_tab_text;
+2 -2
View File
@@ -35,8 +35,8 @@ public:
virtual void Draw(BRect r); virtual void Draw(BRect r);
virtual void Draw(); virtual void Draw();
virtual void GetSizeLimits(float* minWidth, float* minHeight, virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
float* maxWidth, float* maxHeight) const; int32* maxWidth, int32* maxHeight) const;
virtual void GetFootprint(BRegion *region); virtual void GetFootprint(BRegion *region);
File diff suppressed because it is too large Load Diff
+82 -14
View File
@@ -18,31 +18,37 @@
#include "VirtualScreen.h" #include "VirtualScreen.h"
#include "DesktopSettings.h" #include "DesktopSettings.h"
#include "MessageLooper.h" #include "MessageLooper.h"
#include "WindowList.h"
#include "Workspace.h" #include "Workspace.h"
#include "WorkspacePrivate.h" #include "WorkspacePrivate.h"
#include <ObjectList.h>
#include <Autolock.h>
#include <InterfaceDefs.h> #include <InterfaceDefs.h>
#include <List.h> #include <List.h>
#include <Locker.h>
#include <Menu.h> #include <Menu.h>
#include <Autolock.h> #include <Region.h>
#include <ObjectList.h>
#include <Window.h> #include <Window.h>
#define USE_MULTI_LOCKER 0
#if USE_MULTI_LOCKER
# include "MultiLocker.h"
#else
# include <Locker.h>
#endif
class BMessage; class BMessage;
class DrawingEngine; class DrawingEngine;
class HWInterface; class HWInterface;
class Layer; class ServerApp;
class RootLayer;
class WindowLayer;
namespace BPrivate { namespace BPrivate {
class LinkSender; class LinkSender;
}; };
class Desktop : public MessageLooper, public ScreenOwner { class Desktop : public MessageLooper, public ScreenOwner {
public: public:
Desktop(uid_t userID); Desktop(uid_t userID);
@@ -63,7 +69,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
{ return fActiveScreen; } { return fActiveScreen; }
Screen* ActiveScreen() const Screen* ActiveScreen() const
{ return fActiveScreen; } { return fActiveScreen; }
::RootLayer* RootLayer() const { return fRootLayer; }
CursorManager& GetCursorManager() { return fCursorManager; } CursorManager& GetCursorManager() { return fCursorManager; }
void ScreenChanged(Screen* screen); void ScreenChanged(Screen* screen);
@@ -85,11 +91,13 @@ class Desktop : public MessageLooper, public ScreenOwner {
{ return fCurrentWorkspace; } { return fCurrentWorkspace; }
Workspace::Private& WorkspaceAt(int32 index) Workspace::Private& WorkspaceAt(int32 index)
{ return fWorkspaces[index]; } { return fWorkspaces[index]; }
void UpdateWorkspaces();
// WindowLayer methods // WindowLayer methods
void ActivateWindow(WindowLayer* window); void ActivateWindow(WindowLayer* window);
void SendBehindWindow(WindowLayer* window, WindowLayer* front); void SendWindowBehind(WindowLayer* window,
WindowLayer* behindOf = NULL);
void ShowWindow(WindowLayer* window); void ShowWindow(WindowLayer* window);
void HideWindow(WindowLayer* window); void HideWindow(WindowLayer* window);
@@ -107,11 +115,38 @@ class Desktop : public MessageLooper, public ScreenOwner {
void SetWindowFeel(WindowLayer* window, window_feel feel); void SetWindowFeel(WindowLayer* window, window_feel feel);
void SetWindowFlags(WindowLayer* window, uint32 flags); void SetWindowFlags(WindowLayer* window, uint32 flags);
WindowLayer* FocusWindow() const { return fFocus; }
WindowLayer* FrontWindow() const { return fFront; }
WindowLayer* BackWindow() const { return fBack; }
WindowLayer* WindowAt(BPoint where);
WindowLayer* MouseEventWindow() const { return fMouseEventWindow; }
void SetMouseEventWindow(WindowLayer* window);
void SetFocusWindow(WindowLayer* window);
WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID); WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID);
//WindowLayer* FindWindowLayerByServerToken(int32 token); //WindowLayer* FindWindowLayerByServerToken(int32 token);
// get list of registed windows #if USE_MULTI_LOCKER
const BObjectList<WindowLayer>& WindowList() const; bool ReadLockWindows() { return fWindowLock.ReadLock(); }
void ReadUnlockWindows() { fWindowLock.ReadUnlock(); }
bool WriteLockWindows() { return fWindowLock.WriteLock(); }
void WriteUnlockWindows() { fWindowLock.WriteUnlock(); }
#else // USE_MULTI_LOCKER
bool ReadLockWindows() { return fWindowLock.Lock(); }
void ReadUnlockWindows() { fWindowLock.Unlock(); }
bool WriteLockWindows() { return fWindowLock.Lock(); }
void WriteUnlockWindows() { fWindowLock.Unlock(); }
#endif // USE_MULTI_LOCKER
void MarkDirty(BRegion& region);
BRegion& BackgroundRegion()
{ return fBackgroundRegion; }
void WriteWindowList(team_id team, void WriteWindowList(team_id team,
BPrivate::LinkSender& sender); BPrivate::LinkSender& sender);
@@ -119,14 +154,31 @@ class Desktop : public MessageLooper, public ScreenOwner {
BPrivate::LinkSender& sender); BPrivate::LinkSender& sender);
private: private:
void _ShowWindow(WindowLayer* window,
bool affectsOtherWindows = true);
void _HideWindow(WindowLayer* window);
void _ChangeWindowWorkspaces(WindowLayer* window, void _ChangeWindowWorkspaces(WindowLayer* window,
uint32 oldWorkspaces, uint32 newWorkspaces); uint32 oldWorkspaces, uint32 newWorkspaces);
void _BringWindowsToFront(WindowList& windows,
int32 list, bool wereVisible);
status_t _ActivateApp(team_id team); status_t _ActivateApp(team_id team);
void _RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen);
void _TriggerWindowRedrawing(BRegion& newDirtyRegion);
void _SetBackground(BRegion& background);
void _UpdateBack();
void _UpdateFront();
void _UpdateFronts();
void _GetLooperName(char* name, size_t size); void _GetLooperName(char* name, size_t size);
void _PrepareQuit(); void _PrepareQuit();
void _DispatchMessage(int32 code, void _DispatchMessage(int32 code,
BPrivate::LinkReceiver &link); BPrivate::LinkReceiver &link);
WindowList& _CurrentWindows();
private: private:
friend class DesktopSettings; friend class DesktopSettings;
@@ -137,8 +189,8 @@ class Desktop : public MessageLooper, public ScreenOwner {
::EventDispatcher fEventDispatcher; ::EventDispatcher fEventDispatcher;
port_id fInputPort; port_id fInputPort;
BLocker fAppListLock; BLocker fApplicationsLock;
BList fAppList; BObjectList<ServerApp> fApplications;
sem_id fShutdownSemaphore; sem_id fShutdownSemaphore;
int32 fShutdownCount; int32 fShutdownCount;
@@ -146,12 +198,28 @@ class Desktop : public MessageLooper, public ScreenOwner {
::Workspace::Private fWorkspaces[32]; ::Workspace::Private fWorkspaces[32];
int32 fCurrentWorkspace; int32 fCurrentWorkspace;
BObjectList<WindowLayer> fWindowLayerList; WindowList fAllWindows;
::RootLayer* fRootLayer; ::RootLayer* fRootLayer;
Screen* fActiveScreen; Screen* fActiveScreen;
CursorManager fCursorManager; CursorManager fCursorManager;
#if USE_MULTI_LOCKER
MultiLocker fWindowLock;
#else
BLocker fWindowLock;
#endif
BRegion fBackgroundRegion;
BRegion fScreenRegion;
bool fFocusFollowsMouse;
WindowLayer* fMouseEventWindow;
WindowLayer* fFocus;
WindowLayer* fFront;
WindowLayer* fBack;
}; };
#endif // DESKTOP_H #endif // DESKTOP_H
+52 -3
View File
@@ -15,7 +15,6 @@
#include <TokenSpace.h> #include <TokenSpace.h>
#include <Autolock.h> #include <Autolock.h>
#include <MessageFilter.h>
#include <View.h> #include <View.h>
#include <new> #include <new>
@@ -470,7 +469,14 @@ EventDispatcher::SendFakeMouseMoved(EventTarget& target, int32 viewToken)
moved.AddPoint("screen_where", fLastCursorPosition); moved.AddPoint("screen_where", fLastCursorPosition);
moved.AddInt32("buttons", fLastButtons); moved.AddInt32("buttons", fLastButtons);
moved.AddInt32("_view_token", viewToken); moved.AddInt32("_view_token", viewToken);
if (fDraggingMessage) {
/* moved.AddInt32("_msg_data", );
moved.AddInt32("_msg_base_", );
moved.AddInt32("_msg_what_", fDragMessage->what);*/
moved.AddMessage("be:drag_message", &fDragMessage);
}
_SendMessage(target.Messenger(), &moved, kMouseTransitImportance); _SendMessage(target.Messenger(), &moved, kMouseTransitImportance);
} }
@@ -495,6 +501,18 @@ EventDispatcher::SetHWInterface(HWInterface* interface)
} }
void
EventDispatcher::SetDragMessage(BMessage& message)
{
printf("EventDispatcher::SetDragMessage()\n");
BAutolock _(*this);
fDragMessage = message;
fDraggingMessage = true;
}
// #pragma mark - Message methods // #pragma mark - Message methods
@@ -575,6 +593,28 @@ EventDispatcher::_UnsetFeedFocus(BMessage* message)
} }
void
EventDispatcher::_DeliverDragMessage()
{
printf("EventDispatcher::_DeliverDragMessage()\n");
if (fDraggingMessage && fPreviousMouseTarget) {
fDragMessage.RemoveName("_original_what");
fDragMessage.AddInt32("_original_what", fDragMessage.what);
fDragMessage.what = _MESSAGE_DROPPED_;
// fDragMessage.AddBool("dropped", true);
printf(" sending message to previous mouse target\n");
_SendMessage(fPreviousMouseTarget->Messenger(),
&fDragMessage, 100.0);
}
fDragMessage.MakeEmpty();
fDragMessage.what = 0;
fDraggingMessage = false;
}
// #pragma mark - Event loops // #pragma mark - Event loops
@@ -604,6 +644,13 @@ EventDispatcher::_EventLoop()
if (event->FindPoint("where", &where) == B_OK) if (event->FindPoint("where", &where) == B_OK)
fLastCursorPosition = where; fLastCursorPosition = where;
if (fDraggingMessage) {
/* event->AddInt32("_msg_data", );
event->AddInt32("_msg_base_", );
event->AddInt32("_msg_what_", fDragMessage->what);*/
event->AddMessage("be:drag_message", &fDragMessage);
}
if (!HasCursorThread()) { if (!HasCursorThread()) {
// there is no cursor thread, we need to move the cursor ourselves // there is no cursor thread, we need to move the cursor ourselves
BAutolock _(fCursorLock); BAutolock _(fCursorLock);
@@ -717,7 +764,7 @@ EventDispatcher::_EventLoop()
_UnsetFeedFocus(event); _UnsetFeedFocus(event);
} }
if (pointerEvent) { if (pointerEvent) {
// this is added in the RootLayer mouse processing // this is added in the Desktop mouse processing
// but it's only intended for the focus view // but it's only intended for the focus view
event->RemoveName("_view_token"); event->RemoveName("_view_token");
} }
@@ -744,6 +791,8 @@ EventDispatcher::_EventLoop()
if (event->what == B_MOUSE_UP) { if (event->what == B_MOUSE_UP) {
fSuspendFocus = false; fSuspendFocus = false;
_RemoveTemporaryListeners(); _RemoveTemporaryListeners();
if (fDraggingMessage)
_DeliverDragMessage();
} }
} }
+12
View File
@@ -10,6 +10,7 @@
#include <Locker.h> #include <Locker.h>
#include <Message.h>
#include <MessageFilter.h> #include <MessageFilter.h>
#include <Messenger.h> #include <Messenger.h>
#include <ObjectList.h> #include <ObjectList.h>
@@ -83,6 +84,12 @@ class EventDispatcher : public BLocker {
bool HasCursorThread(); bool HasCursorThread();
void SetHWInterface(HWInterface* interface); void SetHWInterface(HWInterface* interface);
void SetDragMessage(BMessage& message);
// the message should be delivered on the next
// "mouse up".
// if the mouse is not pressed, it should
// be delivered to the "current" target right away.
private: private:
status_t _Run(); status_t _Run();
void _Unset(); void _Unset();
@@ -101,6 +108,8 @@ class EventDispatcher : public BLocker {
uint32 eventMask, uint32 options, bool temporary); uint32 eventMask, uint32 options, bool temporary);
void _RemoveTemporaryListeners(); void _RemoveTemporaryListeners();
void _DeliverDragMessage();
void _EventLoop(); void _EventLoop();
void _CursorLoop(); void _CursorLoop();
@@ -124,6 +133,9 @@ class EventDispatcher : public BLocker {
BPoint fLastCursorPosition; BPoint fLastCursorPosition;
int32 fLastButtons; int32 fLastButtons;
BMessage fDragMessage;
bool fDraggingMessage;
BLocker fCursorLock; BLocker fCursorLock;
HWInterface* fHWInterface; HWInterface* fHWInterface;
}; };
+2 -3
View File
@@ -31,7 +31,6 @@ Server app_server :
FontManager.cpp FontManager.cpp
HashTable.cpp HashTable.cpp
InputManager.cpp InputManager.cpp
Layer.cpp
MessageLooper.cpp MessageLooper.cpp
MultiLocker.cpp MultiLocker.cpp
OffscreenServerWindow.cpp OffscreenServerWindow.cpp
@@ -40,7 +39,6 @@ Server app_server :
PicturePlayer.cpp PicturePlayer.cpp
RAMLinkMsgReader.cpp RAMLinkMsgReader.cpp
RGBColor.cpp RGBColor.cpp
RootLayer.cpp
ScreenManager.cpp ScreenManager.cpp
ServerApp.cpp ServerApp.cpp
ServerBitmap.cpp ServerBitmap.cpp
@@ -49,10 +47,11 @@ Server app_server :
ServerPicture.cpp ServerPicture.cpp
ServerScreen.cpp ServerScreen.cpp
ServerWindow.cpp ServerWindow.cpp
SubWindowList.cpp
SystemPalette.cpp SystemPalette.cpp
ViewLayer.cpp
VirtualScreen.cpp VirtualScreen.cpp
WindowLayer.cpp WindowLayer.cpp
WindowList.cpp
Workspace.cpp Workspace.cpp
WorkspacesLayer.cpp WorkspacesLayer.cpp
File diff suppressed because it is too large Load Diff
-267
View File
@@ -1,267 +0,0 @@
/*
* Copyright (c) 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef _LAYER_H_
#define _LAYER_H_
#include "RGBColor.h"
#include "ServerWindow.h"
#include <GraphicsDefs.h>
#include <List.h>
#include <Locker.h>
#include <OS.h>
#include <String.h>
#include <Rect.h>
#include <Region.h>
enum {
B_LAYER_NONE = 1,
B_LAYER_MOVE = 2,
B_LAYER_SIMPLE_MOVE = 3,
B_LAYER_RESIZE = 4,
B_LAYER_MASK_RESIZE = 5,
};
enum {
B_LAYER_ACTION_NONE = 0,
B_LAYER_ACTION_MOVE,
B_LAYER_ACTION_RESIZE
};
class ServerApp;
class RootLayer;
class DrawingEngine;
class DrawState;
class ServerBitmap;
class PointerEvent {
public:
int32 code; // B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED,
// B_MOUSE_WHEEL_CHANGED
bigtime_t when;
BPoint where;
float wheel_delta_x;
float wheel_delta_y;
int32 modifiers;
int32 buttons; // B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
// B_TERTIARY_MOUSE_BUTTON
int32 clicks;
};
class Layer {
public:
Layer(BRect frame, const char* name,
int32 token, uint32 resize,
uint32 flags, DrawingEngine* driver);
virtual ~Layer();
// name
virtual void SetName(const char* name);
inline const char* Name() const
{ return fName.String(); }
int32 ViewToken() const { return fViewToken; }
// children handling
void AddChild(Layer* child, ServerWindow* serverWin);
void RemoveChild(Layer* child);
void RemoveSelf();
bool HasChild(Layer* layer);
Layer* Parent() const
{ return fParent; }
uint32 CountChildren() const;
Layer* LayerAt(BPoint where);
Layer* FirstChild() const;
Layer* LastChild() const;
Layer* NextLayer() const;
Layer* PreviousLayer() const;
void SetAsTopLayer(bool option)
{ fIsTopLayer = option; }
inline bool IsTopLayer() const
{ return fIsTopLayer; }
// visible state
void Show(bool invalidate = true);
void Hide(bool invalidate = true);
bool IsHidden() const;
bool IsVisuallyHidden() const;
// graphic state and attributes
void PushState();
void PopState();
DrawState* CurrentState() const { return fDrawState; }
void SetViewColor(const RGBColor& color);
inline const RGBColor& ViewColor() const
{ return fViewColor; }
void SetBackgroundBitmap(const ServerBitmap* bitmap);
inline const ServerBitmap* BackgroundBitmap() const
{ return fBackgroundBitmap; }
void SetOverlayBitmap(const ServerBitmap* bitmap);
inline const ServerBitmap* OverlayBitmap() const
{ return fOverlayBitmap; }
// coordinate system
BRect Bounds() const;
BRect Frame() const;
BPoint ScrollingOffset() const;
void SetDrawingOrigin(BPoint origin);
BPoint DrawingOrigin() const;
void SetScale(float scale);
float Scale() const;
void ConvertToParent(BPoint* pt) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(BRegion* reg) const;
void ConvertFromParent(BPoint* pt) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(BRegion* reg) const;
void ConvertToScreen(BPoint* pt) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(BRegion* reg) const;
void ConvertFromScreen(BPoint* pt) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(BRegion* reg) const;
void ConvertToScreenForDrawing(BPoint* pt) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* reg) const;
void ConvertFromScreenForDrawing(BPoint* pt) const;
virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y);
virtual void ScrollBy(float x, float y);
void CopyBits(BRect& src, BRect& dst,
int32 xOffset, int32 yOffset);
// input handling
virtual void MouseDown(BMessage *msg, BPoint where, int32* _viewToken);
virtual void MouseUp(BMessage *msg, BPoint where, int32* _viewToken);
virtual void MouseMoved(BMessage *msg, BPoint where, int32* _viewToken);
virtual void WorkspaceActivated(int32 index, bool active);
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
virtual void Activated(bool active);
// action hooks
virtual void MovedByHook(float dx, float dy);
virtual void ResizedByHook(float dx, float dy, bool automatic);
virtual void ScrolledByHook(float dx, float dy);
// app_server objects getters
ServerWindow* Window() const
{ return fWindow; }
ServerApp* App() const
{ return fWindow ? fWindow->App() : NULL; }
RootLayer* GetRootLayer() const
{ return fRootLayer; }
void SetRootLayer(RootLayer* rl)
{ fRootLayer = rl; }
DrawingEngine* GetDrawingEngine() const
{ return fDriver; }
void SetEventMask(uint32 eventMask, uint32 options);
uint32 EventMask() const
{ return fEventMask; }
uint32 EventOptions() const
{ return fEventOptions; }
inline uint32 ResizeMode() const
{ return fResizeMode; }
inline uint32 Flags() const
{ return fFlags; }
void SetFlags(uint32 flags);
// clipping stuff and redraw
void SetUserClipping(const BRegion& region);
// region is expected in layer coordinates
inline const BRegion& VisibleRegion() const { return fVisible; }
inline const BRegion& FullVisible() const { return fFullVisible; }
inline const BRegion& DrawingRegion() const { return fDrawingRegion; }
virtual void GetOnScreenRegion(BRegion& region);
void MarkForRebuild(const BRegion &dirty);
void TriggerRebuild();
void _GetAllRebuildDirty(BRegion *totalReg);
virtual void Draw(const BRect& updateRect);
virtual void _AllRedraw(const BRegion& invalid);
protected:
friend class RootLayer;
friend class ServerWindow;
bool _AddChildToList(Layer* child, Layer* before = NULL);
void _RemoveChildFromList(Layer* child);
// private clipping stuff
virtual void _ReserveRegions(BRegion &reg);
void _RebuildVisibleRegions( const BRegion &invalid,
const BRegion &parentLocalVisible,
const Layer *startFrom);
void _RebuildDrawingRegion();
void _ClearVisibleRegions();
void _ResizeLayerFrameBy(float x, float y);
void _RezizeLayerRedrawMore(BRegion &reg, float dx, float dy);
void _ResizeLayerFullUpdateOnResize(BRegion &reg, float dx, float dy);
// for updating client-side coordinates
void _AddToViewsWithInvalidCoords() const;
void _SendViewCoordUpdateMsg() const;
BString fName;
BRect fFrame;
BPoint fScrollingOffset;
BRegion fVisible;
BRegion fFullVisible;
BRegion fDirtyForRebuild;
BRegion fDrawingRegion;
DrawingEngine* fDriver;
RootLayer* fRootLayer;
ServerWindow* fWindow;
DrawState* fDrawState;
Layer* fParent;
Layer* fPreviousSibling;
Layer* fNextSibling;
Layer* fFirstChild;
Layer* fLastChild;
int32 fViewToken;
uint32 fFlags;
uint32 fResizeMode;
uint32 fEventMask;
uint32 fEventOptions;
bool fHidden;
bool fIsTopLayer;
RGBColor fViewColor;
const ServerBitmap* fBackgroundBitmap;
const ServerBitmap* fOverlayBitmap;
};
#endif // _LAYER_H_
+7 -1
View File
@@ -19,7 +19,7 @@
OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap, OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
const char* name, ServerWindow* window) const char* name, ::ServerWindow* window)
: WindowLayer(bitmap->Bounds(), name, : WindowLayer(bitmap->Bounds(), name,
B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
0, 0, window, new DrawingEngine()), 0, 0, window, new DrawingEngine()),
@@ -29,6 +29,12 @@ OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
GetDrawingEngine()->SetHWInterface(fHWInterface); GetDrawingEngine()->SetHWInterface(fHWInterface);
GetDrawingEngine()->Initialize(); GetDrawingEngine()->Initialize();
GetDrawingEngine()->Update(); GetDrawingEngine()->Update();
fVisibleRegion.Set(fFrame);
fVisibleContentRegion.Set(fFrame);
fVisibleContentRegionValid = true;
fContentRegion.Set(fFrame);
fContentRegionValid = true;
} }
+1 -1
View File
@@ -19,7 +19,7 @@ class OffscreenWindowLayer : public WindowLayer {
public: public:
OffscreenWindowLayer(ServerBitmap* bitmap, OffscreenWindowLayer(ServerBitmap* bitmap,
const char* name, const char* name,
ServerWindow* window); ::ServerWindow* window);
virtual ~OffscreenWindowLayer(); virtual ~OffscreenWindowLayer();
virtual void Draw(const BRect &r); virtual void Draw(const BRect &r);
-825
View File
@@ -1,825 +0,0 @@
/*
* Copyright 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Gabe Yoder <gyoder@stny.rr.com>
* DarkWyrm <bpmagic@columbus.rr.com>
* Adrian Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/
/** Class used for the top layer of each workspace's Layer tree */
#include "Decorator.h"
#include "DrawingEngine.h"
#include "HWInterface.h"
#include "Layer.h"
#include "RootLayer.h"
#include "ServerApp.h"
#include "ServerConfig.h"
#include "ServerProtocol.h"
#include "ServerScreen.h"
#include "ServerWindow.h"
#include "WindowLayer.h"
#include "WorkspacePrivate.h"
#include "WorkspacesLayer.h"
#include <File.h>
#include <List.h>
#include <Message.h>
#include <PortLink.h>
#include <Window.h>
#include <stdio.h>
#if DISPLAY_HAIKU_LOGO
#include "ServerBitmap.h"
#include "HaikuLogo.h"
static const float kGoldenProportion = (sqrtf(5.0) - 1.0) / 2.0;
#endif
//#define TRACE_ROOT_LAYER
#ifdef TRACE_ROOT_LAYER
# define STRACE(a) printf a
#else
# define STRACE(a) ;
#endif
RootLayer::RootLayer(const char *name, Desktop *desktop, DrawingEngine *driver)
: Layer(BRect(0, 0, 0, 0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver),
fDesktop(desktop),
fDragMessage(NULL),
fMouseEventWindow(NULL),
fAllRegionsLock("root layer region lock"),
fDirtyForRedraw(),
fWorkspace(0),
fWorkspacesLayer(NULL),
fFocus(NULL),
fFront(NULL),
fBack(NULL)
{
//NOTE: be careful about this one.
fRootLayer = this;
// Some stuff that will go away in the future but fills some gaps right now
#if ON_SCREEN_DEBUGGING_INFO
fDebugInfo.SetTo("");
#endif
fDrawState->SetHighColor(RGBColor(255, 255, 255));
#if DISPLAY_HAIKU_LOGO
fLogoBitmap = new UtilityBitmap(BRect(0.0, 0.0, kLogoWidth - 1.0,
kLogoHeight - 1.0),
kLogoFormat, 0);
if (fLogoBitmap->IsValid()) {
int32 size = min_c(sizeof(kLogoBits), fLogoBitmap->BitsLength());
memcpy(fLogoBitmap->Bits(), kLogoBits, size);
} else {
delete fLogoBitmap;
fLogoBitmap = NULL;
}
#endif // DISPLAY_HAIKU_LOGO
fHidden = false;
#if ON_SCREEN_DEBUGGING_INFO
DebugInfoManager::Default()->SetRootLayer(this);
#endif
fFrame = desktop->VirtualScreen().Frame();
// RootLayer starts with valid visible regions
fFullVisible.Set(Bounds());
fVisible.Set(Bounds());
// first make sure we are actualy visible
MarkForRebuild(Bounds());
MarkForRedraw(Bounds());
_UpdateWorkspace(fDesktop->WorkspaceAt(fDesktop->CurrentWorkspace()));
TriggerRebuild();
TriggerRedraw();
}
RootLayer::~RootLayer()
{
delete fDragMessage;
fFirstChild = NULL;
// this prevents the Layer destructor from freeing our children again
// (the Desktop destructor already took care of that)
// RootLayer object just uses Screen objects, it is not allowed to delete them.
#if DISPLAY_HAIKU_LOGO
delete fLogoBitmap;
#endif
}
void
RootLayer::MoveBy(float x, float y)
{
}
void
RootLayer::ResizeBy(float x, float y)
{
if (x == 0 && y == 0)
return;
// TODO: we should be able to update less here
//BRect previous = fFrame;
fFrame.right += x;
fFrame.bottom += y;
fFullVisible.Set(Bounds());
fVisible.Set(Bounds());
BRegion region(fFrame);
MarkForRebuild(region);
TriggerRebuild();
//region.Exclude(previous);
MarkForRedraw(region);
TriggerRedraw();
}
bool
RootLayer::_SetFocus(WindowLayer* focus, BRegion& update)
{
// TODO: test for FFM and B_LOCK_WINDOW_FOCUS
if (focus == fFocus && (focus->WindowFlags() & B_AVOID_FOCUS) == 0)
return true;
// make sure no window is chosen that doesn't want focus
while (focus != NULL && (focus->WindowFlags() & B_AVOID_FOCUS) != 0) {
focus = (WindowLayer*)focus->PreviousLayer();
}
if (fFocus != NULL) {
update.Include(&fFocus->VisibleRegion());
fFocus->SetFocus(false);
}
fFocus = focus;
if (focus != NULL) {
update.Include(&focus->VisibleRegion());
focus->SetFocus(true);
}
return true;
}
bool
RootLayer::SetFocus(WindowLayer* focus)
{
BAutolock _(fAllRegionsLock);
BRegion update;
bool success = _SetFocus(focus, update);
if (!success)
return false;
MarkForRedraw(update);
TriggerRedraw();
return true;
}
/*!
\brief Tries to move the specified window to the front of the screen.
If there are any modal windows on this screen, it might not actually
become the frontmost window, though, as modal windows stay in front
of their subset.
*/
void
RootLayer::_SetFront(WindowLayer* window, BRegion& update)
{
if (window == NULL) {
fBack = NULL;
fFront = NULL;
return;
}
if (!window->SupportsFront() && fFront != NULL)
return;
BRegion previous = window->FullVisible();
WindowLayer* frontmost = window->Frontmost();
_RemoveChildFromList(window);
if (frontmost != NULL && frontmost->IsModal()) {
// all modal windows follow their subsets to the front
// (ie. they are staying in front of them, but they are
// not supposed to change their order because of that)
WindowLayer* nextModal;
for (WindowLayer* modal = frontmost; modal != NULL ; modal = nextModal) {
nextModal = (WindowLayer*)modal->NextLayer();
if (nextModal == frontmost) {
// since we're adding the modal windows to the end of the list
// we're traversing, we must stop when we've reached the initial
// starting point again
nextModal = NULL;
} else if (nextModal != NULL
&& (!nextModal->IsModal() || !nextModal->HasInSubset(window)))
nextModal = NULL;
previous.Include(&modal->FullVisible());
WindowLayer* modalFrontmost = modal->Frontmost();
_RemoveChildFromList(modal);
_AddChildToList(modal, modalFrontmost);
BRegion modalRegion;
modal->GetOnScreenRegion(modalRegion);
// TODO: this is not what we want, we'd want the new visible region
update.Include(&modalRegion);
}
}
_AddChildToList(window, frontmost);
BRegion windowRegion;
window->GetOnScreenRegion(windowRegion);
// TODO: this is not what we want, we'd want the new visible region
update.Include(&windowRegion);
update.Exclude(&previous);
_UpdateFront();
if (window == fBack || fBack == NULL)
_UpdateBack();
}
/*! search the visible windows for a valid back window
(only normal windows can be back windows)
*/
void
RootLayer::_UpdateBack()
{
fBack = NULL;
for (WindowLayer* window = (WindowLayer*)FirstChild();
window != NULL; window = (WindowLayer*)window->NextLayer()) {
if (window->IsHidden() || !window->SupportsFront())
continue;
fBack = window;
break;
}
}
/*! search the visible windows for a valid front window
(only normal windows can be front windows)
*/
void
RootLayer::_UpdateFront()
{
// TODO: for now, just choose the top window
fFront = NULL;
for (WindowLayer* window = (WindowLayer*)LastChild();
window != NULL; window = (WindowLayer*)window->PreviousLayer()) {
if (window->IsHidden() || !window->SupportsFront())
continue;
fFront = window;
break;
}
}
void
RootLayer::_UpdateFronts()
{
_UpdateBack();
_UpdateFront();
}
void
RootLayer::ActivateWindow(WindowLayer* window)
{
BAutolock _(fAllRegionsLock);
BRegion changed;
_SetFront(window, changed);
// TODO: if this window has any floating windows, add them here
MarkForRebuild(changed);
TriggerRebuild();
_SetFocus(Front(), changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::SendBehindWindow(WindowLayer* windowLayer, WindowLayer* behindOf)
{
BAutolock _(fAllRegionsLock);
if (windowLayer == Back())
return;
bool wasFocus = windowLayer == Focus();
BRegion changed = windowLayer->FullVisible();
_RemoveChildFromList(windowLayer);
if (behindOf == NULL)
behindOf = Back();
_AddChildToList(windowLayer, behindOf);
// TODO: if this window has any floating windows, remove them here
MarkForRebuild(changed);
TriggerRebuild();
_UpdateFronts();
_SetFocus(Front(), changed);
changed.Exclude(&windowLayer->FullVisible());
if (wasFocus != (Focus() == windowLayer))
changed.Include(&windowLayer->VisibleRegion());
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::AddWindow(WindowLayer* window)
{
STRACE(("AddWindowLayer(%p \"%s\")\n", window, window->Name()));
if (window->SupportsFront())
_AddChildToList(window, window->Frontmost((WindowLayer*)FirstChild()));
else
_AddChildToList(window, Back());
window->SetRootLayer(this);
if (!window->IsHidden())
ActivateWindow(window);
}
void
RootLayer::RemoveWindow(WindowLayer* window)
{
if (!window->IsHidden())
HideWindow(window);
_RemoveChildFromList(window);
LayerRemoved(window);
window->SetRootLayer(NULL);
}
void
RootLayer::_UpdateWorkspace(Workspace::Private& workspace)
{
fColor = workspace.Color();
#if ON_SCREEN_DEBUGGING_INFO
fDrawState->SetLowColor(fColor);
#endif
}
void
RootLayer::SetWorkspace(int32 index, Workspace::Private& previousWorkspace,
Workspace::Private& workspace)
{
BAutolock _(fAllRegionsLock);
int32 previousIndex = fWorkspace;
// build region of windows that are no longer visible in the new workspace
// and move windows to the previous workspace's window list
BRegion changed;
while (WindowLayer* window = (WindowLayer*)FirstChild()) {
// move the window into the workspace's window list
_RemoveChildFromList(window);
BPoint position = window->Frame().LeftTop();
previousWorkspace.AddWindow(window, &position);
if (window->IsHidden())
continue;
if (!window->OnWorkspace(index)) {
// this window will no longer be visible
changed.Include(&window->FullVisible());
}
}
fWorkspace = index;
_UpdateWorkspace(workspace);
// add new windows, and include them in the changed region - but only
// those that were not visible before (or whose position changed)
while (workspace.CountWindows() != 0) {
window_layer_info* info = workspace.WindowAt(0);
WindowLayer* window = info->window;
BPoint position = info->position;
// move window into the RootLayer's list
workspace.RemoveWindowAt(0);
_AddChildToList(window);
if (window->IsHidden())
continue;
if (position == kInvalidWindowPosition) {
// if you enter a workspace for the first time, the position
// of the window in the previous workspace is adopted
position = window->Frame().LeftTop();
// TODO: make sure the window is still on-screen if it
// was before!
}
if (!window->OnWorkspace(previousIndex)) {
// this window was not visible before
// TODO: what we really want here is the visible region of the window
BRegion region;
window->GetOnScreenRegion(region);
changed.Include(&region);
} else if (window->Frame().LeftTop() != position) {
// the window was visible before, but its on-screen location changed
BPoint offset = position - window->Frame().LeftTop();
window->MoveBy(offset.x, offset.y);
// TODO: we're playing dumb here - what we need is a MoveBy() that
// gives us a dirty region back, and since the new clipping code
// will give us just that, we don't take any special measurement
// here
GetOnScreenRegion(changed);
} else {
// the window is still visible and on the same location
continue;
}
}
_UpdateFronts();
_SetFocus(Front(), changed);
MarkForRebuild(changed);
TriggerRebuild();
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::HideWindow(WindowLayer* window)
{
BAutolock _(fAllRegionsLock);
BRegion changed = window->FullVisible();
window->Hide();
_UpdateFronts();
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
fWorkspacesLayer = NULL;
// TODO: if this window has any floating windows, remove them here
MarkForRebuild(changed);
TriggerRebuild();
if (window == Focus())
_SetFocus(Front(), changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::ShowWindow(WindowLayer* window, bool toFront)
{
STRACE(("ShowWindowLayer(%p)\n", window));
if (!window->IsHidden())
return;
BAutolock _(fAllRegionsLock);
window->Show();
BRegion changed = window->FullVisible();
if (toFront)
_SetFront(window, changed);
else
_UpdateFront();
// TODO: if this window has any floating windows, remove them here
// TODO: support FFM
if (Front() == window || Focus() == NULL)
_SetFocus(window, changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
fWorkspacesLayer = window->TopLayer();
}
void
RootLayer::MoveWindowBy(WindowLayer* window, float x, float y)
{
BAutolock _(fAllRegionsLock);
// TODO: the MoveBy() should just return a dirty region
window->MoveBy(x, y);
BRegion changed;
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::ResizeWindowBy(WindowLayer* window, float x, float y)
{
BAutolock _(fAllRegionsLock);
// TODO: the MoveBy() should just return a dirty region
window->ResizeBy(x, y);
BRegion changed;
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::SetWindowLook(WindowLayer *window, window_look newLook)
{
if (window->Look() == newLook)
return;
BAutolock _(fAllRegionsLock);
BRegion changed;
window->SetLook(newLook, window->Parent() ? &changed : NULL);
if (window->Parent() != NULL) {
MarkForRebuild(changed);
TriggerRebuild();
}
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::SetWindowFeel(WindowLayer *window, window_feel newFeel)
{
if (window->Feel() == newFeel)
return;
BAutolock _(fAllRegionsLock);
window->SetFeel(newFeel);
// TODO: implement window feels!
}
void
RootLayer::SetWindowFlags(WindowLayer *window, uint32 newFlags)
{
if (window->WindowFlags() == newFlags)
return;
BAutolock _(fAllRegionsLock);
BRegion changed;
window->SetWindowFlags(newFlags, window->Parent() ? &changed : NULL);
if (window->Parent() != NULL) {
MarkForRebuild(changed);
TriggerRebuild();
}
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::_WindowsChanged(BRegion& region)
{
if (fWorkspacesLayer == NULL)
return;
region.Include(&fWorkspacesLayer->VisibleRegion());
}
void
RootLayer::UpdateWorkspaces()
{
BAutolock _(fAllRegionsLock);
if (fWorkspacesLayer == NULL)
return;
BRegion changed;
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
WindowLayer*
RootLayer::WindowAt(BPoint where)
{
if (VisibleRegion().Contains(where))
return NULL;
for (Layer* child = LastChild(); child; child = child->PreviousLayer()) {
if (child->FullVisible().Contains(where))
return dynamic_cast<WindowLayer*>(child);
}
return NULL;
}
void
RootLayer::SetMouseEventWindow(WindowLayer* window)
{
fMouseEventWindow = window;
}
void
RootLayer::LayerRemoved(Layer* layer)
{
if (fMouseEventWindow == layer)
fMouseEventWindow = NULL;
if (fWorkspacesLayer == layer)
fWorkspacesLayer = NULL;
}
void
RootLayer::SetDragMessage(BMessage* msg)
{
if (fDragMessage) {
delete fDragMessage;
fDragMessage = NULL;
}
if (msg)
fDragMessage = new BMessage(*msg);
}
BMessage *
RootLayer::DragMessage() const
{
return fDragMessage;
}
void
RootLayer::Draw(const BRect& rect)
{
fDriver->FillRect(rect, fColor);
#if ON_SCREEN_DEBUGGING_INFO
BPoint location(5, 40);
float textHeight = 15.0; // be lazy
const char* p = fDebugInfo.String();
const char* start = p;
while (*p) {
p++;
if (*p == 0 || *p == '\n') {
fDriver->DrawString(start, p - start, location,
fDrawState);
// NOTE: Eventually, this will be below the screen!
location.y += textHeight;
start = p + 1;
}
}
#endif // ON_SCREEN_DEBUGGING_INFO
#if DISPLAY_HAIKU_LOGO
if (fLogoBitmap) {
BPoint logoPos;
logoPos.x = floorf(min_c(fFrame.left + fFrame.Width() * kGoldenProportion,
fFrame.right - (kLogoWidth + kLogoHeight / 2.0)));
logoPos.y = floorf(fFrame.bottom - kLogoHeight * 1.5);
BRect bitmapBounds = fLogoBitmap->Bounds();
fDriver->DrawBitmap(fLogoBitmap, bitmapBounds,
bitmapBounds.OffsetToCopy(logoPos), fDrawState);
}
#endif // DISPLAY_HAIKU_LOGO
}
#if ON_SCREEN_DEBUGGING_INFO
void
RootLayer::AddDebugInfo(const char* string)
{
if (Lock()) {
fDebugInfo << string;
MarkForRedraw(VisibleRegion());
TriggerRedraw();
Unlock();
}
}
#endif // ON_SCREEN_DEBUGGING_INFO
void
RootLayer::MarkForRedraw(const BRegion &dirty)
{
BAutolock locker(fAllRegionsLock);
fDirtyForRedraw.Include(&dirty);
}
void
RootLayer::TriggerRedraw()
{
BAutolock locker(fAllRegionsLock);
#if 0
// for debugging
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
RGBColor color(rand()%255, rand()%255, rand()%255);
GetDrawingEngine()->FillRect(Bounds(), color);
snooze(200000);
GetDrawingEngine()->ConstrainClippingRegion(NULL);
#endif
_AllRedraw(fDirtyForRedraw);
fDirtyForRedraw.MakeEmpty();
}
-142
View File
@@ -1,142 +0,0 @@
/*
* Copyright 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Gabe Yoder <gyoder@stny.rr.com>
* DarkWyrm <bpmagic@columbus.rr.com>
* Adrian Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef ROOT_LAYER_H
#define ROOT_LAYER_H
#include <List.h>
#include <Locker.h>
#include <MessageQueue.h>
#include "DebugInfoManager.h"
#include "Desktop.h"
#include "Layer.h"
#include "Workspace.h"
class DrawingEngine;
class HWInterface;
class RGBColor;
class Screen;
class WindowLayer;
namespace BPrivate {
class PortLink;
};
#ifndef DISPLAY_HAIKU_LOGO
# define DISPLAY_HAIKU_LOGO 1
#endif
#if DISPLAY_HAIKU_LOGO
class UtilityBitmap;
#endif
class RootLayer : public Layer {
public:
RootLayer(const char *name, Desktop *desktop,
DrawingEngine *driver);
virtual ~RootLayer();
Desktop* GetDesktop() const { return fDesktop; }
virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y);
virtual void ScrollBy(float x, float y)
{ /* not allowed */ }
void HideWindow(WindowLayer* window);
void ShowWindow(WindowLayer* window, bool toFront = true);
void MoveWindowBy(WindowLayer* window, float x, float y);
void ResizeWindowBy(WindowLayer* window, float x, float y);
bool SetFocus(WindowLayer* focus);
WindowLayer* Focus() const { return fFocus; }
WindowLayer* Front() const { return fFront; }
WindowLayer* Back() const { return fBack; }
void SetWorkspace(int32 index,
Workspace::Private& previousWorkspace,
Workspace::Private& workspace);
void SetDragMessage(BMessage *msg);
BMessage* DragMessage() const;
WindowLayer* WindowAt(BPoint where);
WindowLayer* MouseEventWindow() const { return fMouseEventWindow; }
void SetMouseEventWindow(WindowLayer* layer);
void LayerRemoved(Layer* layer);
// Other methods
bool Lock() { return fAllRegionsLock.Lock(); }
void Unlock() { fAllRegionsLock.Unlock(); }
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
void ActivateWindow(WindowLayer* window);
void SendBehindWindow(WindowLayer* window, WindowLayer* front);
void SetWindowLook(WindowLayer *window, window_look newLook);
void SetWindowFeel(WindowLayer *window, window_feel newFeel);
void SetWindowFlags(WindowLayer *window, uint32 newFlags);
void UpdateWorkspaces();
void MarkForRedraw(const BRegion &dirty);
void TriggerRedraw();
void Draw(const BRect &r);
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
void AddWindow(WindowLayer* window);
void RemoveWindow(WindowLayer* window);
private:
bool _SetFocus(WindowLayer* focus, BRegion& update);
void _SetFront(WindowLayer* front, BRegion& update);
void _UpdateBack();
void _UpdateFront();
void _UpdateFronts();
void _WindowsChanged(BRegion& region);
void _UpdateWorkspace(Workspace::Private& workspace);
Desktop* fDesktop;
BMessage* fDragMessage;
WindowLayer* fMouseEventWindow;
BLocker fAllRegionsLock;
BRegion fDirtyForRedraw;
int32 fWorkspace;
RGBColor fColor;
Layer* fWorkspacesLayer;
WindowLayer* fFocus;
WindowLayer* fFront;
WindowLayer* fBack;
#if ON_SCREEN_DEBUGGING_INFO
friend class DebugInfoManager;
void AddDebugInfo(const char* string);
BString fDebugInfo;
#endif
#if DISPLAY_HAIKU_LOGO
UtilityBitmap* fLogoBitmap;
#endif
};
#endif // ROOT_LAYER_H
+43 -58
View File
@@ -38,6 +38,7 @@
#include "CursorManager.h" #include "CursorManager.h"
#include "CursorSet.h" #include "CursorSet.h"
#include "Desktop.h" #include "Desktop.h"
#include "DebugInfoManager.h"
#include "DecorManager.h" #include "DecorManager.h"
#include "DrawingEngine.h" #include "DrawingEngine.h"
#include "EventStream.h" #include "EventStream.h"
@@ -46,7 +47,6 @@
#include "InputManager.h" #include "InputManager.h"
#include "OffscreenServerWindow.h" #include "OffscreenServerWindow.h"
#include "RAMLinkMsgReader.h" #include "RAMLinkMsgReader.h"
#include "RootLayer.h"
#include "ServerApp.h" #include "ServerApp.h"
#include "ServerBitmap.h" #include "ServerBitmap.h"
#include "ServerConfig.h" #include "ServerConfig.h"
@@ -93,7 +93,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
fAppCursor(NULL), fAppCursor(NULL),
fCursorHidden(false), fCursorHidden(false),
fIsActive(false), fIsActive(false),
fSharedMem("shared memory") fSharedMem("shared memory", 32768)
{ {
if (fSignature == "") if (fSignature == "")
fSignature = "application/no-signature"; fSignature = "application/no-signature";
@@ -231,7 +231,7 @@ ServerApp::Run()
return false; return false;
// Let's tell the client how to talk with us // Let's tell the client how to talk with us
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(fMessagePort); fLink.Attach<int32>(fMessagePort);
fLink.Flush(); fLink.Flush();
@@ -531,7 +531,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
void *sharedmem = fSharedMem.GetBuffer(memsize); void *sharedmem = fSharedMem.GetBuffer(memsize);
if (memsize < 1 || sharedmem == NULL) { if (memsize < 1 || sharedmem == NULL) {
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -540,7 +540,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
area_info info; area_info info;
if (owningArea == B_ERROR || get_area_info(owningArea, &info) < B_OK) { if (owningArea == B_ERROR || get_area_info(owningArea, &info) < B_OK) {
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -548,7 +548,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
int32 areaoffset = (addr_t)sharedmem - (addr_t)info.address; int32 areaoffset = (addr_t)sharedmem - (addr_t)info.address;
STRACE(("Successfully allocated shared memory of size %ld\n",memsize)); STRACE(("Successfully allocated shared memory of size %ld\n",memsize));
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<area_id>(owningArea); fLink.Attach<area_id>(owningArea);
fLink.Attach<int32>(areaoffset); fLink.Attach<int32>(areaoffset);
fLink.Flush(); fLink.Flush();
@@ -582,13 +582,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
{ {
STRACE(("ServerApp %s: Received decorator update notification\n", Signature())); STRACE(("ServerApp %s: Received decorator update notification\n", Signature()));
for (int32 i = 0; i < fWindowList.CountItems(); i++) { // TODO: implement or remove AS_UPDATE_DECORATOR
/* for (int32 i = 0; i < fWindowList.CountItems(); i++) {
ServerWindow *window = fWindowList.ItemAt(i); ServerWindow *window = fWindowList.ItemAt(i);
window->Lock(); window->Lock();
const_cast<WindowLayer *>(window->GetWindowLayer())->UpdateDecorator(); const_cast<WindowLayer *>(window->GetWindowLayer())->UpdateDecorator();
window->Unlock(); window->Unlock();
} }
break; */ break;
} }
case AS_SET_DECORATOR: case AS_SET_DECORATOR:
{ {
@@ -606,14 +607,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
} }
case AS_COUNT_DECORATORS: case AS_COUNT_DECORATORS:
{ {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(gDecorManager.CountDecorators()); fLink.Attach<int32>(gDecorManager.CountDecorators());
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_GET_DECORATOR: case AS_GET_DECORATOR:
{ {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(gDecorManager.GetDecorator()); fLink.Attach<int32>(gDecorManager.GetDecorator());
fLink.Flush(); fLink.Flush();
break; break;
@@ -624,14 +625,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read<int32>(&index); link.Read<int32>(&index);
BString str(gDecorManager.GetDecoratorName(index)); BString str(gDecorManager.GetDecoratorName(index));
if (str.CountChars() > 0) if (str.CountChars() > 0) {
{ fLink.StartMessage(B_OK);
fLink.StartMessage(SERVER_TRUE);
fLink.AttachString(str.String()); fLink.AttachString(str.String());
} } else
else fLink.StartMessage(B_ERROR);
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -659,16 +658,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
{ {
STRACE(("ServerApp %s: Received BBitmap creation request\n", Signature())); STRACE(("ServerApp %s: Received BBitmap creation request\n", Signature()));
// Allocate a bitmap for an application // Allocate a bitmap for an application
// Attached Data: // Attached Data:
// 1) BRect bounds // 1) BRect bounds
// 2) color_space space // 2) color_space space
// 3) int32 bitmap_flags // 3) int32 bitmap_flags
// 4) int32 bytes_per_row // 4) int32 bytes_per_row
// 5) int32 screen_id::id // 5) int32 screen_id::id
// 6) port_id reply port
// Reply Code: SERVER_TRUE
// Reply Data: // Reply Data:
// 1) int32 server token // 1) int32 server token
// 2) area_id id of the area in which the bitmap data resides // 2) area_id id of the area in which the bitmap data resides
@@ -694,13 +691,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
Signature(), frame.Width(), frame.Height())); Signature(), frame.Width(), frame.Height()));
if (bitmap && fBitmapList.AddItem((void*)bitmap)) { if (bitmap && fBitmapList.AddItem((void*)bitmap)) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(bitmap->Token()); fLink.Attach<int32>(bitmap->Token());
fLink.Attach<area_id>(bitmap->Area()); fLink.Attach<area_id>(bitmap->Area());
fLink.Attach<int32>(bitmap->AreaOffset()); fLink.Attach<int32>(bitmap->AreaOffset());
} else { } else {
// alternatively, if something went wrong, we reply with SERVER_FALSE fLink.StartMessage(B_NO_MEMORY);
fLink.StartMessage(SERVER_FALSE);
} }
fLink.Flush(); fLink.Flush();
@@ -713,10 +709,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// Attached Data: // Attached Data:
// 1) int32 token // 1) int32 token
// 2) int32 reply port
// Reply Code: SERVER_TRUE if successful,
// SERVER_FALSE if the buffer was already deleted or was not found
int32 id; int32 id;
link.Read<int32>(&id); link.Read<int32>(&id);
@@ -725,11 +717,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id)); STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id));
gBitmapManager->DeleteBitmap(bitmap); gBitmapManager->DeleteBitmap(bitmap);
fLink.StartMessage(SERVER_TRUE); }
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
break; break;
} }
#if 0 #if 0
@@ -787,7 +775,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (fDesktop->CurrentWorkspace() >= newCount) if (fDesktop->CurrentWorkspace() >= newCount)
fDesktop->SetWorkspace(newCount - 1); fDesktop->SetWorkspace(newCount - 1);
else else
fDesktop->RootLayer()->UpdateWorkspaces(); fDesktop->UpdateWorkspaces();
} }
break; break;
} }
@@ -838,7 +826,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_QUERY_CURSOR_HIDDEN: case AS_QUERY_CURSOR_HIDDEN:
{ {
STRACE(("ServerApp %s: Received IsCursorHidden request\n", Signature())); STRACE(("ServerApp %s: Received IsCursorHidden request\n", Signature()));
fLink.StartMessage(fCursorHidden ? SERVER_TRUE : SERVER_FALSE); fLink.StartMessage(fCursorHidden ? B_OK : B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -886,7 +874,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (sync) { if (sync) {
// the application is expecting a reply, but plans to do literally nothing // the application is expecting a reply, but plans to do literally nothing
// with the data, so we'll just reuse the cursor token variable // with the data, so we'll just reuse the cursor token variable
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Flush(); fLink.Flush();
} }
break; break;
@@ -914,7 +902,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fDesktop->GetCursorManager().AddCursor(fAppCursor); fDesktop->GetCursorManager().AddCursor(fAppCursor);
// Synchronous message - BApplication is waiting on the cursor's ID // Synchronous message - BApplication is waiting on the cursor's ID
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(fAppCursor->ID()); fLink.Attach<int32>(fAppCursor->ID());
fLink.Flush(); fLink.Flush();
break; break;
@@ -940,7 +928,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
DesktopSettings settings(fDesktop); DesktopSettings settings(fDesktop);
settings.GetScrollBarInfo(info); settings.GetScrollBarInfo(info);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<scroll_bar_info>(info); fLink.Attach<scroll_bar_info>(info);
fLink.Flush(); fLink.Flush();
break; break;
@@ -956,7 +944,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
settings.SetScrollBarInfo(info); settings.SetScrollBarInfo(info);
} }
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -1006,7 +994,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature())); STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature()));
DesktopSettings settings(fDesktop); DesktopSettings settings(fDesktop);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<mode_mouse>(settings.MouseMode()); fLink.Attach<mode_mouse>(settings.MouseMode());
fLink.Flush(); fLink.Flush();
break; break;
@@ -1018,7 +1006,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// using a ColorSet object // using a ColorSet object
gGUIColorSet.Lock(); gGUIColorSet.Lock();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<ColorSet>(gGUIColorSet); fLink.Attach<ColorSet>(gGUIColorSet);
fLink.Flush(); fLink.Flush();
@@ -1051,7 +1039,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
color = gGUIColorSet.AttributeToColor(whichColor); color = gGUIColorSet.AttributeToColor(whichColor);
gGUIColorSet.Unlock(); gGUIColorSet.Unlock();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<rgb_color>(color.GetColor32()); fLink.Attach<rgb_color>(color.GetColor32());
fLink.Flush(); fLink.Flush();
break; break;
@@ -1838,14 +1826,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// TODO implement for real // TODO implement for real
if (font.GetBoundingBoxesAsString(charArray, numChars, rectArray, string_escapement, mode, delta)) { if (font.GetBoundingBoxesAsString(charArray, numChars, rectArray, string_escapement, mode, delta)) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(rectArray, sizeof(rectArray)); fLink.Attach(rectArray, sizeof(rectArray));
success = true; success = true;
} }
} }
if (!success) if (!success)
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
@@ -1912,7 +1900,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// TODO implement for real // TODO implement for real
if (font.GetBoundingBoxesForStrings(stringArray, lengthArray, numStrings, rectArray, mode, deltaArray)) { if (font.GetBoundingBoxesForStrings(stringArray, lengthArray, numStrings, rectArray, mode, deltaArray)) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(rectArray, sizeof(rectArray)); fLink.Attach(rectArray, sizeof(rectArray));
success = true; success = true;
} }
@@ -1922,7 +1910,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
free(stringArray[i]); free(stringArray[i]);
if (!success) if (!success)
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
@@ -2036,18 +2024,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
bool makedefault = false; bool makedefault = false;
link.Read<bool>(&makedefault); link.Read<bool>(&makedefault);
RootLayer* rootLayer = fDesktop->RootLayer(); status_t status = B_ERROR;
rootLayer->Lock(); if (fDesktop->WriteLockWindows()) {
status_t status = fDesktop->ScreenAt(0)->SetMode(mode); status = fDesktop->ScreenAt(0)->SetMode(mode);
if (status == B_OK) { if (status == B_OK) {
BRect bounds = rootLayer->Bounds(); gInputManager->UpdateScreenBounds(fDesktop->ScreenAt(0)->Frame());
rootLayer->ResizeBy(mode.virtual_width - 1 - bounds.Width(), fDesktop->ScreenChanged(fDesktop->ScreenAt(0));
mode.virtual_height - 1 - bounds.Height()); }
fDesktop->WriteUnlockWindows();
gInputManager->UpdateScreenBounds(rootLayer->Bounds());
fDesktop->ScreenChanged(fDesktop->ScreenAt(0));
} }
rootLayer->Unlock();
fLink.StartMessage(status); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
@@ -2313,7 +2298,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (link.NeedsReply()) { if (link.NeedsReply()) {
// the client is now blocking and waiting for a reply! // the client is now blocking and waiting for a reply!
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
} else } else
puts("message doesn't need a reply!"); puts("message doesn't need a reply!");
@@ -2418,7 +2403,7 @@ ServerApp::RemoveWindow(ServerWindow* window)
bool bool
ServerApp::OnWorkspace(int32 index) ServerApp::OnWorkspace(int32 index) const
{ {
BAutolock locker(fWindowListLock); BAutolock locker(fWindowListLock);
+2 -2
View File
@@ -64,7 +64,7 @@ class ServerApp : public MessageLooper {
const char *Signature() const { return fSignature.String(); } const char *Signature() const { return fSignature.String(); }
void RemoveWindow(ServerWindow* window); void RemoveWindow(ServerWindow* window);
bool OnWorkspace(int32 index); bool OnWorkspace(int32 index) const;
int32 CountBitmaps() const; int32 CountBitmaps() const;
ServerBitmap *FindBitmap(int32 token) const; ServerBitmap *FindBitmap(int32 token) const;
@@ -98,7 +98,7 @@ class ServerApp : public MessageLooper {
BString fSignature; BString fSignature;
team_id fClientTeam; team_id fClientTeam;
BLocker fWindowListLock; mutable BLocker fWindowListLock;
BObjectList<ServerWindow> fWindowList; BObjectList<ServerWindow> fWindowList;
BPrivate::BTokenSpace fViewTokens; BPrivate::BTokenSpace fViewTokens;
File diff suppressed because it is too large Load Diff
+19 -8
View File
@@ -38,7 +38,7 @@ class Decorator;
class WindowLayer; class WindowLayer;
class Workspace; class Workspace;
class RootLayer; class RootLayer;
class Layer; class ViewLayer;
class ServerPicture; class ServerPicture;
struct dw_data; struct dw_data;
struct window_info; struct window_info;
@@ -97,7 +97,8 @@ public:
// related thread/team_id(s). // related thread/team_id(s).
inline team_id ClientTeam() const { return fClientTeam; } inline team_id ClientTeam() const { return fClientTeam; }
void HandleDirectConnection(int bufferState = -1, int driverState = -1); void HandleDirectConnection(int bufferState = -1,
int driverState = -1);
inline int32 ClientToken() const { return fClientToken; } inline int32 ClientToken() const { return fClientToken; }
inline int32 ServerToken() const { return fServerToken; } inline int32 ServerToken() const { return fServerToken; }
@@ -106,19 +107,27 @@ public:
private: private:
// methods for retrieving and creating a tree strcture of Layers. // methods for retrieving and creating a tree strcture of Layers.
Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent); ViewLayer* CreateLayerTree(BPrivate::LinkReceiver &link,
void SetLayerState(Layer *layer, BPrivate::LinkReceiver &link); ViewLayer **_parent);
void SetLayerFontState(Layer *layer, BPrivate::LinkReceiver &link); void SetLayerState(ViewLayer *layer,
BPrivate::LinkReceiver &link);
void SetLayerFontState(ViewLayer *layer,
BPrivate::LinkReceiver &link);
// message handling methods. // message handling methods.
void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
void _DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link); void _DispatchViewMessage(int32 code,
BPrivate::LinkReceiver &link);
void _DispatchViewDrawingMessage(int32 code,
BPrivate::LinkReceiver &link);
void _MessageLooper(); void _MessageLooper();
virtual void _PrepareQuit(); virtual void _PrepareQuit();
virtual void _GetLooperName(char* name, size_t size); virtual void _GetLooperName(char* name, size_t size);
status_t _EnableDirectWindowMode(); status_t _EnableDirectWindowMode();
void _SetCurrentLayer(ViewLayer* view);
// TODO: Move me elsewhere // TODO: Move me elsewhere
status_t PictureToRegion(ServerPicture *picture, status_t PictureToRegion(ServerPicture *picture,
BRegion &, BRegion &,
@@ -146,7 +155,9 @@ private:
int32 fServerToken; int32 fServerToken;
int32 fClientToken; int32 fClientToken;
Layer* fCurrentLayer; ViewLayer* fCurrentLayer;
BRegion fCurrentDrawingRegion;
bool fCurrentDrawingRegionValid;
dw_data* fDirectWindowData; dw_data* fDirectWindowData;
}; };
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <adioanca@cotty.iren.ro>
*/
/** List class for tracking floating and modal windows */
#include "SubWindowList.h"
#include "WindowLayer.h"
#include "ServerWindow.h"
#include <List.h>
#include <stdio.h>
SubWindowList::SubWindowList()
{
}
SubWindowList::~SubWindowList()
{
}
void
SubWindowList::AddWindowLayer(WindowLayer *windowLayer)
{
if (HasItem(windowLayer))
return;
int32 borderFeel = windowLayer->Feel();;
int32 location = 0;
for (; location < CountItems(); location++) {
int32 feelTemp = ((WindowLayer*)ItemAt(location))->Feel();
// in short: if 'windowLayer' is a floating window and 'temp' a modal one
if ((borderFeel == B_FLOATING_SUBSET_WINDOW_FEEL
|| borderFeel == B_FLOATING_APP_WINDOW_FEEL
|| borderFeel == B_FLOATING_ALL_WINDOW_FEEL)
&& (feelTemp == B_MODAL_SUBSET_WINDOW_FEEL
|| feelTemp == B_MODAL_APP_WINDOW_FEEL
|| feelTemp == B_MODAL_ALL_WINDOW_FEEL)) {
// means we found the place for our window('windowLayer')
break;
}
}
AddItem(windowLayer, location);
}
void
SubWindowList::AddSubWindowList(SubWindowList *list)
{
int32 i = 0;
for (; i < CountItems(); i++) {
int32 feel = ((WindowLayer*)ItemAt(i))->Feel();
if (feel == B_MODAL_SUBSET_WINDOW_FEEL
|| feel == B_MODAL_APP_WINDOW_FEEL
|| feel == B_MODAL_ALL_WINDOW_FEEL)
break;
}
for (int32 j = 0; j < list->CountItems(); j++) {
void *item = list->ItemAt(j);
int32 feel = ((WindowLayer*)item)->Feel();
if (feel == B_MODAL_SUBSET_WINDOW_FEEL
|| feel == B_MODAL_APP_WINDOW_FEEL
|| feel == B_MODAL_ALL_WINDOW_FEEL) {
AddItem(item, CountItems());
} else {
AddItem(item, i);
i++;
}
}
}
void
SubWindowList::PrintToStream() const
{
printf("Floating and modal windows list:\n");
WindowLayer* windowLayer = NULL;
for (int32 i=0; i<CountItems(); i++) {
windowLayer = (WindowLayer*)ItemAt(i);
printf("\t%s", windowLayer->Name());
if (windowLayer->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_SUBSET_WINDOW_FEEL");
if (windowLayer->Feel() == B_FLOATING_APP_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_APP_WINDOW_FEEL");
if (windowLayer->Feel() == B_FLOATING_ALL_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_ALL_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_SUBSET_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_APP_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_APP_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_ALL_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_ALL_WINDOW_FEEL");
// this should NOT happen
if (windowLayer->Feel() == B_NORMAL_WINDOW_FEEL)
printf("\t%s\n", "B_NORMAL_WINDOW_FEEL");
}
}
-32
View File
@@ -1,32 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <adioanca@cotty.iren.ro>
*/
#ifndef _SUB_WINDOW_LIST_H_
#define _SUB_WINDOW_LIST_H_
#include <List.h>
#include <Window.h>
class WindowLayer;
class SubWindowList : public BList {
public:
SubWindowList();
virtual ~SubWindowList();
void AddWindowLayer(WindowLayer *windowLayer);
// special
void AddSubWindowList(SubWindowList *list);
// debugging methods
void PrintToStream() const;
};
#endif /* _SUB_WINDOW_LIST_H_ */
File diff suppressed because it is too large Load Diff
+212
View File
@@ -0,0 +1,212 @@
/*
* Copyright (c) 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef VIEW_LAYER_H
#define VIEW_LAYER_H
#include "RGBColor.h"
#include <GraphicsDefs.h>
#include <Region.h>
#include <String.h>
class BList;
class DrawState;
class DrawingEngine;
class WindowLayer;
class ViewLayer {
public:
ViewLayer(BRect frame, const char* name,
int32 token, uint32 resizeMode,
uint32 flags);
virtual ~ViewLayer();
void SetName(const char* string);
const char* Name() const
{ return fName.String(); }
int32 Token() const
{ return fToken; }
BRect Frame() const
{ return fFrame; }
BRect Bounds() const;
void SetResizeMode(uint32 resizeMode)
{ fResizeMode = resizeMode; }
uint32 Flags() const
{ return fFlags; }
void SetFlags(uint32 flags);
BPoint ScrollingOffset() const;
void SetDrawingOrigin(BPoint origin);
BPoint DrawingOrigin() const;
void SetScale(float scale);
float Scale() const;
void SetUserClipping(const BRegion& region);
// region is expected in layer coordinates
// converts the given frame up the view hierarchy and
// clips to each views bounds
void ConvertToVisibleInTopView(BRect* bounds) const;
void AttachedToWindow(WindowLayer* window);
void DetachedFromWindow();
WindowLayer* Window() const { return fWindow; }
// tree stuff
void AddChild(ViewLayer* layer);
bool RemoveChild(ViewLayer* layer);
inline ViewLayer* Parent() const
{ return fParent; }
ViewLayer* FirstChild() const;
ViewLayer* LastChild() const;
ViewLayer* PreviousSibling() const;
ViewLayer* NextSibling() const;
ViewLayer* TopLayer();
uint32 CountChildren(bool deep = false) const;
void CollectTokensForChildren(BList* tokenMap) const;
ViewLayer* ViewAt(const BPoint& where,
BRegion* windowContentClipping);
// coordinate conversion
void ConvertToParent(BPoint* point) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(BRegion* region) const;
void ConvertFromParent(BPoint* point) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(BRegion* region) const;
void ConvertToScreen(BPoint* point) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(BRegion* region) const;
void ConvertFromScreen(BPoint* point) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(BRegion* region) const;
void ConvertToScreenForDrawing(BPoint* point) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* region) const;
void ConvertFromScreenForDrawing(BPoint* point) const;
// used when updating the pen position
void MoveBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ResizeBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ScrollBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ParentResized(int32 dx, int32 dy,
BRegion* dirtyRegion);
void CopyBits(BRect src, BRect dst,
BRegion& windowContentClipping);
const BRegion& LocalClipping() const { return fLocalClipping; }
const RGBColor& ViewColor() const
{ return fViewColor; }
void SetViewColor(const RGBColor& color)
{ fViewColor = color; }
void PushState();
void PopState();
DrawState* CurrentState() const { return fDrawState; }
void SetEventMask(uint32 eventMask, uint32 options);
uint32 EventMask() const
{ return fEventMask; }
uint32 EventOptions() const
{ return fEventOptions; }
// for background clearing
virtual void Draw(DrawingEngine* drawingEngine,
BRegion* effectiveClipping,
BRegion* windowContentClipping,
bool deep = false);
void SetHidden(bool hidden);
bool IsHidden() const;
// takes into account parent views hidden status
bool IsVisible() const
{ return fVisible; }
// update visible status for this view and all children
// according to the parents visibility
void UpdateVisibleDeep(bool parentVisible);
// clipping
void RebuildClipping(bool deep);
BRegion& ScreenClipping(BRegion* windowContentClipping,
bool force = false) const;
void InvalidateScreenClipping(bool deep);
bool IsScreenClippingValid() const
{ return fScreenClippingValid; }
// debugging
void PrintToStream() const;
protected:
void _MoveScreenClipping(int32 x, int32 y,
bool deep);
BString fName;
int32 fToken;
// area within parent coordinate space
BRect fFrame;
// scrolling offset
BPoint fScrollingOffset;
RGBColor fViewColor;
DrawState* fDrawState;
uint32 fResizeMode;
uint32 fFlags;
bool fHidden;
bool fVisible;
uint32 fEventMask;
uint32 fEventOptions;
WindowLayer* fWindow;
ViewLayer* fParent;
ViewLayer* fFirstChild;
ViewLayer* fPreviousSibling;
ViewLayer* fNextSibling;
ViewLayer* fLastChild;
// clipping
BRegion fLocalClipping;
mutable BRegion fScreenClipping;
mutable bool fScreenClippingValid;
};
#endif // LAYER_H
File diff suppressed because it is too large Load Diff
+221 -95
View File
@@ -12,98 +12,135 @@
#include "Decorator.h" #include "Decorator.h"
#include "Layer.h" #include "ViewLayer.h"
#include "ServerWindow.h"
#include "WindowList.h"
#include <ObjectList.h> #include <ObjectList.h>
#include <Rect.h> #include <Region.h>
#include <String.h> #include <String.h>
class ServerWindow; class ClientLooper;
class Decorator; class Decorator;
class DrawingEngine;
class Desktop; class Desktop;
class DrawingEngine;
class EventDispatcher;
class WindowLayer;
class WindowLayer : public Layer { // TODO: move this into a proper place
#define AS_REDRAW 'rdrw'
class WindowLayer {
public: public:
WindowLayer(const BRect &frame, WindowLayer(const BRect& frame,
const char *name, window_look look, const char *name, window_look look,
window_feel feel, uint32 flags, window_feel feel, uint32 flags,
uint32 workspaces, ServerWindow *window, uint32 workspaces,
DrawingEngine *driver); ::ServerWindow* window,
DrawingEngine* drawingEngine);
virtual ~WindowLayer(); virtual ~WindowLayer();
virtual void Draw(const BRect &r); BRect Frame() const { return fFrame; }
const char* Title() const { return fTitle.String(); }
virtual void MoveBy(float x, float y); window_anchor& Anchor(int32 index);
virtual void ResizeBy(float x, float y); WindowLayer* NextWindow(int32 index);
virtual void ScrollBy(float x, float y) WindowLayer* PreviousWindow(int32 index);
{ /* not allowed */ }
virtual void SetName(const char* name); ::Desktop* Desktop() const { return fDesktop; }
::Decorator* Decorator() const { return fDecorator; }
::ServerWindow* ServerWindow() const { return fWindow; }
::EventTarget& EventTarget() const { return fWindow->EventTarget(); }
virtual bool IsOffscreenWindow() const // for convenience, handles window not attached to Desktop
{ return false; } bool ReadLockWindows();
void ReadUnlockWindows();
virtual void GetOnScreenRegion(BRegion& region); // setting and getting the "hard" clipping, you need to have
// WriteLock()ed the clipping!
void SetClipping(BRegion* stillAvailableOnScreen);
// you need to have ReadLock()ed the clipping!
inline BRegion& VisibleRegion() { return fVisibleRegion; }
BRegion& VisibleContentRegion();
// TODO: not protected by a lock, but noone should need this anyways
// make private? when used inside WindowLayer, it has the ReadLock()
void GetFullRegion(BRegion* region);
void GetBorderRegion(BRegion* region);
void GetContentRegion(BRegion* region);
void MoveBy(int32 x, int32 y);
void ResizeBy(int32 x, int32 y, BRegion* dirtyRegion);
void ScrollViewBy(ViewLayer* view, int32 dx, int32 dy);
void SetTopLayer(ViewLayer* topLayer);
ViewLayer* ViewAt(const BPoint& where);
virtual bool IsOffscreenWindow() const { return false; }
void GetEffectiveDrawingRegion(ViewLayer* layer, BRegion& region);
bool DrawingRegionChanged(ViewLayer* layer) const;
// generic version, used by the Desktop
void ProcessDirtyRegion(BRegion& regionOnScreen);
void RedrawDirtyRegion();
// can be used from inside classes that don't
// need to know about Desktop (first version uses Desktop)
void MarkDirty(BRegion& regionOnScreen);
// this version does not use the Desktop
void MarkContentDirty(BRegion& regionOnScreen);
// shortcut for invalidating just one view
void InvalidateView(ViewLayer* view, BRegion& layerRegion);
void UpdateStart();
void UpdateEnd();
inline bool InUpdate() const
{ return fInUpdate; }
inline const BRegion& RegionToBeUpdated() const
{ return fInUpdateRegion; }
inline const BRegion& CulmulatedUpdateRegion() const
{ return fCumulativeRegion; }
void EnableUpdateRequests(); void EnableUpdateRequests();
inline void DisableUpdateRequests() void DisableUpdateRequests();
{ fUpdateRequestsEnabled = false; }
void SetSizeLimits(float minWidth, void BeginUpdate();
float maxWidth, void EndUpdate();
float minHeight,
float maxHeight);
void GetSizeLimits(float* minWidth, bool NeedsUpdate() const
float* maxWidth, { return fUpdateRequested; }
float* minHeight,
float* maxHeight) const;
virtual void MouseDown(BMessage* message, BPoint where, int32* _viewToken); DrawingEngine* GetDrawingEngine() const
virtual void MouseUp(BMessage* message, BPoint where, int32* _viewToken); { return fDrawingEngine; }
virtual void MouseMoved(BMessage* message, BPoint where, int32* _viewToken);
// click_type ActionFor(const BMessage *msg) void CopyContents(BRegion* region,
// { return _ActionFor(evt); } int32 xOffset, int32 yOffset);
virtual void WorkspaceActivated(int32 index, bool active); void MouseDown(BMessage* message, BPoint where, int32* _viewToken);
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces); void MouseUp(BMessage* message, BPoint where, int32* _viewToken);
virtual void Activated(bool active); void MouseMoved(BMessage* message, BPoint where, int32* _viewToken);
void UpdateColors(); // some hooks to inform the client window
void UpdateDecorator(); // TODO: move this to ServerWindow maybe?
void UpdateFont(); void WorkspaceActivated(int32 index, bool active);
void UpdateScreen(); void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
void Activated(bool active);
// changing some properties
void SetTitle(const char* name);
void SetFocus(bool focus);
bool IsFocus() const { return fIsFocus; } bool IsFocus() const { return fIsFocus; }
void SetFocus(bool focus) { fIsFocus = focus; }
inline Decorator* GetDecorator() const { return fDecorator; } void SetHidden(bool hidden);
inline bool IsHidden() const { return fHidden; }
window_look Look() const { return fLook; } void SetCurrentWorkspace(int32 index)
window_feel Feel() const { return fFeel; } { fCurrentWorkspace = index; }
uint32 WindowFlags() const { return fWindowFlags; } bool IsVisible() const;
void SetLook(window_look look, BRegion* updateRegion); // TODO: make this int32 stuff
void SetFeel(window_feel feel); void SetSizeLimits(int32 minWidth, int32 maxWidth,
void SetWindowFlags(uint32 flags, BRegion* updateRegion); int32 minHeight, int32 maxHeight);
uint32 Workspaces() const { return fWorkspaces; } void GetSizeLimits(int32* minWidth, int32* maxWidth,
void SetWorkspaces(uint32 workspaces) int32* minHeight, int32* maxHeight) const;
{ fWorkspaces = workspaces; }
bool OnWorkspace(int32 index) const;
bool SupportsFront();
// 0.0 -> left .... 1.0 -> right // 0.0 -> left .... 1.0 -> right
void SetTabLocation(float location); void SetTabLocation(float location);
@@ -111,20 +148,33 @@ class WindowLayer : public Layer {
void HighlightDecorator(bool active); void HighlightDecorator(bool active);
void SetLook(window_look look, BRegion* updateRegion);
void SetFeel(window_feel feel);
void SetFlags(uint32 flags, BRegion* updateRegion);
window_look Look() const { return fLook; }
window_feel Feel() const { return fFeel; }
uint32 Flags() const { return fFlags; }
// window manager stuff
uint32 Workspaces() const { return fWorkspaces; }
void SetWorkspaces(uint32 workspaces)
{ fWorkspaces = workspaces; }
bool OnWorkspace(int32 index) const;
bool SupportsFront();
bool IsModal() const; bool IsModal() const;
bool IsFloating() const; bool IsFloating() const;
bool IsNormal() const;
WindowLayer* Frontmost(WindowLayer* first = NULL); WindowLayer* Frontmost(WindowLayer* first = NULL, int32 workspace = -1);
WindowLayer* Backmost(WindowLayer* first = NULL, int32 workspace = -1);
bool AddToSubset(WindowLayer* window); bool AddToSubset(WindowLayer* window);
void RemoveFromSubset(WindowLayer* window); void RemoveFromSubset(WindowLayer* window);
bool HasInSubset(WindowLayer* window); bool HasInSubset(WindowLayer* window);
bool SameSubset(WindowLayer* window);
void RequestClientRedraw(const BRegion& invalid);
void SetTopLayer(Layer* layer);
inline Layer* TopLayer() const
{ return fTopLayer; }
static bool IsValidLook(window_look look); static bool IsValidLook(window_look look);
static bool IsValidFeel(window_feel feel); static bool IsValidFeel(window_feel feel);
@@ -135,33 +185,58 @@ class WindowLayer : public Layer {
static uint32 ValidWindowFlags(window_feel feel); static uint32 ValidWindowFlags(window_feel feel);
protected: protected:
virtual void _AllRedraw(const BRegion& invalid); friend class Desktop;
// TODO: for now (list management)
private: void _ShiftPartOfRegion(BRegion* region, BRegion* regionToShift,
void set_decorator_region(BRect frame); int32 xOffset, int32 yOffset);
virtual void _ReserveRegions(BRegion &reg);
friend class RootLayer; // different types of drawing
void _TriggerContentRedraw();
void _DrawBorder();
click_type _ActionFor(const BMessage *msg) const; // handling update sessions
void _MarkContentDirty(BRegion* contentDirtyRegion);
void _SendUpdateMessage();
Decorator* fDecorator; void _UpdateContentRegion();
Layer* fTopLayer;
BRegion fCumulativeRegion; click_type _ActionFor(const BMessage* msg) const;
BRegion fInUpdateRegion;
BRegion fDecRegion; void _ObeySizeLimits();
bool fRebuildDecRegion;
int32 fMouseButtons; BString fTitle;
BPoint fLastMousePosition; // TODO: no fp rects anywhere
BPoint fResizingClickOffset; BRect fFrame;
bool fIsFocus; window_anchor fAnchor[kWorkingList + 1];
// one for each desktop, and one working anchor
// the visible region is only recalculated from the
// Desktop thread, when using it, Desktop::ReadLockClipping()
// has to be called
BRegion fVisibleRegion;
BRegion fVisibleContentRegion;
bool fVisibleContentRegionValid;
// our part of the "global" dirty region
// it is calculated from the desktop thread,
// but we can write to it when we read locked
// the clipping, since it is local and the desktop
// thread is blocked
BRegion fDirtyRegion;
// caching local regions
BRegion fBorderRegion;
bool fBorderRegionValid;
BRegion fContentRegion;
bool fContentRegionValid;
BRegion fEffectiveDrawingRegion;
bool fEffectiveDrawingRegionValid;
BObjectList<WindowLayer> fSubsets; BObjectList<WindowLayer> fSubsets;
// TODO: remove those some day (let the decorator handle that stuff)
bool fIsClosing; bool fIsClosing;
bool fIsMinimizing; bool fIsMinimizing;
bool fIsZooming; bool fIsZooming;
@@ -169,21 +244,72 @@ class WindowLayer : public Layer {
bool fIsSlidingTab; bool fIsSlidingTab;
bool fIsDragging; bool fIsDragging;
bool fBringToFrontOnRelease; // bool fBringToFrontOnRelease;
bool fUpdateRequestsEnabled; ::Decorator* fDecorator;
ViewLayer* fTopLayer;
::ServerWindow* fWindow;
DrawingEngine* fDrawingEngine;
::Desktop* fDesktop;
BPoint fLastMousePosition;
// BPoint fResizingClickOffset;
// The synchronization, which client drawing commands
// belong to the redraw of which dirty region is handled
// through an UpdateSession. When the client has
// been informed that it should redraw stuff, then
// this is the current update session. All new
// redraw requests from the Desktop will go
// into the pending update session.
class UpdateSession {
public:
UpdateSession();
virtual ~UpdateSession();
void Include(BRegion* additionalDirty);
void Exclude(BRegion* dirtyInNextSession);
inline BRegion& DirtyRegion()
{ return fDirtyRegion; }
void MoveBy(int32 x, int32 y);
void SetUsed(bool used);
inline bool IsUsed() const
{ return fInUse; }
UpdateSession& operator=(const UpdateSession& other);
private:
BRegion fDirtyRegion;
bool fInUse;
};
BRegion fDecoratorRegion;
UpdateSession fCurrentUpdateSession;
UpdateSession fPendingUpdateSession;
// these two flags are supposed to ensure a sane
// and consistent update session
bool fUpdateRequested;
bool fInUpdate; bool fInUpdate;
bool fRequestSent;
bool fHidden;
bool fIsFocus;
window_look fLook; window_look fLook;
window_feel fFeel; window_feel fFeel;
uint32 fWindowFlags; uint32 fFlags;
uint32 fWorkspaces; uint32 fWorkspaces;
int32 fCurrentWorkspace;
float fMinWidth; int32 fMinWidth;
float fMaxWidth; int32 fMaxWidth;
float fMinHeight; int32 fMinHeight;
float fMaxHeight; int32 fMaxHeight;
mutable bool fReadLocked;
}; };
#endif // WINDOW_LAYER_H #endif // WINDOW_LAYER_H
+112
View File
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#include "WindowLayer.h"
const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
window_anchor::window_anchor()
:
next(NULL),
previous(NULL),
position(kInvalidWindowPosition)
{
}
// #pragma mark -
WindowList::WindowList(int32 index)
:
fIndex(index),
fFirstWindow(NULL),
fLastWindow(NULL)
{
}
WindowList::~WindowList()
{
}
void
WindowList::SetIndex(int32 index)
{
fIndex = index;
}
void
WindowList::AddWindow(WindowLayer* window, WindowLayer* before)
{
window_anchor& windowAnchor = window->Anchor(fIndex);
if (before != NULL) {
window_anchor& beforeAnchor = before->Anchor(fIndex);
// add view before this one
windowAnchor.next = before;
windowAnchor.previous = beforeAnchor.previous;
if (windowAnchor.previous != NULL)
windowAnchor.previous->Anchor(fIndex).next = window;
beforeAnchor.previous = window;
if (fFirstWindow == before)
fFirstWindow = window;
} else {
// add view to the end of the list
if (fLastWindow != NULL) {
fLastWindow->Anchor(fIndex).next = window;
windowAnchor.previous = fLastWindow;
} else {
fFirstWindow = window;
windowAnchor.previous = NULL;
}
windowAnchor.next = NULL;
fLastWindow = window;
}
}
void
WindowList::RemoveWindow(WindowLayer* window)
{
// TODO: Axel, the same window can be removed in the same list
// more than once, would that be a bug?
window_anchor& windowAnchor = window->Anchor(fIndex);
if (fFirstWindow == window) {
// it's the first child
fFirstWindow = windowAnchor.next;
} else {
// it must have a previous sibling if it was not
// previously removed from this list
if (windowAnchor.previous)
windowAnchor.previous->Anchor(fIndex).next = windowAnchor.next;
}
if (fLastWindow == window) {
// it's the last child
fLastWindow = windowAnchor.previous;
} else {
// it must have a next sibling if it was not
// previously removed from this list
if (windowAnchor.next)
windowAnchor.next->Anchor(fIndex).previous = windowAnchor.previous;
}
windowAnchor.previous = NULL;
windowAnchor.next = NULL;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef WINDOW_LIST_H
#define WINDOW_LIST_H
#include <SupportDefs.h>
#include <Point.h>
class WindowLayer;
class WindowList {
public:
WindowList(int32 index = 0);
~WindowList();
void SetIndex(int32 index);
int32 Index() const { return fIndex; }
WindowLayer* FirstWindow() { return fFirstWindow; }
WindowLayer* LastWindow() { return fLastWindow; }
void AddWindow(WindowLayer* window, WindowLayer* before = NULL);
void RemoveWindow(WindowLayer* window);
private:
int32 fIndex;
WindowLayer* fFirstWindow;
WindowLayer* fLastWindow;
};
enum window_lists {
kAllWindowList = 32,
kFloatingList,
kWorkingList,
};
struct window_anchor {
window_anchor();
WindowLayer* next;
WindowLayer* previous;
BPoint position;
};
extern const BPoint kInvalidWindowPosition;
#endif // WINDOW_LIST_H
+14 -64
View File
@@ -7,8 +7,9 @@
*/ */
#include "RootLayer.h" #include "Desktop.h"
#include "Workspace.h" #include "Workspace.h"
#include "WorkspacePrivate.h"
#include "WindowLayer.h" #include "WindowLayer.h"
#include <math.h> #include <math.h>
@@ -17,13 +18,9 @@
static RGBColor kDefaultColor = RGBColor(51, 102, 152); static RGBColor kDefaultColor = RGBColor(51, 102, 152);
const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
Workspace::Private::Private() Workspace::Private::Private()
:
fWindows(20, true)
// this list owns its items
{ {
_SetDefaults(); _SetDefaults();
} }
@@ -34,47 +31,6 @@ Workspace::Private::~Private()
} }
bool
Workspace::Private::AddWindow(WindowLayer* window, BPoint* position)
{
window_layer_info* info = new (nothrow) window_layer_info;
if (info == NULL)
return false;
info->position = position ? *position : kInvalidWindowPosition;
info->window = window;
bool success = fWindows.AddItem(info);
if (!success)
delete info;
return success;
}
void
Workspace::Private::RemoveWindow(WindowLayer* window)
{
for (int32 i = fWindows.CountItems(); i-- > 0;) {
window_layer_info* info = fWindows.ItemAt(i);
if (info->window == window) {
fWindows.RemoveItemAt(i);
delete info;
return;
}
}
}
void
Workspace::Private::RemoveWindowAt(int32 index)
{
window_layer_info* info = fWindows.RemoveItemAt(index);
delete info;
}
void void
Workspace::Private::SetDisplaysFromDesktop(Desktop* desktop) Workspace::Private::SetDisplaysFromDesktop(Desktop* desktop)
{ {
@@ -137,26 +93,21 @@ Workspace::Color() const
status_t status_t
Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop) Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop)
{ {
if (fCurrentWorkspace) { if (fCurrent == NULL)
if (fCurrent == NULL) fCurrent = fWorkspace.Windows().FirstWindow();
fCurrent = (WindowLayer*)fDesktop.RootLayer()->FirstChild(); else
else fCurrent = fCurrent->NextWindow(fWorkspace.Index());
fCurrent = (WindowLayer*)fCurrent->NextLayer();
if (fCurrent == NULL)
return B_ENTRY_NOT_FOUND;
_window = fCurrent; if (fCurrent == NULL)
_leftTop = fCurrent->Frame().LeftTop();
return B_OK;
}
window_layer_info* info = fWorkspace.WindowAt(fIndex++);
if (info == NULL)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
_window = info->window; _window = fCurrent;
_leftTop = info->position;
if (fCurrentWorkspace)
_leftTop = fCurrent->Frame().LeftTop();
else
_leftTop = fCurrent->Anchor(fWorkspace.Index()).position;
return B_OK; return B_OK;
} }
@@ -164,7 +115,6 @@ Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop)
void void
Workspace::RewindWindows() Workspace::RewindWindows()
{ {
fIndex = 0;
fCurrent = NULL; fCurrent = NULL;
} }
-1
View File
@@ -35,7 +35,6 @@ class Workspace {
private: private:
Workspace::Private& fWorkspace; Workspace::Private& fWorkspace;
Desktop& fDesktop; Desktop& fDesktop;
int32 fIndex;
WindowLayer* fCurrent; WindowLayer* fCurrent;
bool fCurrentWorkspace; bool fCurrentWorkspace;
}; };
+5 -17
View File
@@ -10,38 +10,28 @@
#include "RGBColor.h" #include "RGBColor.h"
#include "WindowList.h"
#include "Workspace.h" #include "Workspace.h"
#include <Accelerant.h>
#include <ObjectList.h> #include <ObjectList.h>
#include <String.h> #include <String.h>
class RootLayer;
class WindowLayer;
struct display_info { struct display_info {
BString identifier; BString identifier;
BPoint origin; BPoint origin;
display_mode mode; display_mode mode;
}; };
struct window_layer_info {
BPoint position;
WindowLayer* window;
};
class Workspace::Private { class Workspace::Private {
public: public:
Private(); Private();
~Private(); ~Private();
bool AddWindow(WindowLayer* window, BPoint* point = NULL); int32 Index() const { return fWindows.Index(); }
void RemoveWindow(WindowLayer* window);
void RemoveWindowAt(int32 index);
int32 CountWindows() const { return fWindows.CountItems(); } WindowList& Windows() { return fWindows; }
window_layer_info* WindowAt(int32 index) const { return fWindows.ItemAt(index); }
// displays // displays
@@ -61,7 +51,7 @@ class Workspace::Private {
private: private:
void _SetDefaults(); void _SetDefaults();
BObjectList<window_layer_info> fWindows; WindowList fWindows;
WindowLayer* fFront; WindowLayer* fFront;
WindowLayer* fFocus; WindowLayer* fFocus;
@@ -70,6 +60,4 @@ class Workspace::Private {
RGBColor fColor; RGBColor fColor;
}; };
extern const BPoint kInvalidWindowPosition;
#endif /* WORKSPACE_PRIVATE_H */ #endif /* WORKSPACE_PRIVATE_H */
+35 -33
View File
@@ -8,20 +8,21 @@
*/ */
#include <ColorSet.h> #include "WorkspacesLayer.h"
#include <WindowPrivate.h>
#include "AppServer.h" #include "AppServer.h"
#include "Desktop.h"
#include "DrawingEngine.h" #include "DrawingEngine.h"
#include "RootLayer.h"
#include "WindowLayer.h" #include "WindowLayer.h"
#include "Workspace.h" #include "Workspace.h"
#include "WorkspacesLayer.h" #include <ColorSet.h>
#include <WindowPrivate.h>
WorkspacesLayer::WorkspacesLayer(BRect frame, const char* name, WorkspacesLayer::WorkspacesLayer(BRect frame, const char* name,
int32 token, uint32 resizeMode, uint32 flags, DrawingEngine* driver) int32 token, uint32 resizeMode, uint32 flags)
: Layer(frame, name, token, resizeMode, flags, driver) : ViewLayer(frame, name, token, resizeMode, flags)
{ {
fDrawState->SetLowColor(RGBColor(255, 255, 255)); fDrawState->SetLowColor(RGBColor(255, 255, 255));
fDrawState->SetHighColor(RGBColor(0, 0, 0)); fDrawState->SetHighColor(RGBColor(0, 0, 0));
@@ -98,7 +99,7 @@ WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame,
void void
WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame, WorkspacesLayer::_DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame,
const BRect& screenFrame, WindowLayer* window, BPoint windowPosition, const BRect& screenFrame, WindowLayer* window, BPoint windowPosition,
BRegion& backgroundRegion, bool active) BRegion& backgroundRegion, bool active)
{ {
@@ -108,12 +109,12 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
BPoint offset = window->Frame().LeftTop() - windowPosition; BPoint offset = window->Frame().LeftTop() - windowPosition;
BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame(), BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame(),
windowPosition); windowPosition);
BRect tabFrame = window->GetDecorator()->TabRect(); BRect tabFrame = window->Decorator()->TabRect();
tabFrame = _WindowFrame(workspaceFrame, screenFrame, tabFrame = _WindowFrame(workspaceFrame, screenFrame,
tabFrame, tabFrame.LeftTop() - offset); tabFrame, tabFrame.LeftTop() - offset);
// ToDo: let decorator do this! // ToDo: let decorator do this!
RGBColor yellow = window->GetDecorator()->GetColors().window_tab; RGBColor yellow = window->Decorator()->Colors().window_tab;
RGBColor gray(180, 180, 180); RGBColor gray(180, 180, 180);
RGBColor white(255, 255, 255); RGBColor white(255, 255, 255);
@@ -134,12 +135,12 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
backgroundRegion.Exclude(tabFrame); backgroundRegion.Exclude(tabFrame);
backgroundRegion.Exclude(frame); backgroundRegion.Exclude(frame);
GetDrawingEngine()->StrokeLine(tabFrame.LeftTop(), tabFrame.RightBottom(), yellow); drawingEngine->StrokeLine(tabFrame.LeftTop(), tabFrame.RightBottom(), yellow);
GetDrawingEngine()->StrokeRect(frame, gray); drawingEngine->StrokeRect(frame, gray);
frame.InsetBy(1, 1); frame.InsetBy(1, 1);
GetDrawingEngine()->FillRect(frame, white); drawingEngine->FillRect(frame, white);
// draw title // draw title
@@ -170,7 +171,7 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
void void
WorkspacesLayer::_DrawWorkspace(int32 index) WorkspacesLayer::_DrawWorkspace(DrawingEngine* drawingEngine, int32 index)
{ {
BRect rect = _WorkspaceAt(index); BRect rect = _WorkspaceAt(index);
@@ -179,7 +180,7 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
if (active) { if (active) {
// draw active frame // draw active frame
RGBColor black(0, 0, 0); RGBColor black(0, 0, 0);
GetDrawingEngine()->StrokeRect(rect, black); drawingEngine->StrokeRect(rect, black);
} }
rect.InsetBy(1, 1); rect.InsetBy(1, 1);
@@ -190,7 +191,7 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
// draw windows // draw windows
BRegion backgroundRegion = VisibleRegion(); BRegion backgroundRegion = fLocalClipping;
// ToDo: would be nice to get the real update region here // ToDo: would be nice to get the real update region here
@@ -203,23 +204,23 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
BRegion workspaceRegion(rect); BRegion workspaceRegion(rect);
backgroundRegion.IntersectWith(&workspaceRegion); backgroundRegion.IntersectWith(&workspaceRegion);
GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion); drawingEngine->ConstrainClippingRegion(&backgroundRegion);
WindowLayer* window; WindowLayer* window;
BPoint leftTop; BPoint leftTop;
while (workspace.GetNextWindow(window, leftTop) == B_OK) { while (workspace.GetNextWindow(window, leftTop) == B_OK) {
_DrawWindow(rect, screenFrame, window, leftTop, _DrawWindow(drawingEngine, rect, screenFrame, window,
backgroundRegion, active); leftTop, backgroundRegion, active);
} }
// draw background // draw background
GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion); drawingEngine->ConstrainClippingRegion(&backgroundRegion);
GetDrawingEngine()->FillRect(rect, color); drawingEngine->FillRect(rect, color);
// TODO: ConstrainClippingRegion() should accept a const parameter !! // TODO: ConstrainClippingRegion() should accept a const parameter !!
BRegion cRegion(VisibleRegion()); BRegion cRegion(fLocalClipping);
GetDrawingEngine()->ConstrainClippingRegion(&cRegion); drawingEngine->ConstrainClippingRegion(&cRegion);
} }
@@ -231,7 +232,8 @@ WorkspacesLayer::_DarkenColor(RGBColor& color) const
void void
WorkspacesLayer::Draw(const BRect& updateRect) WorkspacesLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
BRegion* windowContentClipping, bool deep)
{ {
int32 columns, rows; int32 columns, rows;
_GetGrid(columns, rows); _GetGrid(columns, rows);
@@ -241,9 +243,9 @@ WorkspacesLayer::Draw(const BRect& updateRect)
// make sure the grid around the active workspace is not drawn // make sure the grid around the active workspace is not drawn
// to reduce flicker // to reduce flicker
BRect activeRect = _WorkspaceAt(Window()->Desktop()->CurrentWorkspace()); BRect activeRect = _WorkspaceAt(Window()->Desktop()->CurrentWorkspace());
BRegion gridRegion(VisibleRegion()); BRegion gridRegion(fLocalClipping);
gridRegion.Exclude(activeRect); gridRegion.Exclude(activeRect);
GetDrawingEngine()->ConstrainClippingRegion(&gridRegion); drawingEngine->ConstrainClippingRegion(&gridRegion);
BRect frame = Frame(); BRect frame = Frame();
BPoint pt(0,0); BPoint pt(0,0);
@@ -252,33 +254,33 @@ WorkspacesLayer::Draw(const BRect& updateRect)
// horizontal lines // horizontal lines
GetDrawingEngine()->StrokeLine(BPoint(frame.left, frame.top), drawingEngine->StrokeLine(BPoint(frame.left, frame.top),
BPoint(frame.right, frame.top), ViewColor()); BPoint(frame.right, frame.top), ViewColor());
for (int32 row = 0; row < rows; row++) { for (int32 row = 0; row < rows; row++) {
BRect rect = _WorkspaceAt(row * columns); BRect rect = _WorkspaceAt(row * columns);
GetDrawingEngine()->StrokeLine(BPoint(frame.left, rect.bottom), drawingEngine->StrokeLine(BPoint(frame.left, rect.bottom),
BPoint(frame.right, rect.bottom), ViewColor()); BPoint(frame.right, rect.bottom), ViewColor());
} }
// vertical lines // vertical lines
GetDrawingEngine()->StrokeLine(BPoint(frame.left, frame.top), drawingEngine->StrokeLine(BPoint(frame.left, frame.top),
BPoint(frame.left, frame.bottom), ViewColor()); BPoint(frame.left, frame.bottom), ViewColor());
for (int32 column = 0; column < columns; column++) { for (int32 column = 0; column < columns; column++) {
BRect rect = _WorkspaceAt(column); BRect rect = _WorkspaceAt(column);
GetDrawingEngine()->StrokeLine(BPoint(rect.right, frame.top), drawingEngine->StrokeLine(BPoint(rect.right, frame.top),
BPoint(rect.right, frame.bottom), ViewColor()); BPoint(rect.right, frame.bottom), ViewColor());
} }
BRegion cRegion(VisibleRegion()); BRegion cRegion(fLocalClipping);
GetDrawingEngine()->ConstrainClippingRegion(&cRegion); drawingEngine->ConstrainClippingRegion(&cRegion);
// draw workspaces // draw workspaces
for (int32 i = rows * columns; i-- > 0;) { for (int32 i = rows * columns; i-- > 0;) {
_DrawWorkspace(i); _DrawWorkspace(drawingEngine, i);
} }
} }
@@ -298,7 +300,7 @@ WorkspacesLayer::MouseDown(BMessage* message, BPoint where, int32* _viewToken)
} }
} }
Layer::MouseDown(message, where, _viewToken); //ViewLayer::MouseDown(message, where, _viewToken);
} }
+9 -6
View File
@@ -9,18 +9,21 @@
#define WORKSPACES_LAYER_H #define WORKSPACES_LAYER_H
#include "Layer.h" #include "ViewLayer.h"
class WindowLayer; class WindowLayer;
class WorkspacesLayer : public Layer { class WorkspacesLayer : public ViewLayer {
public: public:
WorkspacesLayer(BRect frame, const char* name, int32 token, WorkspacesLayer(BRect frame, const char* name, int32 token,
uint32 resize, uint32 flags, DrawingEngine* driver); uint32 resize, uint32 flags);
virtual ~WorkspacesLayer(); virtual ~WorkspacesLayer();
virtual void Draw(const BRect& updateRect); virtual void Draw(DrawingEngine* drawingEngine,
BRegion* effectiveClipping,
BRegion* windowContentClipping,
bool deep = false);
virtual void MouseDown(BMessage* message, BPoint where, int32* _viewToken); virtual void MouseDown(BMessage* message, BPoint where, int32* _viewToken);
private: private:
@@ -30,11 +33,11 @@ class WorkspacesLayer : public Layer {
const BRect& screenFrame, const BRect& windowFrame, const BRect& screenFrame, const BRect& windowFrame,
BPoint windowPosition); BPoint windowPosition);
void _DrawWindow(const BRect& workspaceFrame, void _DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame,
const BRect& screenFrame, WindowLayer* window, const BRect& screenFrame, WindowLayer* window,
BPoint windowPosition, BRegion& backgroundRegion, BPoint windowPosition, BRegion& backgroundRegion,
bool active); bool active);
void _DrawWorkspace(int32 index); void _DrawWorkspace(DrawingEngine* drawingEngine, int32 index);
void _DarkenColor(RGBColor& color) const; void _DarkenColor(RGBColor& color) const;
}; };
+118 -87
View File
@@ -120,16 +120,16 @@ DrawingEngine::Update()
} }
} }
// SetHWInterface
void void
DrawingEngine::SetHWInterface(HWInterface* interface) DrawingEngine::SetHWInterface(HWInterface* interface)
{ {
fGraphicsCard = interface; fGraphicsCard = interface;
} }
// ConstrainClippingRegion
void void
DrawingEngine::ConstrainClippingRegion(BRegion *region) DrawingEngine::ConstrainClippingRegion(const BRegion* region)
{ {
if (Lock()) { if (Lock()) {
if (!region) { if (!region) {
@@ -377,7 +377,7 @@ DrawingEngine::CopyRegion(/*const*/ BRegion* region,
// CopyRegionList // CopyRegionList
// //
// * used to move windows arround on screen // * used to move windows around on screen
// TODO: Since the regions are passed to CopyRegion() one by one, // TODO: Since the regions are passed to CopyRegion() one by one,
// the case of different regions overlapping each other at source // the case of different regions overlapping each other at source
// and/or dest locations is not handled. // and/or dest locations is not handled.
@@ -395,7 +395,6 @@ DrawingEngine::CopyRegionList(BList* list, BList* pList,
// This needs to be investigated, I'm doing this because of // This needs to be investigated, I'm doing this because of
// gut feeling. // gut feeling.
if (WriteLock()) { if (WriteLock()) {
for (int32 i = 0; i < rCount; i++) { for (int32 i = 0; i < rCount; i++) {
BRegion* region = (BRegion*)list->ItemAt(i); BRegion* region = (BRegion*)list->ItemAt(i);
BPoint* offset = (BPoint*)pList->ItemAt(i); BPoint* offset = (BPoint*)pList->ItemAt(i);
@@ -583,7 +582,6 @@ DrawingEngine::StrokeRect(BRect r, const RGBColor &color)
make_rect_valid(r); make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r); BRect clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) { if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped); fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->StrokeRect(r, color.GetColor32()); fPainter->StrokeRect(r, color.GetColor32());
@@ -671,13 +669,12 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
r = fPainter->ClipRect(r); r = fPainter->ClipRect(r);
if (r.IsValid()) { if (r.IsValid()) {
fGraphicsCard->HideSoftwareCursor(r); fGraphicsCard->HideSoftwareCursor(r);
bool doInSoftware = true; bool doInSoftware = true;
// try hardware optimized version first // try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) && if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
(d->GetDrawingMode() == B_OP_COPY || && (d->GetDrawingMode() == B_OP_COPY
d->GetDrawingMode() == B_OP_OVER)) { || d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) { if (d->GetPattern() == B_SOLID_HIGH) {
BRegion region(r); BRegion region(r);
region.IntersectWith(fPainter->ClippingRegion()); region.IntersectWith(fPainter->ClippingRegion());
@@ -691,13 +688,12 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
} }
} }
if (doInSoftware) { if (doInSoftware) {
fPainter->SetDrawState(d); fPainter->SetDrawState(d);
fPainter->FillRect(r); fPainter->FillRect(r);
fGraphicsCard->Invalidate(r); fGraphicsCard->Invalidate(r);
} }
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -715,16 +711,16 @@ DrawingEngine::StrokeRegion(BRegion& r, const DrawState *d)
clipped = fPainter->ClipRect(clipped); clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) { if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped); fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawState(d); fPainter->SetDrawState(d);
BRect touched = fPainter->StrokeRect(r.RectAt(0)); BRect touched = fPainter->StrokeRect(r.RectAt(0));
int32 count = r.CountRects(); int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) { for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->StrokeRect(r.RectAt(i)); touched = touched | fPainter->StrokeRect(r.RectAt(i));
} }
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -744,13 +740,12 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
BRect clipped = fPainter->ClipRect(r.Frame()); BRect clipped = fPainter->ClipRect(r.Frame());
if (clipped.IsValid()) { if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped); fGraphicsCard->HideSoftwareCursor(clipped);
bool doInSoftware = true; bool doInSoftware = true;
// try hardware optimized version first // try hardware optimized version first
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) && if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
(d->GetDrawingMode() == B_OP_COPY || && (d->GetDrawingMode() == B_OP_COPY
d->GetDrawingMode() == B_OP_OVER)) { || d->GetDrawingMode() == B_OP_OVER)) {
if (d->GetPattern() == B_SOLID_HIGH) { if (d->GetPattern() == B_SOLID_HIGH) {
fGraphicsCard->FillRegion(r, d->HighColor()); fGraphicsCard->FillRegion(r, d->HighColor());
doInSoftware = false; doInSoftware = false;
@@ -759,20 +754,20 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
doInSoftware = false; doInSoftware = false;
} }
} }
if (doInSoftware) { if (doInSoftware) {
fPainter->SetDrawState(d); fPainter->SetDrawState(d);
BRect touched = fPainter->FillRect(r.RectAt(0)); BRect touched = fPainter->FillRect(r.RectAt(0));
int32 count = r.CountRects(); int32 count = r.CountRects();
for (int32 i = 1; i < count; i++) { for (int32 i = 1; i < count; i++) {
touched = touched | fPainter->FillRect(r.RectAt(i)); touched = touched | fPainter->FillRect(r.RectAt(i));
} }
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
} }
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -780,58 +775,96 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
} }
} }
// DrawRoundRect
// FillRegion
void void
DrawingEngine::DrawRoundRect(BRect r, const float &xrad, DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
const float &yrad, const DrawState *d,
bool filled)
{ {
if (Lock()) { // NOTE: Write locking because we might use HW acceleration.
// NOTE: the stroke does not extend past "r" in R5, // This needs to be investigated, I'm doing this because of
// though I consider this unexpected behaviour. // gut feeling.
make_rect_valid(r); if (WriteLock()) {
BRect clipped = fPainter->ClipRect(r); BRect clipped = fPainter->ClipRect(r.Frame());
if (clipped.IsValid()) { if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped); fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawState(d); bool doInSoftware = true;
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad) // try hardware optimized version first
: fPainter->StrokeRoundRect(r, xrad, yrad); if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
fGraphicsCard->FillRegion(r, color);
fGraphicsCard->Invalidate(touched); doInSoftware = false;
}
if (doInSoftware) {
int32 count = r.CountRects();
for (int32 i = 0; i < count; i++) {
fPainter->FillRect(r.RectAt(i), color.GetColor32());
}
BRect touched = r.Frame();
fGraphicsCard->Invalidate(touched);
}
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
Unlock(); WriteUnlock();
} }
} }
// DrawShape
void void
DrawingEngine::DrawShape(const BRect& bounds, const int32& opCount, DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
const uint32* opList, const int32& ptCount, const DrawState* d, bool filled)
const BPoint* ptList, const DrawState* d,
bool filled)
{ {
if (Lock()) { if (!Lock())
fGraphicsCard->HideSoftwareCursor(); return;
// NOTE: the stroke does not extend past "r" in R5,
// though I consider this unexpected behaviour.
make_rect_valid(r);
BRect clipped = fPainter->ClipRect(r);
if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawState(d); fPainter->SetDrawState(d);
BRect touched = fPainter->DrawShape(opCount, opList, BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
ptCount, ptList, : fPainter->StrokeRoundRect(r, xrad, yrad);
filled);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
Unlock();
} }
Unlock();
} }
// DrawTriangle
void
DrawingEngine::DrawShape(const BRect& bounds, int32 opCount,
const uint32* opList, int32 ptCount, const BPoint* ptList,
const DrawState* d, bool filled)
{
if (!Lock())
return;
fGraphicsCard->HideSoftwareCursor();
fPainter->SetDrawState(d);
BRect touched = fPainter->DrawShape(opCount, opList,
ptCount, ptList,
filled);
fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor();
Unlock();
}
void void
DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds, DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
const DrawState* d, bool filled) const DrawState* d, bool filled)
{ {
if (Lock()) { if (Lock()) {
BRect clipped(bounds); BRect clipped(bounds);
@@ -840,13 +873,13 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
clipped = fPainter->ClipRect(clipped); clipped = fPainter->ClipRect(clipped);
if (clipped.IsValid()) { if (clipped.IsValid()) {
fGraphicsCard->HideSoftwareCursor(clipped); fGraphicsCard->HideSoftwareCursor(clipped);
fPainter->SetDrawState(d); fPainter->SetDrawState(d);
if (filled) if (filled)
fPainter->FillTriangle(pts[0], pts[1], pts[2]); fPainter->FillTriangle(pts[0], pts[1], pts[2]);
else else
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]); fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
fGraphicsCard->Invalidate(clipped); fGraphicsCard->Invalidate(clipped);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -892,9 +925,9 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
if (touched.IsValid()) { if (touched.IsValid()) {
fGraphicsCard->HideSoftwareCursor(touched); fGraphicsCard->HideSoftwareCursor(touched);
touched = fPainter->StrokeLine(start, end, context); touched = fPainter->StrokeLine(start, end, context);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -905,13 +938,12 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
// StrokeLineArray // StrokeLineArray
void void
DrawingEngine::StrokeLineArray(const int32 &numlines, DrawingEngine::StrokeLineArray(int32 numLines,
const LineArrayData *linedata, const LineArrayData *linedata, const DrawState *d)
const DrawState *d)
{ {
if(!d || !linedata || numlines <= 0) if (!d || !linedata || numLines <= 0)
return; return;
if (Lock()) { if (Lock()) {
// figure out bounding box for line array // figure out bounding box for line array
const LineArrayData *data = (const LineArrayData *)&(linedata[0]); const LineArrayData *data = (const LineArrayData *)&(linedata[0]);
@@ -919,7 +951,8 @@ DrawingEngine::StrokeLineArray(const int32 &numlines,
min_c(data->pt1.y, data->pt2.y), min_c(data->pt1.y, data->pt2.y),
max_c(data->pt1.x, data->pt2.x), max_c(data->pt1.x, data->pt2.x),
max_c(data->pt1.y, data->pt2.y)); max_c(data->pt1.y, data->pt2.y));
for (int32 i = 1; i < numlines; i++) {
for (int32 i = 1; i < numLines; i++) {
data = (const LineArrayData *)&(linedata[i]); data = (const LineArrayData *)&(linedata[i]);
BRect box(min_c(data->pt1.x, data->pt2.x), BRect box(min_c(data->pt1.x, data->pt2.x),
min_c(data->pt1.y, data->pt2.y), min_c(data->pt1.y, data->pt2.y),
@@ -931,20 +964,20 @@ DrawingEngine::StrokeLineArray(const int32 &numlines,
touched = fPainter->ClipRect(touched); touched = fPainter->ClipRect(touched);
if (touched.IsValid()) { if (touched.IsValid()) {
fGraphicsCard->HideSoftwareCursor(touched); fGraphicsCard->HideSoftwareCursor(touched);
DrawState context; DrawState context;
context.SetDrawingMode(B_OP_COPY); context.SetDrawingMode(B_OP_COPY);
data = (const LineArrayData *)&(linedata[0]); data = (const LineArrayData *)&(linedata[0]);
context.SetHighColor(data->color); context.SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2, &context); fPainter->StrokeLine(data->pt1, data->pt2, &context);
for (int32 i = 1; i < numlines; i++) { for (int32 i = 1; i < numLines; i++) {
data = (const LineArrayData *)&(linedata[i]); data = (const LineArrayData *)&(linedata[i]);
context.SetHighColor(data->color); context.SetHighColor(data->color);
fPainter->StrokeLine(data->pt1, data->pt2, &context); fPainter->StrokeLine(data->pt1, data->pt2, &context);
} }
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -1007,11 +1040,11 @@ DrawingEngine::DrawString(const char* string, int32 length,
if (b.IsValid()) { if (b.IsValid()) {
//printf("bounding box '%s': %lld µs\n", string, system_time() - now); //printf("bounding box '%s': %lld µs\n", string, system_time() - now);
fGraphicsCard->HideSoftwareCursor(b); fGraphicsCard->HideSoftwareCursor(b);
//now = system_time(); //now = system_time();
BRect touched = fPainter->DrawString(string, length, pt, delta); BRect touched = fPainter->DrawString(string, length, pt, delta);
//printf("drawing string: %lld µs\n", system_time() - now); //printf("drawing string: %lld µs\n", system_time() - now);
fGraphicsCard->Invalidate(touched); fGraphicsCard->Invalidate(touched);
fGraphicsCard->ShowSoftwareCursor(); fGraphicsCard->ShowSoftwareCursor();
} }
@@ -1119,22 +1152,20 @@ DrawingEngine::DumpToBitmap()
return NULL; return NULL;
} }
// _CopyRect
BRect BRect
DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
{ {
BRect dst; BRect dst;
RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer(); RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer();
if (buffer) { if (buffer) {
BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1); BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1);
dst = src; dst = src;
dst.OffsetBy(xOffset, yOffset); dst.OffsetBy(xOffset, yOffset);
if (clip.Intersects(src) && clip.Intersects(dst)) { if (clip.Intersects(src) && clip.Intersects(dst)) {
uint32 bytesPerRow = buffer->BytesPerRow();
uint32 bpr = buffer->BytesPerRow();
uint8* bits = (uint8*)buffer->Bits(); uint8* bits = (uint8*)buffer->Bits();
// clip source rect // clip source rect
@@ -1146,12 +1177,12 @@ DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
src = src & dst; src = src & dst;
// calc offset in buffer // calc offset in buffer
bits += (int32)src.left * 4 + (int32)src.top * bpr; bits += (int32)src.left * 4 + (int32)src.top * bytesPerRow;
uint32 width = src.IntegerWidth() + 1; uint32 width = src.IntegerWidth() + 1;
uint32 height = src.IntegerHeight() + 1; uint32 height = src.IntegerHeight() + 1;
_CopyRect(bits, width, height, bpr, xOffset, yOffset); _CopyRect(bits, width, height, bytesPerRow, xOffset, yOffset);
// offset dest again, because it is return value // offset dest again, because it is return value
dst.OffsetBy(xOffset, yOffset); dst.OffsetBy(xOffset, yOffset);
@@ -1160,10 +1191,10 @@ DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
return dst; return dst;
} }
// _CopyRect
void void
DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height, DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
uint32 bpr, int32 xOffset, int32 yOffset) const uint32 bytesPerRow, int32 xOffset, int32 yOffset) const
{ {
int32 xIncrement; int32 xIncrement;
int32 yIncrement; int32 yIncrement;
@@ -1179,14 +1210,14 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
if (yOffset > 0) { if (yOffset > 0) {
// copy from bottom to top // copy from bottom to top
yIncrement = -bpr; yIncrement = -bytesPerRow;
src += (height - 1) * bpr; src += (height - 1) * bytesPerRow;
} else { } else {
// copy from top to bottom // copy from top to bottom
yIncrement = bpr; yIncrement = bytesPerRow;
} }
uint8* dst = src + yOffset * bpr + xOffset * 4; uint8* dst = src + yOffset * bytesPerRow + xOffset * 4;
for (uint32 y = 0; y < height; y++) { for (uint32 y = 0; y < height; y++) {
uint32* srcHandle = (uint32*)src; uint32* srcHandle = (uint32*)src;
@@ -231,9 +231,9 @@ AGGTextRenderer::RenderString(const char* string,
// by the x y location of the glyph along the base line, // by the x y location of the glyph along the base line,
// it is therefor yet "untransformed". // it is therefor yet "untransformed".
const agg::rect& r = glyph->bounds; const agg::rect& r = glyph->bounds;
BRect glyphBounds(r.x1 + x, r.y1 + y - 1, r.x2 + x + 1, r.y2 + y); BRect glyphBounds(r.x1 + x, r.y1 + y - 1, r.x2 + x + 1, r.y2 + y + 1);
// NOTE: "- 1"/"+ 1" fixes some weird problem with the bounding box // NOTE: "-1"/"+ 1" converts the glyph bounding box from pixel
// might be a bug in AGG // indices to pixel area coordinates
// track bounding box // track bounding box
if (glyphBounds.IsValid()) if (glyphBounds.IsValid())
+2 -3
View File
@@ -77,7 +77,6 @@ Server haiku_app_server :
# Misc. Sources # Misc. Sources
Decorator.cpp Decorator.cpp
DebugInfoManager.cpp DebugInfoManager.cpp
SubWindowList.cpp
PNGDump.cpp PNGDump.cpp
RAMLinkMsgReader.cpp RAMLinkMsgReader.cpp
MessageLooper.cpp MessageLooper.cpp
@@ -108,13 +107,13 @@ Server haiku_app_server :
VirtualScreen.cpp VirtualScreen.cpp
BitmapHWInterface.cpp BitmapHWInterface.cpp
DefaultDecorator.cpp DefaultDecorator.cpp
Layer.cpp
OffscreenServerWindow.cpp OffscreenServerWindow.cpp
OffscreenWindowLayer.cpp OffscreenWindowLayer.cpp
RootLayer.cpp
ServerPicture.cpp ServerPicture.cpp
ServerScreen.cpp ServerScreen.cpp
ViewLayer.cpp
WindowLayer.cpp WindowLayer.cpp
WindowList.cpp
Workspace.cpp Workspace.cpp
WorkspacesLayer.cpp WorkspacesLayer.cpp