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:
@@ -80,16 +80,15 @@ class Decorator {
|
||||
bool GetMinimize();
|
||||
bool GetZoom();
|
||||
|
||||
virtual void GetSizeLimits(float* minWidth, float* minHeight,
|
||||
float* maxWidth, float* maxHeight) const;
|
||||
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const;
|
||||
|
||||
|
||||
void SetFocus(bool is_active);
|
||||
bool GetFocus()
|
||||
void SetFocus(bool focussed);
|
||||
bool IsFocus()
|
||||
{ return fIsFocused; };
|
||||
ColorSet GetColors()
|
||||
ColorSet Colors()
|
||||
{ return (_colors) ? *_colors : ColorSet(); }
|
||||
|
||||
|
||||
virtual void GetFootprint(BRegion *region);
|
||||
|
||||
virtual click_type Clicked(BPoint pt, int32 buttons,
|
||||
|
||||
@@ -28,8 +28,7 @@ class ServerBitmap;
|
||||
class ServerCursor;
|
||||
class ServerFont;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
BPoint pt1;
|
||||
BPoint pt2;
|
||||
rgb_color color;
|
||||
@@ -38,176 +37,134 @@ typedef struct
|
||||
|
||||
class DrawingEngine {
|
||||
public:
|
||||
DrawingEngine(HWInterface* interface = NULL);
|
||||
virtual ~DrawingEngine();
|
||||
DrawingEngine(HWInterface* interface = NULL);
|
||||
virtual ~DrawingEngine();
|
||||
|
||||
// when implementing, be sure to call the inherited version
|
||||
status_t Initialize();
|
||||
void Shutdown();
|
||||
status_t Initialize();
|
||||
void Shutdown();
|
||||
|
||||
// locking
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
bool Lock();
|
||||
void Unlock();
|
||||
|
||||
bool WriteLock();
|
||||
void WriteUnlock();
|
||||
bool WriteLock();
|
||||
void WriteUnlock();
|
||||
|
||||
// for "changing" hardware
|
||||
void Update();
|
||||
void Update();
|
||||
|
||||
void SetHWInterface(HWInterface* interface);
|
||||
void SetHWInterface(HWInterface* interface);
|
||||
|
||||
// for screen shots
|
||||
bool DumpToFile( const char *path);
|
||||
ServerBitmap* DumpToBitmap();
|
||||
bool DumpToFile(const char *path);
|
||||
ServerBitmap* DumpToBitmap();
|
||||
|
||||
|
||||
// clipping for all drawing functions, passing a NULL region
|
||||
// will remove any clipping (drawing allowed everywhere)
|
||||
void ConstrainClippingRegion(BRegion* region);
|
||||
void ConstrainClippingRegion(const BRegion* region);
|
||||
|
||||
// drawing functions
|
||||
void CopyRegion( /*const*/ BRegion* region,
|
||||
int32 xOffset,
|
||||
int32 yOffset);
|
||||
void CopyRegion(/*const*/ BRegion* region,
|
||||
int32 xOffset, int32 yOffset);
|
||||
|
||||
void CopyRegionList( BList* list,
|
||||
BList* pList,
|
||||
int32 rCount,
|
||||
BRegion* clipReg);
|
||||
void CopyRegionList(BList* list, BList* pList,
|
||||
int32 rCount, BRegion* clipReg);
|
||||
|
||||
void InvertRect( BRect r);
|
||||
void InvertRect(BRect r);
|
||||
|
||||
void DrawBitmap( ServerBitmap *bitmap,
|
||||
const BRect &source,
|
||||
const BRect &dest,
|
||||
const DrawState *d);
|
||||
void DrawBitmap(ServerBitmap *bitmap,
|
||||
const BRect &source, const BRect &dest,
|
||||
const DrawState *d);
|
||||
// drawing primitives
|
||||
|
||||
void DrawArc( BRect r,
|
||||
const float &angle,
|
||||
const float &span,
|
||||
const DrawState *d,
|
||||
bool filled);
|
||||
void DrawArc(BRect r, const float &angle,
|
||||
const float &span,
|
||||
const DrawState *d,
|
||||
bool filled);
|
||||
|
||||
void DrawBezier( BPoint *pts,
|
||||
const DrawState *d,
|
||||
bool filled);
|
||||
void DrawBezier(BPoint *pts, const DrawState *d,
|
||||
bool filled);
|
||||
|
||||
void DrawEllipse( BRect r,
|
||||
const DrawState *d,
|
||||
bool filled);
|
||||
void DrawEllipse(BRect r, const DrawState *d,
|
||||
bool filled);
|
||||
|
||||
void DrawPolygon( BPoint *ptlist,
|
||||
int32 numpts,
|
||||
BRect bounds,
|
||||
const DrawState *d,
|
||||
bool filled,
|
||||
bool closed);
|
||||
void DrawPolygon(BPoint *ptlist, int32 numpts,
|
||||
BRect bounds, const DrawState *d,
|
||||
bool filled, bool closed);
|
||||
|
||||
// this version used by Decorator
|
||||
void StrokeRect( BRect r,
|
||||
const RGBColor &color);
|
||||
void StrokeRect(BRect r, const RGBColor &color);
|
||||
void FillRect(BRect r, const RGBColor &color);
|
||||
|
||||
void FillRect( BRect r,
|
||||
const RGBColor &color);
|
||||
|
||||
void StrokeRect( BRect r,
|
||||
const DrawState *d);
|
||||
|
||||
void FillRect( BRect r,
|
||||
const DrawState *d);
|
||||
void StrokeRect(BRect r, const DrawState *d);
|
||||
void FillRect(BRect r, const DrawState *d);
|
||||
|
||||
// for debugging purposes?
|
||||
void StrokeRegion( BRegion &r,
|
||||
const DrawState *d);
|
||||
void StrokeRegion(BRegion &r, const DrawState *d);
|
||||
void FillRegion(BRegion &r, const DrawState *d);
|
||||
void FillRegion(BRegion &r, const RGBColor& color);
|
||||
|
||||
void FillRegion( BRegion &r,
|
||||
const DrawState *d);
|
||||
void DrawRoundRect(BRect r, float xrad,
|
||||
float yrad, const DrawState *d,
|
||||
bool filled);
|
||||
|
||||
void DrawRoundRect( BRect r,
|
||||
const float &xrad,
|
||||
const float &yrad,
|
||||
const DrawState *d,
|
||||
bool filled);
|
||||
void DrawShape(const BRect &bounds,
|
||||
int32 opcount, const uint32 *oplist,
|
||||
int32 ptcount, const BPoint *ptlist,
|
||||
const DrawState *d, bool filled);
|
||||
|
||||
void DrawShape( const BRect &bounds,
|
||||
const int32 &opcount,
|
||||
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);
|
||||
void DrawTriangle(BPoint *pts, const BRect &bounds,
|
||||
const DrawState *d, bool filled);
|
||||
|
||||
// this version used by Decorator
|
||||
void StrokeLine( const BPoint &start,
|
||||
const BPoint &end,
|
||||
const RGBColor &color);
|
||||
void StrokeLine(const BPoint &start,
|
||||
const BPoint &end, const RGBColor &color);
|
||||
|
||||
void StrokeLine( const BPoint &start,
|
||||
const BPoint &end,
|
||||
DrawState *d);
|
||||
void StrokeLine(const BPoint &start,
|
||||
const BPoint &end, DrawState *d);
|
||||
|
||||
void StrokeLineArray(const int32 &numlines,
|
||||
const LineArrayData *data,
|
||||
const DrawState *d);
|
||||
void StrokeLineArray(int32 numlines,
|
||||
const LineArrayData *data,
|
||||
const DrawState *d);
|
||||
|
||||
// this version used by Decorator
|
||||
void StrokePoint( const BPoint &pt,
|
||||
const RGBColor &color);
|
||||
void StrokePoint(const BPoint &pt,
|
||||
const RGBColor &color);
|
||||
|
||||
void StrokePoint( const BPoint &pt,
|
||||
DrawState *d);
|
||||
void StrokePoint(const BPoint &pt,
|
||||
DrawState *d);
|
||||
|
||||
// -------- text related calls
|
||||
|
||||
|
||||
// DrawState is NOT const because this call updates the pen position in the passed DrawState
|
||||
BPoint DrawString( const char* string,
|
||||
int32 length,
|
||||
const BPoint& pt,
|
||||
DrawState* d,
|
||||
escapement_delta* delta = NULL);
|
||||
BPoint DrawString(const char* string, int32 length,
|
||||
const BPoint& pt, DrawState* d,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
/* void DrawString( const char *string,
|
||||
const int32 &length,
|
||||
const BPoint &pt,
|
||||
const RGBColor &color,
|
||||
escapement_delta *delta=NULL);*/
|
||||
float StringWidth(const char* string, int32 length,
|
||||
const DrawState* d,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const DrawState* d,
|
||||
escapement_delta* delta = NULL);
|
||||
float StringWidth(const char* string,
|
||||
int32 length, const ServerFont& font,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const ServerFont& font,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
float StringHeight( const char* string,
|
||||
int32 length,
|
||||
const DrawState* d);
|
||||
float StringHeight(const char* string,
|
||||
int32 length, const DrawState* d);
|
||||
|
||||
private:
|
||||
BRect _CopyRect( BRect r,
|
||||
int32 xOffset,
|
||||
int32 yOffset) const;
|
||||
BRect _CopyRect(BRect r, int32 xOffset,
|
||||
int32 yOffset) const;
|
||||
|
||||
void _CopyRect( uint8* bits,
|
||||
uint32 width,
|
||||
uint32 height,
|
||||
uint32 bpr,
|
||||
int32 xOffset,
|
||||
int32 yOffset) const;
|
||||
void _CopyRect(uint8* bits, uint32 width,
|
||||
uint32 height, uint32 bytesPerRow,
|
||||
int32 xOffset, int32 yOffset) const;
|
||||
|
||||
Painter* fPainter;
|
||||
HWInterface* fGraphicsCard;
|
||||
uint32 fAvailableHWAccleration;
|
||||
Painter* fPainter;
|
||||
HWInterface* fGraphicsCard;
|
||||
uint32 fAvailableHWAccleration;
|
||||
};
|
||||
|
||||
#endif // DRAWING_ENGINE_H_
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#include "FontManager.h"
|
||||
#include "HWInterface.h"
|
||||
#include "InputManager.h"
|
||||
#include "Layer.h"
|
||||
//#include "Layer.h"
|
||||
#include "RGBColor.h"
|
||||
#include "RegistrarDefs.h"
|
||||
#include "RootLayer.h"
|
||||
//#include "RootLayer.h"
|
||||
#include "ScreenManager.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerConfig.h"
|
||||
|
||||
+253
-311
@@ -6,11 +6,11 @@
|
||||
* John Walker <[email protected]>
|
||||
* DarkWyrm <[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
|
||||
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
|
||||
@@ -49,8 +49,8 @@
|
||||
#define ESent ((ssize_t) (-(((1L << (sizeof(ssize_t) * 8 - 2)) - 1) * 2) - 2))
|
||||
|
||||
|
||||
MemPool::MemPool()
|
||||
: fTotalAlloced(0),
|
||||
MemPool::MemPool(int32 incrementSize)
|
||||
: fTotalAllocated(0),
|
||||
fGetCount(0),
|
||||
fReleaseCount(0),
|
||||
fNumpblk(0),
|
||||
@@ -58,7 +58,7 @@ MemPool::MemPool()
|
||||
fNumprel(0),
|
||||
fNumdget(0),
|
||||
fNumdrel(0),
|
||||
fExpIncr(0),
|
||||
fIncrementSize(incrementSize),
|
||||
fPoolLength(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;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
if (size < (ssize_t)SizeQ)
|
||||
{
|
||||
if (size < (ssize_t)SizeQ) {
|
||||
// Need at least room for the queue links.
|
||||
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
|
||||
// a loop around the allocation process to allow compaction to
|
||||
// intervene in case we don't find a suitable buffer in the chain.
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
b = fFreeList.ql.flink;
|
||||
best = &fFreeList;
|
||||
|
||||
|
||||
|
||||
// Scan the free list searching for the first buffer big enough
|
||||
// to hold the requested size buffer.
|
||||
|
||||
while (b != &fFreeList)
|
||||
{
|
||||
if (b->bh.bsize >= size)
|
||||
{
|
||||
if ((best == &fFreeList) || (b->bh.bsize < best->bh.bsize))
|
||||
{
|
||||
|
||||
while (b != &fFreeList) {
|
||||
if (b->bh.bsize >= size) {
|
||||
if ((best == &fFreeList) || (b->bh.bsize < best->bh.bsize)) {
|
||||
best = b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
b = b->ql.flink; // Link to next buffer
|
||||
}
|
||||
b = best;
|
||||
|
||||
while (b != &fFreeList)
|
||||
{
|
||||
if ((ssize_t) b->bh.bsize >= size)
|
||||
{
|
||||
|
||||
|
||||
while (b != &fFreeList) {
|
||||
if ((ssize_t) b->bh.bsize >= size) {
|
||||
// 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
|
||||
// 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
|
||||
// to the caller in its entirety. We only split the buffer if enough room
|
||||
// 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;
|
||||
|
||||
|
||||
ba = BH(((char *) b) + (b->bh.bsize - size));
|
||||
bn = BH(((char *) ba) + size);
|
||||
assert(bn->prevfree == b->bh.bsize);
|
||||
|
||||
|
||||
// Subtract size from length of free block.
|
||||
b->bh.bsize -= size;
|
||||
|
||||
|
||||
// Link allocated buffer to the previous free buffer.
|
||||
ba->prevfree = b->bh.bsize;
|
||||
|
||||
|
||||
// Plug negative size into user buffer.
|
||||
ba->bsize = -(ssize_t) size;
|
||||
|
||||
|
||||
// Mark buffer after this one not preceded by free block.
|
||||
bn->prevfree = 0;
|
||||
|
||||
fTotalAlloced += size;
|
||||
|
||||
fTotalAllocated += size;
|
||||
fGetCount++; // Increment number of GetBuffer() calls
|
||||
|
||||
buf = (void *) ((((char *) ba) + sizeof(struct bhead)));
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return (void *)((((char *)ba) + sizeof(struct bhead)));
|
||||
} else {
|
||||
struct bhead *ba;
|
||||
|
||||
ba = BH(((char *) b) + b->bh.bsize);
|
||||
assert(ba->prevfree == b->bh.bsize);
|
||||
|
||||
|
||||
// The buffer isn't big enough to split. Give the whole
|
||||
// shebang to the caller and remove it from the free list.
|
||||
|
||||
|
||||
assert(b->ql.blink->ql.flink == b);
|
||||
assert(b->ql.flink->ql.blink == b);
|
||||
b->ql.blink->ql.flink = b->ql.flink;
|
||||
b->ql.flink->ql.blink = b->ql.blink;
|
||||
|
||||
fTotalAlloced += b->bh.bsize;
|
||||
|
||||
fTotalAllocated += b->bh.bsize;
|
||||
fGetCount++; // Increment number of GetBuffer() calls
|
||||
|
||||
|
||||
// Negate size to mark buffer allocated.
|
||||
b->bh.bsize = -(b->bh.bsize);
|
||||
|
||||
|
||||
// Zero the back pointer in the next buffer in memory
|
||||
// to indicate that this buffer is allocated.
|
||||
ba->prevfree = 0;
|
||||
|
||||
|
||||
// Give user buffer starting at queue links.
|
||||
buf = (void *) &(b->ql);
|
||||
return buf;
|
||||
return (void *)&(b->ql);
|
||||
}
|
||||
}
|
||||
b = b->ql.flink; // Link to next buffer
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We failed to find a buffer. If there's a compact function
|
||||
// defined, notify it of the size requested. If it returns
|
||||
// TRUE, try the allocation again.
|
||||
|
||||
if(!CompactMem(size, ++compactseq))
|
||||
|
||||
if (!CompactMem(size, ++compactseq))
|
||||
break;
|
||||
}
|
||||
|
||||
// No buffer available with requested size free.
|
||||
|
||||
// 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
|
||||
// block. Try to satisy it by a direct buffer acquisition.
|
||||
struct bdhead *bdh;
|
||||
|
||||
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
|
||||
// of its header to zero.
|
||||
bdh->bh.bsize = 0;
|
||||
bdh->bh.prevfree = 0;
|
||||
bdh->tsize = size;
|
||||
|
||||
fTotalAlloced += size;
|
||||
|
||||
|
||||
fTotalAllocated += size;
|
||||
|
||||
// Increment number of GetBuffer() calls
|
||||
fGetCount++;
|
||||
|
||||
|
||||
// Direct GetBuffer() call count
|
||||
fNumdget++;
|
||||
|
||||
buf = (void *) (bdh + 1);
|
||||
return buf;
|
||||
|
||||
return (void *)(bdh + 1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Try to obtain a new expansion block
|
||||
} else {
|
||||
// Try to obtain a new expansion block
|
||||
void *newpool;
|
||||
|
||||
if ((newpool = AcquireMem((ssize_t) fExpIncr)) != NULL)
|
||||
{
|
||||
AddToPool(newpool, fExpIncr);
|
||||
|
||||
// This can't, I say, can't get into a loop
|
||||
buf = GetBuffer(requested_size);
|
||||
if ((newpool = AcquireMem((ssize_t)fIncrementSize)) != NULL) {
|
||||
AddToPool(newpool, fIncrementSize);
|
||||
|
||||
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;
|
||||
|
||||
// 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
|
||||
// buffer to grow into adjacent free blocks and to avoid moving data unnecessarily.
|
||||
/*!
|
||||
Reallocate a buffer. This is a minimal implementation, simply in terms
|
||||
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*
|
||||
MemPool::ReallocateBuffer(void *buf, ssize_t size)
|
||||
{
|
||||
void *nbuf;
|
||||
|
||||
// Old size of buffer
|
||||
ssize_t osize;
|
||||
struct bhead *b;
|
||||
void *nbuf;
|
||||
|
||||
if ((nbuf = GetBuffer(size)) == NULL)
|
||||
{
|
||||
// Acquire new buffer
|
||||
// Old size of buffer
|
||||
ssize_t osize;
|
||||
struct bhead *b;
|
||||
|
||||
if ((nbuf = GetBuffer(size)) == NULL) {
|
||||
// Acquire new buffer
|
||||
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.
|
||||
struct bdhead *bd;
|
||||
|
||||
|
||||
bd = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||
osize = bd->tsize - sizeof(struct bdhead);
|
||||
}
|
||||
else
|
||||
} else
|
||||
osize -= sizeof(struct bhead);
|
||||
assert(osize > 0);
|
||||
|
||||
// Copy the data
|
||||
memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize));
|
||||
ReleaseBuffer(buf);
|
||||
return nbuf;
|
||||
|
||||
assert(osize > 0);
|
||||
|
||||
// Copy the data
|
||||
memcpy((char *) nbuf, (char *) buf, (int) ((size < osize) ? size : osize));
|
||||
ReleaseBuffer(buf);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
// BREL -- Release a buffer.
|
||||
|
||||
//! Release a buffer.
|
||||
void
|
||||
MemPool::ReleaseBuffer(void *buf)
|
||||
{
|
||||
struct bfhead *b, *bn;
|
||||
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
|
||||
// Increment number of ReleaseBuffer() calls
|
||||
fReleaseCount++;
|
||||
b = BFH(((char *)buf) - sizeof(struct bhead));
|
||||
|
||||
// Increment number of ReleaseBuffer() calls
|
||||
fReleaseCount++;
|
||||
|
||||
assert(buf != NULL);
|
||||
|
||||
assert(buf != NULL);
|
||||
|
||||
// Directly-acquired buffer?
|
||||
if (b->bh.bsize == 0)
|
||||
{
|
||||
if (b->bh.bsize == 0) {
|
||||
struct bdhead *bdh;
|
||||
|
||||
bdh = BDH(((char *) buf) - sizeof(struct bdhead));
|
||||
|
||||
bdh = BDH(((char *)buf) - sizeof(struct bdhead));
|
||||
assert(b->bh.prevfree == 0);
|
||||
|
||||
fTotalAlloced -= bdh->tsize;
|
||||
assert(fTotalAlloced >= 0);
|
||||
|
||||
|
||||
fTotalAllocated -= bdh->tsize;
|
||||
assert(fTotalAllocated >= 0);
|
||||
|
||||
// Number of direct releases
|
||||
fNumdrel++;
|
||||
|
||||
memset((char *) buf, 0x55, (int) (bdh->tsize - sizeof(struct bdhead)));
|
||||
|
||||
|
||||
memset((char *)buf, 0x55, (int)(bdh->tsize - sizeof(struct bdhead)));
|
||||
|
||||
// Release it directly.
|
||||
ReleaseMem((void *) bdh);
|
||||
ReleaseMem((void *)bdh);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Buffer size must be negative, indicating that the buffer is allocated.
|
||||
if (b->bh.bsize >= 0)
|
||||
{
|
||||
// Buffer size must be negative, indicating that the buffer is allocated.
|
||||
if (b->bh.bsize >= 0)
|
||||
bn = NULL;
|
||||
}
|
||||
assert(b->bh.bsize < 0);
|
||||
|
||||
// Back pointer in next buffer must be zero, indicating the same thing:
|
||||
assert(BH((char *) b - b->bh.bsize)->prevfree == 0);
|
||||
assert(b->bh.bsize < 0);
|
||||
|
||||
fTotalAlloced += b->bh.bsize;
|
||||
assert(fTotalAlloced >= 0);
|
||||
// Back pointer in next buffer must be zero, indicating the same thing:
|
||||
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
|
||||
// by adding the length of this buffer to the previous free
|
||||
// buffer. Note that we subtract the size in the buffer being
|
||||
// released, since it's negative to indicate that the buffer is allocated.
|
||||
|
||||
|
||||
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);
|
||||
b = BFH(((char *) b) - b->bh.prevfree);
|
||||
b->bh.bsize -= size;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// The previous buffer isn't allocated. Insert this buffer on the
|
||||
// free list as an isolated free block.
|
||||
assert(fFreeList.ql.blink->ql.flink == &fFreeList);
|
||||
@@ -404,16 +372,15 @@ MemPool::ReleaseBuffer(void *buf)
|
||||
fFreeList.ql.blink = b;
|
||||
b->ql.blink->ql.flink = b;
|
||||
b->bh.bsize = -b->bh.bsize;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// free. If it is, we combine this buffer with the next one in
|
||||
// memory, dechaining the second buffer from the free list.
|
||||
|
||||
bn = BFH(((char *) b) + b->bh.bsize);
|
||||
if (bn->bh.bsize > 0)
|
||||
{
|
||||
bn = BFH(((char *) b) + b->bh.bsize);
|
||||
if (bn->bh.bsize > 0) {
|
||||
// The buffer is free. Remove it from the free list and add
|
||||
// its size to that of our buffer.
|
||||
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.flink->ql.blink = bn->ql.blink;
|
||||
b->bh.bsize += bn->bh.bsize;
|
||||
|
||||
|
||||
// Finally, advance to the buffer that follows the newly
|
||||
// consolidated free block. We must set its backpointer to the
|
||||
// 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
|
||||
// memory.
|
||||
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
|
||||
// to this buffer; the previous free buffer in memory.
|
||||
bn->bh.prevfree = b->bh.bsize;
|
||||
// The next buffer is allocated. Set the backpointer in it to point
|
||||
// to this buffer; the previous free buffer in memory.
|
||||
bn->bh.prevfree = b->bh.bsize;
|
||||
|
||||
// If a block-release function is defined, and this free buffer
|
||||
// constitutes the entire block, release it. Note that fPoolLength
|
||||
// is defined in such a way that the test will fail unless all
|
||||
// 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(BH((char *) b + b->bh.bsize)->bsize == ESent);
|
||||
assert(BH((char *) b + b->bh.bsize)->prevfree == b->bh.bsize);
|
||||
|
||||
|
||||
// Unlink the buffer from the free list
|
||||
b->ql.blink->ql.flink = b->ql.flink;
|
||||
b->ql.flink->ql.blink = b->ql.blink;
|
||||
|
||||
|
||||
ReleaseMem(b);
|
||||
|
||||
|
||||
// Nr of expansion block releases
|
||||
fNumprel++;
|
||||
|
||||
|
||||
// Total number of blocks
|
||||
fNumpblk--;
|
||||
assert(fNumpblk == fNumpget - fNumprel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a region of memory to the buffer pool.
|
||||
|
||||
//! Add a region of memory to the buffer pool.
|
||||
void
|
||||
MemPool::AddToPool(void *buffer, ssize_t length)
|
||||
{
|
||||
@@ -518,7 +486,8 @@ MemPool::AddToPool(void *buffer, ssize_t length)
|
||||
length -= sizeof(struct bhead);
|
||||
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);
|
||||
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
|
||||
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;
|
||||
*nrel = fReleaseCount;
|
||||
*curalloc = fTotalAlloced;
|
||||
*totfree = 0;
|
||||
*maxfree = -1;
|
||||
while (b != &fFreeList)
|
||||
{
|
||||
*nget = fGetCount;
|
||||
*nrel = fReleaseCount;
|
||||
*curalloc = fTotalAllocated;
|
||||
*totfree = 0;
|
||||
*maxfree = -1;
|
||||
|
||||
while (b != &fFreeList) {
|
||||
assert(b->bh.bsize > 0);
|
||||
*totfree += b->bh.bsize;
|
||||
if (b->bh.bsize > *maxfree)
|
||||
{
|
||||
*maxfree = b->bh.bsize;
|
||||
}
|
||||
|
||||
|
||||
// Link to next buffer
|
||||
b = b->ql.flink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return extended statistics
|
||||
// !Return extended statistics
|
||||
void
|
||||
MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget, long *nprel,
|
||||
long *ndget, long *ndrel)
|
||||
MemPool::ExtendedStats(ssize_t *pool_incr, long *npool, long *npget,
|
||||
long *nprel, long *ndget, long *ndrel)
|
||||
{
|
||||
*pool_incr = (fPoolLength < 0) ? -fExpIncr : fExpIncr;
|
||||
*npool = fNumpblk;
|
||||
*npget = fNumpget;
|
||||
*nprel = fNumprel;
|
||||
*ndget = fNumdget;
|
||||
*ndrel = fNumdrel;
|
||||
*pool_incr = (fPoolLength < 0) ? -fIncrementSize : fIncrementSize;
|
||||
*npool = fNumpblk;
|
||||
*npget = fNumpget;
|
||||
*nprel = fNumprel;
|
||||
*ndget = fNumdget;
|
||||
*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
|
||||
// or an allocated one.
|
||||
/*!
|
||||
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
|
||||
or an allocated one.
|
||||
*/
|
||||
void
|
||||
MemPool::BufferDump(void *buf)
|
||||
{
|
||||
struct bfhead *b;
|
||||
unsigned char *bdump;
|
||||
ssize_t bdlen;
|
||||
struct bfhead *b;
|
||||
unsigned char *bdump;
|
||||
ssize_t bdlen;
|
||||
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
assert(b->bh.bsize != 0);
|
||||
if (b->bh.bsize < 0)
|
||||
{
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
assert(b->bh.bsize != 0);
|
||||
if (b->bh.bsize < 0) {
|
||||
bdump = (unsigned char *) buf;
|
||||
bdlen = (-b->bh.bsize) - sizeof(struct bhead);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
bdump = (unsigned char *) (((char *) b) + sizeof(struct bfhead));
|
||||
bdlen = b->bh.bsize - sizeof(struct bfhead);
|
||||
}
|
||||
}
|
||||
|
||||
while (bdlen > 0)
|
||||
{
|
||||
while (bdlen > 0) {
|
||||
int i, dupes = 0;
|
||||
ssize_t l = bdlen;
|
||||
char bhex[50], bascii[20];
|
||||
|
||||
|
||||
if (l > 16)
|
||||
{
|
||||
l = 16;
|
||||
}
|
||||
|
||||
for (i = 0; i < l; i++)
|
||||
{
|
||||
sprintf(bhex + i * 3, "%02X ", bdump[i]);
|
||||
bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
|
||||
l = 16;
|
||||
|
||||
for (i = 0; i < l; i++) {
|
||||
sprintf(bhex + i * 3, "%02X ", bdump[i]);
|
||||
bascii[i] = isprint(bdump[i]) ? bdump[i] : ' ';
|
||||
}
|
||||
bascii[i] = 0;
|
||||
printf("%-48s %s\n", bhex, bascii);
|
||||
printf("%-48s %s\n", bhex, bascii);
|
||||
bdump += l;
|
||||
bdlen -= l;
|
||||
while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0))
|
||||
{
|
||||
dupes++;
|
||||
bdump += 16;
|
||||
bdlen -= 16;
|
||||
while ((bdlen > 16) && (memcmp((char *) (bdump - 16),(char *) bdump, 16) == 0)) {
|
||||
dupes++;
|
||||
bdump += 16;
|
||||
bdlen -= 16;
|
||||
}
|
||||
|
||||
if (dupes > 1)
|
||||
{
|
||||
printf(" (%d lines [%d bytes] identical to above line skipped)\n",
|
||||
dupes, dupes * 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dupes == 1)
|
||||
{
|
||||
bdump -= 16;
|
||||
bdlen += 16;
|
||||
if (dupes > 1) {
|
||||
printf(" (%d lines [%d bytes] identical to above line skipped)\n",
|
||||
dupes, dupes * 16);
|
||||
} else {
|
||||
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,
|
||||
// free blocks which have been clobbered will always be dumped.
|
||||
|
||||
/*!
|
||||
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,
|
||||
free blocks which have been clobbered will always be dumped.
|
||||
*/
|
||||
void
|
||||
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;
|
||||
|
||||
if (bs < 0)
|
||||
{
|
||||
bs = -bs;
|
||||
printf("Allocated buffer: size %6ld bytes.\n", (long) bs);
|
||||
if (dumpalloc)
|
||||
{
|
||||
|
||||
if (bs < 0) {
|
||||
bs = -bs;
|
||||
printf("Allocated buffer: size %6ld bytes.\n", (long) bs);
|
||||
if (dumpalloc)
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
char *lerr = "";
|
||||
|
||||
assert(bs > 0);
|
||||
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||
{
|
||||
lerr = " (Bad free list links)";
|
||||
}
|
||||
printf("Free block: size %6ld bytes.%s\n",
|
||||
(long) bs, lerr);
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||
(memcmp(lerr, lerr + 1, (int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||
{
|
||||
assert(bs > 0);
|
||||
if ((b->ql.blink->ql.flink != b) || (b->ql.flink->ql.blink != b))
|
||||
lerr = " (Bad free list links)";
|
||||
|
||||
printf("Free block: size %6ld bytes.%s\n",
|
||||
(long) bs, lerr);
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if (bs > (ssize_t)sizeof(struct bfhead)
|
||||
&& (*lerr != 0x55
|
||||
|| memcmp(lerr, lerr + 1, (int)(bs - (sizeof(struct bfhead) + 1))) != 0)) {
|
||||
printf("(Contents of above free block have been overstored.)\n");
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dumpfree)
|
||||
{
|
||||
} else {
|
||||
if (dumpfree)
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
b = BFH(((char *) b) + bs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate a buffer pool.
|
||||
|
||||
//! Validate a buffer pool.
|
||||
int
|
||||
MemPool::Validate(void *buf)
|
||||
{
|
||||
struct bfhead *b = BFH(buf);
|
||||
|
||||
while (b->bh.bsize != ESent)
|
||||
{
|
||||
struct bfhead *b = BFH(buf);
|
||||
|
||||
while (b->bh.bsize != ESent) {
|
||||
ssize_t bs = b->bh.bsize;
|
||||
|
||||
if (bs < 0)
|
||||
{
|
||||
bs = -bs;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *lerr = "";
|
||||
|
||||
assert(bs > 0);
|
||||
if (bs <= 0)
|
||||
{
|
||||
bs = -bs;
|
||||
else {
|
||||
char *lerr = "";
|
||||
|
||||
assert(bs > 0);
|
||||
if (bs <= 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if ((bs > (ssize_t)sizeof(struct bfhead)) && ((*lerr != 0x55) ||
|
||||
(memcmp(lerr, lerr + 1,(int) (bs - (sizeof(struct bfhead) + 1))) != 0)))
|
||||
{
|
||||
}
|
||||
|
||||
lerr = ((char *) b) + sizeof(struct bfhead);
|
||||
if (bs > (ssize_t)sizeof(struct bfhead)
|
||||
&& (*lerr != 0x55
|
||||
|| memcmp(lerr, lerr + 1, (int)(bs - (sizeof(struct bfhead) + 1))) != 0)) {
|
||||
printf("(Contents of above free block have been overstored.)\n");
|
||||
BufferDump((void *) (((char *) b) + sizeof(struct bhead)));
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
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)
|
||||
:
|
||||
: MemPool(initialSize),
|
||||
fName(name)
|
||||
{
|
||||
if (initialSize > 0)
|
||||
|
||||
+74
-76
@@ -6,95 +6,93 @@
|
||||
* John Walker <[email protected]>
|
||||
* DarkWyrm <[email protected]>
|
||||
* Stephan Aßmus <[email protected]>
|
||||
*
|
||||
* BGET pool allocator
|
||||
*/
|
||||
|
||||
#ifndef MEM_POOL_H
|
||||
#define MEM_POOL_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class MemPool {
|
||||
public:
|
||||
MemPool();
|
||||
virtual ~MemPool();
|
||||
public:
|
||||
MemPool(int32 incrementSize);
|
||||
virtual ~MemPool();
|
||||
|
||||
void AddToPool(void* buffer, ssize_t len);
|
||||
void* GetBuffer(ssize_t size, bool zero = false);
|
||||
void* ReallocateBuffer(void* buffer, ssize_t size);
|
||||
void ReleaseBuffer(void* buffer);
|
||||
void AddToPool(void* buffer, ssize_t len);
|
||||
void* GetBuffer(ssize_t size, bool zero = false);
|
||||
void* ReallocateBuffer(void* buffer, ssize_t size);
|
||||
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);
|
||||
virtual void* AcquireMem(ssize_t size);
|
||||
virtual void ReleaseMem(void* buffer);
|
||||
// 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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
// 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;
|
||||
ssize_t fTotalAllocated;
|
||||
long fGetCount;
|
||||
long fReleaseCount;
|
||||
long fNumpblk;
|
||||
long fNumpget;
|
||||
long fNumprel;
|
||||
long fNumdget;
|
||||
long fNumdrel;
|
||||
ssize_t fIncrementSize;
|
||||
ssize_t fPoolLength;
|
||||
// List of free buffers
|
||||
bfhead fFreeList;
|
||||
};
|
||||
|
||||
class AreaPool : public MemPool {
|
||||
public:
|
||||
AreaPool(const char* name, size_t initialSize = 0);
|
||||
AreaPool(const char* name, size_t initialSize);
|
||||
virtual ~AreaPool();
|
||||
|
||||
virtual void* AcquireMem(ssize_t size);
|
||||
@@ -104,4 +102,4 @@ class AreaPool : public MemPool {
|
||||
const char* fName;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* MEM_POOL_H */
|
||||
|
||||
@@ -32,7 +32,7 @@ using std::nothrow;
|
||||
BitmapManager *gBitmapManager = NULL;
|
||||
|
||||
//! 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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "RootLayer.h"
|
||||
//#include "RootLayer.h"
|
||||
|
||||
#include "DebugInfoManager.h"
|
||||
|
||||
|
||||
@@ -288,8 +288,8 @@ Decorator::GetZoom()
|
||||
|
||||
// GetSizeLimits
|
||||
void
|
||||
Decorator::GetSizeLimits(float* minWidth, float* minHeight,
|
||||
float* maxWidth, float* maxHeight) const
|
||||
Decorator::GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -184,13 +184,13 @@ DefaultDecorator::MoveBy(BPoint pt)
|
||||
void
|
||||
DefaultDecorator::ResizeBy(float x, float y)
|
||||
{
|
||||
ResizeBy(BPoint(x,y));
|
||||
ResizeBy(BPoint(x, y));
|
||||
}
|
||||
|
||||
void
|
||||
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
|
||||
_frame.right += pt.x;
|
||||
_frame.bottom += pt.y;
|
||||
@@ -250,13 +250,13 @@ DefaultDecorator::Draw()
|
||||
|
||||
// GetSizeLimits
|
||||
void
|
||||
DefaultDecorator::GetSizeLimits(float* minWidth, float* minHeight,
|
||||
float* maxWidth, float* maxHeight) const
|
||||
DefaultDecorator::GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const
|
||||
{
|
||||
if (_tabrect.IsValid())
|
||||
*minWidth = max_c(*minWidth, fMinTabWidth - 2 * fBorderWidth);
|
||||
*minWidth = (int32)roundf(max_c(*minWidth, fMinTabWidth - 2 * fBorderWidth));
|
||||
if (_resizerect.IsValid())
|
||||
*minHeight = max_c(*minHeight, _resizerect.Height() - fBorderWidth);
|
||||
*minHeight = (int32)roundf(max_c(*minHeight, _resizerect.Height() - fBorderWidth));
|
||||
}
|
||||
|
||||
// GetFootprint
|
||||
@@ -309,7 +309,7 @@ DefaultDecorator::Clicked(BPoint pt, int32 buttons, int32 modifiers)
|
||||
|
||||
if (!(fFlags & B_NOT_ZOOMABLE) && _zoomrect.Contains(pt))
|
||||
return DEC_ZOOM;
|
||||
|
||||
|
||||
if (fLook == B_DOCUMENT_WINDOW_LOOK && _resizerect.Contains(pt))
|
||||
return DEC_RESIZE;
|
||||
|
||||
@@ -466,7 +466,7 @@ DefaultDecorator::_DoLayout()
|
||||
|
||||
// calculate resize rect
|
||||
_resizerect.Set(fBottomBorder.right - 18.0, fBottomBorder.bottom - 18.0,
|
||||
fBottomBorder.right - 3, fBottomBorder.bottom - 3);
|
||||
fBottomBorder.right, fBottomBorder.bottom);
|
||||
}
|
||||
|
||||
// _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
|
||||
if (!(fFlags & B_NOT_RESIZABLE)) {
|
||||
|
||||
r = _resizerect;
|
||||
|
||||
switch (fLook){
|
||||
case B_DOCUMENT_WINDOW_LOOK: {
|
||||
|
||||
// Explicitly locking the driver is normally unnecessary. However, we need to do
|
||||
// this because we are rapidly drawing a series of calls which would not necessarily
|
||||
// draw correctly if we didn't do so.
|
||||
float x = r.right;
|
||||
float y = r.bottom;
|
||||
// Explicitly locking the driver is normally unnecessary. However, we
|
||||
// need to do this because we are rapidly drawing a series of calls
|
||||
// which would not necessarily draw correctly if we didn't do so.
|
||||
float x = r.right - 3;
|
||||
float y = r.bottom - 3;
|
||||
_driver->Lock();
|
||||
_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]);
|
||||
@@ -600,7 +598,7 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top,
|
||||
fFrameColors[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default: {
|
||||
// don't draw resize corner
|
||||
break;
|
||||
@@ -715,7 +713,7 @@ DefaultDecorator::_SetFocus()
|
||||
// SetFocus() performs necessary duties for color swapping and
|
||||
// other things when a window is deactivated or activated.
|
||||
|
||||
if (GetFocus()) {
|
||||
if (IsFocus()) {
|
||||
fButtonHighColor.SetColor(tint_color(_colors->window_tab,B_LIGHTEN_2_TINT));
|
||||
fButtonLowColor.SetColor(tint_color(_colors->window_tab,B_DARKEN_1_TINT));
|
||||
fTextColor = _colors->window_tab_text;
|
||||
|
||||
@@ -35,8 +35,8 @@ public:
|
||||
virtual void Draw(BRect r);
|
||||
virtual void Draw();
|
||||
|
||||
virtual void GetSizeLimits(float* minWidth, float* minHeight,
|
||||
float* maxWidth, float* maxHeight) const;
|
||||
virtual void GetSizeLimits(int32* minWidth, int32* minHeight,
|
||||
int32* maxWidth, int32* maxHeight) const;
|
||||
|
||||
virtual void GetFootprint(BRegion *region);
|
||||
|
||||
|
||||
+691
-142
File diff suppressed because it is too large
Load Diff
+82
-14
@@ -18,31 +18,37 @@
|
||||
#include "VirtualScreen.h"
|
||||
#include "DesktopSettings.h"
|
||||
#include "MessageLooper.h"
|
||||
#include "WindowList.h"
|
||||
#include "Workspace.h"
|
||||
#include "WorkspacePrivate.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <List.h>
|
||||
#include <Locker.h>
|
||||
#include <Menu.h>
|
||||
#include <Autolock.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Region.h>
|
||||
#include <Window.h>
|
||||
|
||||
#define USE_MULTI_LOCKER 0
|
||||
|
||||
#if USE_MULTI_LOCKER
|
||||
# include "MultiLocker.h"
|
||||
#else
|
||||
# include <Locker.h>
|
||||
#endif
|
||||
|
||||
class BMessage;
|
||||
|
||||
class DrawingEngine;
|
||||
class HWInterface;
|
||||
class Layer;
|
||||
class RootLayer;
|
||||
class WindowLayer;
|
||||
class ServerApp;
|
||||
|
||||
namespace BPrivate {
|
||||
class LinkSender;
|
||||
};
|
||||
|
||||
|
||||
class Desktop : public MessageLooper, public ScreenOwner {
|
||||
public:
|
||||
Desktop(uid_t userID);
|
||||
@@ -63,7 +69,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
{ return fActiveScreen; }
|
||||
Screen* ActiveScreen() const
|
||||
{ return fActiveScreen; }
|
||||
::RootLayer* RootLayer() const { return fRootLayer; }
|
||||
|
||||
CursorManager& GetCursorManager() { return fCursorManager; }
|
||||
|
||||
void ScreenChanged(Screen* screen);
|
||||
@@ -85,11 +91,13 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
{ return fCurrentWorkspace; }
|
||||
Workspace::Private& WorkspaceAt(int32 index)
|
||||
{ return fWorkspaces[index]; }
|
||||
void UpdateWorkspaces();
|
||||
|
||||
// WindowLayer methods
|
||||
|
||||
void ActivateWindow(WindowLayer* window);
|
||||
void SendBehindWindow(WindowLayer* window, WindowLayer* front);
|
||||
void SendWindowBehind(WindowLayer* window,
|
||||
WindowLayer* behindOf = NULL);
|
||||
|
||||
void ShowWindow(WindowLayer* window);
|
||||
void HideWindow(WindowLayer* window);
|
||||
@@ -107,11 +115,38 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
void SetWindowFeel(WindowLayer* window, window_feel feel);
|
||||
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* FindWindowLayerByServerToken(int32 token);
|
||||
|
||||
// get list of registed windows
|
||||
const BObjectList<WindowLayer>& WindowList() const;
|
||||
#if USE_MULTI_LOCKER
|
||||
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,
|
||||
BPrivate::LinkSender& sender);
|
||||
@@ -119,14 +154,31 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
BPrivate::LinkSender& sender);
|
||||
|
||||
private:
|
||||
void _ShowWindow(WindowLayer* window,
|
||||
bool affectsOtherWindows = true);
|
||||
void _HideWindow(WindowLayer* window);
|
||||
|
||||
void _ChangeWindowWorkspaces(WindowLayer* window,
|
||||
uint32 oldWorkspaces, uint32 newWorkspaces);
|
||||
void _BringWindowsToFront(WindowList& windows,
|
||||
int32 list, bool wereVisible);
|
||||
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 _PrepareQuit();
|
||||
void _DispatchMessage(int32 code,
|
||||
BPrivate::LinkReceiver &link);
|
||||
|
||||
WindowList& _CurrentWindows();
|
||||
|
||||
private:
|
||||
friend class DesktopSettings;
|
||||
|
||||
@@ -137,8 +189,8 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
::EventDispatcher fEventDispatcher;
|
||||
port_id fInputPort;
|
||||
|
||||
BLocker fAppListLock;
|
||||
BList fAppList;
|
||||
BLocker fApplicationsLock;
|
||||
BObjectList<ServerApp> fApplications;
|
||||
|
||||
sem_id fShutdownSemaphore;
|
||||
int32 fShutdownCount;
|
||||
@@ -146,12 +198,28 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
::Workspace::Private fWorkspaces[32];
|
||||
int32 fCurrentWorkspace;
|
||||
|
||||
BObjectList<WindowLayer> fWindowLayerList;
|
||||
WindowList fAllWindows;
|
||||
|
||||
::RootLayer* fRootLayer;
|
||||
Screen* fActiveScreen;
|
||||
|
||||
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
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <TokenSpace.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <new>
|
||||
@@ -470,7 +469,14 @@ EventDispatcher::SendFakeMouseMoved(EventTarget& target, int32 viewToken)
|
||||
moved.AddPoint("screen_where", fLastCursorPosition);
|
||||
moved.AddInt32("buttons", fLastButtons);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -604,6 +644,13 @@ EventDispatcher::_EventLoop()
|
||||
if (event->FindPoint("where", &where) == B_OK)
|
||||
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()) {
|
||||
// there is no cursor thread, we need to move the cursor ourselves
|
||||
BAutolock _(fCursorLock);
|
||||
@@ -717,7 +764,7 @@ EventDispatcher::_EventLoop()
|
||||
_UnsetFeedFocus(event);
|
||||
}
|
||||
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
|
||||
event->RemoveName("_view_token");
|
||||
}
|
||||
@@ -744,6 +791,8 @@ EventDispatcher::_EventLoop()
|
||||
if (event->what == B_MOUSE_UP) {
|
||||
fSuspendFocus = false;
|
||||
_RemoveTemporaryListeners();
|
||||
if (fDraggingMessage)
|
||||
_DeliverDragMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Message.h>
|
||||
#include <MessageFilter.h>
|
||||
#include <Messenger.h>
|
||||
#include <ObjectList.h>
|
||||
@@ -83,6 +84,12 @@ class EventDispatcher : public BLocker {
|
||||
bool HasCursorThread();
|
||||
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:
|
||||
status_t _Run();
|
||||
void _Unset();
|
||||
@@ -101,6 +108,8 @@ class EventDispatcher : public BLocker {
|
||||
uint32 eventMask, uint32 options, bool temporary);
|
||||
void _RemoveTemporaryListeners();
|
||||
|
||||
void _DeliverDragMessage();
|
||||
|
||||
void _EventLoop();
|
||||
void _CursorLoop();
|
||||
|
||||
@@ -124,6 +133,9 @@ class EventDispatcher : public BLocker {
|
||||
BPoint fLastCursorPosition;
|
||||
int32 fLastButtons;
|
||||
|
||||
BMessage fDragMessage;
|
||||
bool fDraggingMessage;
|
||||
|
||||
BLocker fCursorLock;
|
||||
HWInterface* fHWInterface;
|
||||
};
|
||||
|
||||
@@ -31,7 +31,6 @@ Server app_server :
|
||||
FontManager.cpp
|
||||
HashTable.cpp
|
||||
InputManager.cpp
|
||||
Layer.cpp
|
||||
MessageLooper.cpp
|
||||
MultiLocker.cpp
|
||||
OffscreenServerWindow.cpp
|
||||
@@ -40,7 +39,6 @@ Server app_server :
|
||||
PicturePlayer.cpp
|
||||
RAMLinkMsgReader.cpp
|
||||
RGBColor.cpp
|
||||
RootLayer.cpp
|
||||
ScreenManager.cpp
|
||||
ServerApp.cpp
|
||||
ServerBitmap.cpp
|
||||
@@ -49,10 +47,11 @@ Server app_server :
|
||||
ServerPicture.cpp
|
||||
ServerScreen.cpp
|
||||
ServerWindow.cpp
|
||||
SubWindowList.cpp
|
||||
SystemPalette.cpp
|
||||
ViewLayer.cpp
|
||||
VirtualScreen.cpp
|
||||
WindowLayer.cpp
|
||||
WindowList.cpp
|
||||
Workspace.cpp
|
||||
WorkspacesLayer.cpp
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 ®);
|
||||
void _RebuildVisibleRegions( const BRegion &invalid,
|
||||
const BRegion &parentLocalVisible,
|
||||
const Layer *startFrom);
|
||||
void _RebuildDrawingRegion();
|
||||
void _ClearVisibleRegions();
|
||||
void _ResizeLayerFrameBy(float x, float y);
|
||||
void _RezizeLayerRedrawMore(BRegion ®, float dx, float dy);
|
||||
void _ResizeLayerFullUpdateOnResize(BRegion ®, 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_
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
|
||||
OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
|
||||
const char* name, ServerWindow* window)
|
||||
const char* name, ::ServerWindow* window)
|
||||
: WindowLayer(bitmap->Bounds(), name,
|
||||
B_NO_BORDER_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||
0, 0, window, new DrawingEngine()),
|
||||
@@ -29,6 +29,12 @@ OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
|
||||
GetDrawingEngine()->SetHWInterface(fHWInterface);
|
||||
GetDrawingEngine()->Initialize();
|
||||
GetDrawingEngine()->Update();
|
||||
|
||||
fVisibleRegion.Set(fFrame);
|
||||
fVisibleContentRegion.Set(fFrame);
|
||||
fVisibleContentRegionValid = true;
|
||||
fContentRegion.Set(fFrame);
|
||||
fContentRegionValid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class OffscreenWindowLayer : public WindowLayer {
|
||||
public:
|
||||
OffscreenWindowLayer(ServerBitmap* bitmap,
|
||||
const char* name,
|
||||
ServerWindow* window);
|
||||
::ServerWindow* window);
|
||||
virtual ~OffscreenWindowLayer();
|
||||
|
||||
virtual void Draw(const BRect &r);
|
||||
|
||||
@@ -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(®ion);
|
||||
} 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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "CursorManager.h"
|
||||
#include "CursorSet.h"
|
||||
#include "Desktop.h"
|
||||
#include "DebugInfoManager.h"
|
||||
#include "DecorManager.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "EventStream.h"
|
||||
@@ -46,7 +47,6 @@
|
||||
#include "InputManager.h"
|
||||
#include "OffscreenServerWindow.h"
|
||||
#include "RAMLinkMsgReader.h"
|
||||
#include "RootLayer.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerBitmap.h"
|
||||
#include "ServerConfig.h"
|
||||
@@ -93,7 +93,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
||||
fAppCursor(NULL),
|
||||
fCursorHidden(false),
|
||||
fIsActive(false),
|
||||
fSharedMem("shared memory")
|
||||
fSharedMem("shared memory", 32768)
|
||||
{
|
||||
if (fSignature == "")
|
||||
fSignature = "application/no-signature";
|
||||
@@ -231,7 +231,7 @@ ServerApp::Run()
|
||||
return false;
|
||||
|
||||
// Let's tell the client how to talk with us
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(fMessagePort);
|
||||
fLink.Flush();
|
||||
|
||||
@@ -531,7 +531,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
void *sharedmem = fSharedMem.GetBuffer(memsize);
|
||||
|
||||
if (memsize < 1 || sharedmem == NULL) {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
@@ -540,7 +540,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
area_info info;
|
||||
|
||||
if (owningArea == B_ERROR || get_area_info(owningArea, &info) < B_OK) {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
@@ -548,7 +548,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
int32 areaoffset = (addr_t)sharedmem - (addr_t)info.address;
|
||||
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<int32>(areaoffset);
|
||||
fLink.Flush();
|
||||
@@ -582,13 +582,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
{
|
||||
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);
|
||||
window->Lock();
|
||||
const_cast<WindowLayer *>(window->GetWindowLayer())->UpdateDecorator();
|
||||
window->Unlock();
|
||||
}
|
||||
break;
|
||||
*/ break;
|
||||
}
|
||||
case AS_SET_DECORATOR:
|
||||
{
|
||||
@@ -606,14 +607,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
}
|
||||
case AS_COUNT_DECORATORS:
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(gDecorManager.CountDecorators());
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_GET_DECORATOR:
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(gDecorManager.GetDecorator());
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -624,14 +625,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
link.Read<int32>(&index);
|
||||
|
||||
BString str(gDecorManager.GetDecoratorName(index));
|
||||
if (str.CountChars() > 0)
|
||||
{
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
if (str.CountChars() > 0) {
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.AttachString(str.String());
|
||||
}
|
||||
else
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
|
||||
} else
|
||||
fLink.StartMessage(B_ERROR);
|
||||
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
@@ -659,16 +658,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
{
|
||||
STRACE(("ServerApp %s: Received BBitmap creation request\n", Signature()));
|
||||
// Allocate a bitmap for an application
|
||||
|
||||
|
||||
// Attached Data:
|
||||
// 1) BRect bounds
|
||||
// 2) color_space space
|
||||
// 3) int32 bitmap_flags
|
||||
// 4) int32 bytes_per_row
|
||||
// 5) int32 screen_id::id
|
||||
// 6) port_id reply port
|
||||
|
||||
// Reply Code: SERVER_TRUE
|
||||
// Reply Data:
|
||||
// 1) int32 server token
|
||||
// 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()));
|
||||
|
||||
if (bitmap && fBitmapList.AddItem((void*)bitmap)) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(bitmap->Token());
|
||||
fLink.Attach<area_id>(bitmap->Area());
|
||||
fLink.Attach<int32>(bitmap->AreaOffset());
|
||||
} else {
|
||||
// alternatively, if something went wrong, we reply with SERVER_FALSE
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_NO_MEMORY);
|
||||
}
|
||||
|
||||
fLink.Flush();
|
||||
@@ -713,10 +709,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
// Attached Data:
|
||||
// 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;
|
||||
link.Read<int32>(&id);
|
||||
|
||||
@@ -725,11 +717,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id));
|
||||
|
||||
gBitmapManager->DeleteBitmap(bitmap);
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
} else
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
|
||||
fLink.Flush();
|
||||
}
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
@@ -787,7 +775,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (fDesktop->CurrentWorkspace() >= newCount)
|
||||
fDesktop->SetWorkspace(newCount - 1);
|
||||
else
|
||||
fDesktop->RootLayer()->UpdateWorkspaces();
|
||||
fDesktop->UpdateWorkspaces();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -838,7 +826,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
case AS_QUERY_CURSOR_HIDDEN:
|
||||
{
|
||||
STRACE(("ServerApp %s: Received IsCursorHidden request\n", Signature()));
|
||||
fLink.StartMessage(fCursorHidden ? SERVER_TRUE : SERVER_FALSE);
|
||||
fLink.StartMessage(fCursorHidden ? B_OK : B_ERROR);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
@@ -886,7 +874,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (sync) {
|
||||
// the application is expecting a reply, but plans to do literally nothing
|
||||
// with the data, so we'll just reuse the cursor token variable
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
}
|
||||
break;
|
||||
@@ -914,7 +902,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
fDesktop->GetCursorManager().AddCursor(fAppCursor);
|
||||
|
||||
// Synchronous message - BApplication is waiting on the cursor's ID
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(fAppCursor->ID());
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -940,7 +928,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
DesktopSettings settings(fDesktop);
|
||||
settings.GetScrollBarInfo(info);
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<scroll_bar_info>(info);
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -956,7 +944,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
settings.SetScrollBarInfo(info);
|
||||
}
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
@@ -1006,7 +994,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature()));
|
||||
DesktopSettings settings(fDesktop);
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<mode_mouse>(settings.MouseMode());
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -1018,7 +1006,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
// using a ColorSet object
|
||||
gGUIColorSet.Lock();
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<ColorSet>(gGUIColorSet);
|
||||
fLink.Flush();
|
||||
|
||||
@@ -1051,7 +1039,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
color = gGUIColorSet.AttributeToColor(whichColor);
|
||||
gGUIColorSet.Unlock();
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<rgb_color>(color.GetColor32());
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -1838,14 +1826,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
// TODO implement for real
|
||||
if (font.GetBoundingBoxesAsString(charArray, numChars, rectArray, string_escapement, mode, delta)) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach(rectArray, sizeof(rectArray));
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -1912,7 +1900,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
// TODO implement for real
|
||||
if (font.GetBoundingBoxesForStrings(stringArray, lengthArray, numStrings, rectArray, mode, deltaArray)) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach(rectArray, sizeof(rectArray));
|
||||
success = true;
|
||||
}
|
||||
@@ -1922,7 +1910,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
free(stringArray[i]);
|
||||
|
||||
if (!success)
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
|
||||
fLink.Flush();
|
||||
break;
|
||||
@@ -2036,18 +2024,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
bool makedefault = false;
|
||||
link.Read<bool>(&makedefault);
|
||||
|
||||
RootLayer* rootLayer = fDesktop->RootLayer();
|
||||
rootLayer->Lock();
|
||||
status_t status = fDesktop->ScreenAt(0)->SetMode(mode);
|
||||
if (status == B_OK) {
|
||||
BRect bounds = rootLayer->Bounds();
|
||||
rootLayer->ResizeBy(mode.virtual_width - 1 - bounds.Width(),
|
||||
mode.virtual_height - 1 - bounds.Height());
|
||||
|
||||
gInputManager->UpdateScreenBounds(rootLayer->Bounds());
|
||||
fDesktop->ScreenChanged(fDesktop->ScreenAt(0));
|
||||
status_t status = B_ERROR;
|
||||
if (fDesktop->WriteLockWindows()) {
|
||||
status = fDesktop->ScreenAt(0)->SetMode(mode);
|
||||
if (status == B_OK) {
|
||||
gInputManager->UpdateScreenBounds(fDesktop->ScreenAt(0)->Frame());
|
||||
fDesktop->ScreenChanged(fDesktop->ScreenAt(0));
|
||||
}
|
||||
fDesktop->WriteUnlockWindows();
|
||||
}
|
||||
rootLayer->Unlock();
|
||||
|
||||
fLink.StartMessage(status);
|
||||
fLink.Flush();
|
||||
@@ -2313,7 +2298,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
if (link.NeedsReply()) {
|
||||
// the client is now blocking and waiting for a reply!
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
} else
|
||||
puts("message doesn't need a reply!");
|
||||
@@ -2418,7 +2403,7 @@ ServerApp::RemoveWindow(ServerWindow* window)
|
||||
|
||||
|
||||
bool
|
||||
ServerApp::OnWorkspace(int32 index)
|
||||
ServerApp::OnWorkspace(int32 index) const
|
||||
{
|
||||
BAutolock locker(fWindowListLock);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class ServerApp : public MessageLooper {
|
||||
const char *Signature() const { return fSignature.String(); }
|
||||
|
||||
void RemoveWindow(ServerWindow* window);
|
||||
bool OnWorkspace(int32 index);
|
||||
bool OnWorkspace(int32 index) const;
|
||||
|
||||
int32 CountBitmaps() const;
|
||||
ServerBitmap *FindBitmap(int32 token) const;
|
||||
@@ -98,7 +98,7 @@ class ServerApp : public MessageLooper {
|
||||
BString fSignature;
|
||||
team_id fClientTeam;
|
||||
|
||||
BLocker fWindowListLock;
|
||||
mutable BLocker fWindowListLock;
|
||||
BObjectList<ServerWindow> fWindowList;
|
||||
BPrivate::BTokenSpace fViewTokens;
|
||||
|
||||
|
||||
+955
-936
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ class Decorator;
|
||||
class WindowLayer;
|
||||
class Workspace;
|
||||
class RootLayer;
|
||||
class Layer;
|
||||
class ViewLayer;
|
||||
class ServerPicture;
|
||||
struct dw_data;
|
||||
struct window_info;
|
||||
@@ -97,7 +97,8 @@ public:
|
||||
// related thread/team_id(s).
|
||||
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 ServerToken() const { return fServerToken; }
|
||||
@@ -106,19 +107,27 @@ public:
|
||||
|
||||
private:
|
||||
// methods for retrieving and creating a tree strcture of Layers.
|
||||
Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent);
|
||||
void SetLayerState(Layer *layer, BPrivate::LinkReceiver &link);
|
||||
void SetLayerFontState(Layer *layer, BPrivate::LinkReceiver &link);
|
||||
ViewLayer* CreateLayerTree(BPrivate::LinkReceiver &link,
|
||||
ViewLayer **_parent);
|
||||
void SetLayerState(ViewLayer *layer,
|
||||
BPrivate::LinkReceiver &link);
|
||||
void SetLayerFontState(ViewLayer *layer,
|
||||
BPrivate::LinkReceiver &link);
|
||||
|
||||
// message handling methods.
|
||||
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();
|
||||
virtual void _PrepareQuit();
|
||||
virtual void _GetLooperName(char* name, size_t size);
|
||||
|
||||
status_t _EnableDirectWindowMode();
|
||||
|
||||
|
||||
void _SetCurrentLayer(ViewLayer* view);
|
||||
|
||||
// TODO: Move me elsewhere
|
||||
status_t PictureToRegion(ServerPicture *picture,
|
||||
BRegion &,
|
||||
@@ -146,7 +155,9 @@ private:
|
||||
int32 fServerToken;
|
||||
int32 fClientToken;
|
||||
|
||||
Layer* fCurrentLayer;
|
||||
ViewLayer* fCurrentLayer;
|
||||
BRegion fCurrentDrawingRegion;
|
||||
bool fCurrentDrawingRegionValid;
|
||||
|
||||
dw_data* fDirectWindowData;
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
+1243
-486
File diff suppressed because it is too large
Load Diff
+221
-95
@@ -12,98 +12,135 @@
|
||||
|
||||
|
||||
#include "Decorator.h"
|
||||
#include "Layer.h"
|
||||
#include "ViewLayer.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "WindowList.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Rect.h>
|
||||
#include <Region.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class ServerWindow;
|
||||
class ClientLooper;
|
||||
class Decorator;
|
||||
class DrawingEngine;
|
||||
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:
|
||||
WindowLayer(const BRect &frame,
|
||||
const char *name, window_look look,
|
||||
window_feel feel, uint32 flags,
|
||||
uint32 workspaces, ServerWindow *window,
|
||||
DrawingEngine *driver);
|
||||
WindowLayer(const BRect& frame,
|
||||
const char *name, window_look look,
|
||||
window_feel feel, uint32 flags,
|
||||
uint32 workspaces,
|
||||
::ServerWindow* window,
|
||||
DrawingEngine* drawingEngine);
|
||||
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);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
virtual void ScrollBy(float x, float y)
|
||||
{ /* not allowed */ }
|
||||
window_anchor& Anchor(int32 index);
|
||||
WindowLayer* NextWindow(int32 index);
|
||||
WindowLayer* PreviousWindow(int32 index);
|
||||
|
||||
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
|
||||
{ return false; }
|
||||
// for convenience, handles window not attached to Desktop
|
||||
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();
|
||||
inline void DisableUpdateRequests()
|
||||
{ fUpdateRequestsEnabled = false; }
|
||||
void DisableUpdateRequests();
|
||||
|
||||
void SetSizeLimits(float minWidth,
|
||||
float maxWidth,
|
||||
float minHeight,
|
||||
float maxHeight);
|
||||
void BeginUpdate();
|
||||
void EndUpdate();
|
||||
|
||||
void GetSizeLimits(float* minWidth,
|
||||
float* maxWidth,
|
||||
float* minHeight,
|
||||
float* maxHeight) const;
|
||||
bool NeedsUpdate() const
|
||||
{ return fUpdateRequested; }
|
||||
|
||||
virtual void MouseDown(BMessage* message, BPoint where, int32* _viewToken);
|
||||
virtual void MouseUp(BMessage* message, BPoint where, int32* _viewToken);
|
||||
virtual void MouseMoved(BMessage* message, BPoint where, int32* _viewToken);
|
||||
DrawingEngine* GetDrawingEngine() const
|
||||
{ return fDrawingEngine; }
|
||||
|
||||
// click_type ActionFor(const BMessage *msg)
|
||||
// { return _ActionFor(evt); }
|
||||
void CopyContents(BRegion* region,
|
||||
int32 xOffset, int32 yOffset);
|
||||
|
||||
virtual void WorkspaceActivated(int32 index, bool active);
|
||||
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
|
||||
virtual void Activated(bool active);
|
||||
void MouseDown(BMessage* message, BPoint where, int32* _viewToken);
|
||||
void MouseUp(BMessage* message, BPoint where, int32* _viewToken);
|
||||
void MouseMoved(BMessage* message, BPoint where, int32* _viewToken);
|
||||
|
||||
void UpdateColors();
|
||||
void UpdateDecorator();
|
||||
void UpdateFont();
|
||||
void UpdateScreen();
|
||||
// some hooks to inform the client window
|
||||
// TODO: move this to ServerWindow maybe?
|
||||
void WorkspaceActivated(int32 index, bool active);
|
||||
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; }
|
||||
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; }
|
||||
window_feel Feel() const { return fFeel; }
|
||||
uint32 WindowFlags() const { return fWindowFlags; }
|
||||
void SetCurrentWorkspace(int32 index)
|
||||
{ fCurrentWorkspace = index; }
|
||||
bool IsVisible() const;
|
||||
|
||||
void SetLook(window_look look, BRegion* updateRegion);
|
||||
void SetFeel(window_feel feel);
|
||||
void SetWindowFlags(uint32 flags, BRegion* updateRegion);
|
||||
// TODO: make this int32 stuff
|
||||
void SetSizeLimits(int32 minWidth, int32 maxWidth,
|
||||
int32 minHeight, int32 maxHeight);
|
||||
|
||||
uint32 Workspaces() const { return fWorkspaces; }
|
||||
void SetWorkspaces(uint32 workspaces)
|
||||
{ fWorkspaces = workspaces; }
|
||||
bool OnWorkspace(int32 index) const;
|
||||
|
||||
bool SupportsFront();
|
||||
void GetSizeLimits(int32* minWidth, int32* maxWidth,
|
||||
int32* minHeight, int32* maxHeight) const;
|
||||
|
||||
// 0.0 -> left .... 1.0 -> right
|
||||
void SetTabLocation(float location);
|
||||
@@ -111,20 +148,33 @@ class WindowLayer : public Layer {
|
||||
|
||||
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 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);
|
||||
void RemoveFromSubset(WindowLayer* window);
|
||||
bool HasInSubset(WindowLayer* window);
|
||||
|
||||
void RequestClientRedraw(const BRegion& invalid);
|
||||
|
||||
void SetTopLayer(Layer* layer);
|
||||
inline Layer* TopLayer() const
|
||||
{ return fTopLayer; }
|
||||
bool SameSubset(WindowLayer* window);
|
||||
|
||||
static bool IsValidLook(window_look look);
|
||||
static bool IsValidFeel(window_feel feel);
|
||||
@@ -135,33 +185,58 @@ class WindowLayer : public Layer {
|
||||
static uint32 ValidWindowFlags(window_feel feel);
|
||||
|
||||
protected:
|
||||
virtual void _AllRedraw(const BRegion& invalid);
|
||||
friend class Desktop;
|
||||
// TODO: for now (list management)
|
||||
|
||||
private:
|
||||
void set_decorator_region(BRect frame);
|
||||
virtual void _ReserveRegions(BRegion ®);
|
||||
void _ShiftPartOfRegion(BRegion* region, BRegion* regionToShift,
|
||||
int32 xOffset, int32 yOffset);
|
||||
|
||||
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;
|
||||
Layer* fTopLayer;
|
||||
void _UpdateContentRegion();
|
||||
|
||||
BRegion fCumulativeRegion;
|
||||
BRegion fInUpdateRegion;
|
||||
click_type _ActionFor(const BMessage* msg) const;
|
||||
|
||||
BRegion fDecRegion;
|
||||
bool fRebuildDecRegion;
|
||||
void _ObeySizeLimits();
|
||||
|
||||
int32 fMouseButtons;
|
||||
BPoint fLastMousePosition;
|
||||
BPoint fResizingClickOffset;
|
||||
BString fTitle;
|
||||
// TODO: no fp rects anywhere
|
||||
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;
|
||||
|
||||
// TODO: remove those some day (let the decorator handle that stuff)
|
||||
bool fIsClosing;
|
||||
bool fIsMinimizing;
|
||||
bool fIsZooming;
|
||||
@@ -169,21 +244,72 @@ class WindowLayer : public Layer {
|
||||
bool fIsSlidingTab;
|
||||
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 fRequestSent;
|
||||
|
||||
bool fHidden;
|
||||
bool fIsFocus;
|
||||
|
||||
window_look fLook;
|
||||
window_feel fFeel;
|
||||
uint32 fWindowFlags;
|
||||
uint32 fFlags;
|
||||
uint32 fWorkspaces;
|
||||
int32 fCurrentWorkspace;
|
||||
|
||||
float fMinWidth;
|
||||
float fMaxWidth;
|
||||
float fMinHeight;
|
||||
float fMaxHeight;
|
||||
int32 fMinWidth;
|
||||
int32 fMaxWidth;
|
||||
int32 fMinHeight;
|
||||
int32 fMaxHeight;
|
||||
|
||||
mutable bool fReadLocked;
|
||||
};
|
||||
|
||||
#endif // WINDOW_LAYER_H
|
||||
#endif // WINDOW_LAYER_H
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -7,8 +7,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "RootLayer.h"
|
||||
#include "Desktop.h"
|
||||
#include "Workspace.h"
|
||||
#include "WorkspacePrivate.h"
|
||||
#include "WindowLayer.h"
|
||||
|
||||
#include <math.h>
|
||||
@@ -17,13 +18,9 @@
|
||||
|
||||
|
||||
static RGBColor kDefaultColor = RGBColor(51, 102, 152);
|
||||
const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
|
||||
|
||||
|
||||
Workspace::Private::Private()
|
||||
:
|
||||
fWindows(20, true)
|
||||
// this list owns its items
|
||||
{
|
||||
_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
|
||||
Workspace::Private::SetDisplaysFromDesktop(Desktop* desktop)
|
||||
{
|
||||
@@ -137,26 +93,21 @@ Workspace::Color() const
|
||||
status_t
|
||||
Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop)
|
||||
{
|
||||
if (fCurrentWorkspace) {
|
||||
if (fCurrent == NULL)
|
||||
fCurrent = (WindowLayer*)fDesktop.RootLayer()->FirstChild();
|
||||
else
|
||||
fCurrent = (WindowLayer*)fCurrent->NextLayer();
|
||||
|
||||
if (fCurrent == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
if (fCurrent == NULL)
|
||||
fCurrent = fWorkspace.Windows().FirstWindow();
|
||||
else
|
||||
fCurrent = fCurrent->NextWindow(fWorkspace.Index());
|
||||
|
||||
_window = fCurrent;
|
||||
_leftTop = fCurrent->Frame().LeftTop();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
window_layer_info* info = fWorkspace.WindowAt(fIndex++);
|
||||
if (info == NULL)
|
||||
if (fCurrent == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
_window = info->window;
|
||||
_leftTop = info->position;
|
||||
_window = fCurrent;
|
||||
|
||||
if (fCurrentWorkspace)
|
||||
_leftTop = fCurrent->Frame().LeftTop();
|
||||
else
|
||||
_leftTop = fCurrent->Anchor(fWorkspace.Index()).position;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -164,7 +115,6 @@ Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop)
|
||||
void
|
||||
Workspace::RewindWindows()
|
||||
{
|
||||
fIndex = 0;
|
||||
fCurrent = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ class Workspace {
|
||||
private:
|
||||
Workspace::Private& fWorkspace;
|
||||
Desktop& fDesktop;
|
||||
int32 fIndex;
|
||||
WindowLayer* fCurrent;
|
||||
bool fCurrentWorkspace;
|
||||
};
|
||||
|
||||
@@ -10,38 +10,28 @@
|
||||
|
||||
|
||||
#include "RGBColor.h"
|
||||
#include "WindowList.h"
|
||||
#include "Workspace.h"
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include <ObjectList.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class RootLayer;
|
||||
class WindowLayer;
|
||||
|
||||
|
||||
struct display_info {
|
||||
BString identifier;
|
||||
BPoint origin;
|
||||
display_mode mode;
|
||||
};
|
||||
|
||||
struct window_layer_info {
|
||||
BPoint position;
|
||||
WindowLayer* window;
|
||||
};
|
||||
|
||||
class Workspace::Private {
|
||||
public:
|
||||
Private();
|
||||
~Private();
|
||||
|
||||
bool AddWindow(WindowLayer* window, BPoint* point = NULL);
|
||||
void RemoveWindow(WindowLayer* window);
|
||||
void RemoveWindowAt(int32 index);
|
||||
int32 Index() const { return fWindows.Index(); }
|
||||
|
||||
int32 CountWindows() const { return fWindows.CountItems(); }
|
||||
window_layer_info* WindowAt(int32 index) const { return fWindows.ItemAt(index); }
|
||||
WindowList& Windows() { return fWindows; }
|
||||
|
||||
// displays
|
||||
|
||||
@@ -61,7 +51,7 @@ class Workspace::Private {
|
||||
private:
|
||||
void _SetDefaults();
|
||||
|
||||
BObjectList<window_layer_info> fWindows;
|
||||
WindowList fWindows;
|
||||
WindowLayer* fFront;
|
||||
WindowLayer* fFocus;
|
||||
|
||||
@@ -70,6 +60,4 @@ class Workspace::Private {
|
||||
RGBColor fColor;
|
||||
};
|
||||
|
||||
extern const BPoint kInvalidWindowPosition;
|
||||
|
||||
#endif /* WORKSPACE_PRIVATE_H */
|
||||
|
||||
@@ -8,20 +8,21 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <ColorSet.h>
|
||||
#include <WindowPrivate.h>
|
||||
#include "WorkspacesLayer.h"
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "Desktop.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "RootLayer.h"
|
||||
#include "WindowLayer.h"
|
||||
#include "Workspace.h"
|
||||
|
||||
#include "WorkspacesLayer.h"
|
||||
#include <ColorSet.h>
|
||||
#include <WindowPrivate.h>
|
||||
|
||||
|
||||
WorkspacesLayer::WorkspacesLayer(BRect frame, const char* name,
|
||||
int32 token, uint32 resizeMode, uint32 flags, DrawingEngine* driver)
|
||||
: Layer(frame, name, token, resizeMode, flags, driver)
|
||||
int32 token, uint32 resizeMode, uint32 flags)
|
||||
: ViewLayer(frame, name, token, resizeMode, flags)
|
||||
{
|
||||
fDrawState->SetLowColor(RGBColor(255, 255, 255));
|
||||
fDrawState->SetHighColor(RGBColor(0, 0, 0));
|
||||
@@ -98,7 +99,7 @@ WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame,
|
||||
|
||||
|
||||
void
|
||||
WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
|
||||
WorkspacesLayer::_DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame,
|
||||
const BRect& screenFrame, WindowLayer* window, BPoint windowPosition,
|
||||
BRegion& backgroundRegion, bool active)
|
||||
{
|
||||
@@ -108,12 +109,12 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
|
||||
BPoint offset = window->Frame().LeftTop() - windowPosition;
|
||||
BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame(),
|
||||
windowPosition);
|
||||
BRect tabFrame = window->GetDecorator()->TabRect();
|
||||
BRect tabFrame = window->Decorator()->TabRect();
|
||||
tabFrame = _WindowFrame(workspaceFrame, screenFrame,
|
||||
tabFrame, tabFrame.LeftTop() - offset);
|
||||
|
||||
// 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 white(255, 255, 255);
|
||||
|
||||
@@ -134,12 +135,12 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
|
||||
backgroundRegion.Exclude(tabFrame);
|
||||
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);
|
||||
GetDrawingEngine()->FillRect(frame, white);
|
||||
drawingEngine->FillRect(frame, white);
|
||||
|
||||
// draw title
|
||||
|
||||
@@ -170,7 +171,7 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame,
|
||||
|
||||
|
||||
void
|
||||
WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
WorkspacesLayer::_DrawWorkspace(DrawingEngine* drawingEngine, int32 index)
|
||||
{
|
||||
BRect rect = _WorkspaceAt(index);
|
||||
|
||||
@@ -179,7 +180,7 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
if (active) {
|
||||
// draw active frame
|
||||
RGBColor black(0, 0, 0);
|
||||
GetDrawingEngine()->StrokeRect(rect, black);
|
||||
drawingEngine->StrokeRect(rect, black);
|
||||
}
|
||||
|
||||
rect.InsetBy(1, 1);
|
||||
@@ -190,7 +191,7 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
|
||||
// draw windows
|
||||
|
||||
BRegion backgroundRegion = VisibleRegion();
|
||||
BRegion backgroundRegion = fLocalClipping;
|
||||
|
||||
// ToDo: would be nice to get the real update region here
|
||||
|
||||
@@ -203,23 +204,23 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
|
||||
BRegion workspaceRegion(rect);
|
||||
backgroundRegion.IntersectWith(&workspaceRegion);
|
||||
GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion);
|
||||
drawingEngine->ConstrainClippingRegion(&backgroundRegion);
|
||||
|
||||
WindowLayer* window;
|
||||
BPoint leftTop;
|
||||
while (workspace.GetNextWindow(window, leftTop) == B_OK) {
|
||||
_DrawWindow(rect, screenFrame, window, leftTop,
|
||||
backgroundRegion, active);
|
||||
_DrawWindow(drawingEngine, rect, screenFrame, window,
|
||||
leftTop, backgroundRegion, active);
|
||||
}
|
||||
|
||||
// draw background
|
||||
|
||||
GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion);
|
||||
GetDrawingEngine()->FillRect(rect, color);
|
||||
drawingEngine->ConstrainClippingRegion(&backgroundRegion);
|
||||
drawingEngine->FillRect(rect, color);
|
||||
|
||||
// TODO: ConstrainClippingRegion() should accept a const parameter !!
|
||||
BRegion cRegion(VisibleRegion());
|
||||
GetDrawingEngine()->ConstrainClippingRegion(&cRegion);
|
||||
BRegion cRegion(fLocalClipping);
|
||||
drawingEngine->ConstrainClippingRegion(&cRegion);
|
||||
}
|
||||
|
||||
|
||||
@@ -231,7 +232,8 @@ WorkspacesLayer::_DarkenColor(RGBColor& color) const
|
||||
|
||||
|
||||
void
|
||||
WorkspacesLayer::Draw(const BRect& updateRect)
|
||||
WorkspacesLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
|
||||
BRegion* windowContentClipping, bool deep)
|
||||
{
|
||||
int32 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
|
||||
// to reduce flicker
|
||||
BRect activeRect = _WorkspaceAt(Window()->Desktop()->CurrentWorkspace());
|
||||
BRegion gridRegion(VisibleRegion());
|
||||
BRegion gridRegion(fLocalClipping);
|
||||
gridRegion.Exclude(activeRect);
|
||||
GetDrawingEngine()->ConstrainClippingRegion(&gridRegion);
|
||||
drawingEngine->ConstrainClippingRegion(&gridRegion);
|
||||
|
||||
BRect frame = Frame();
|
||||
BPoint pt(0,0);
|
||||
@@ -252,33 +254,33 @@ WorkspacesLayer::Draw(const BRect& updateRect)
|
||||
|
||||
// horizontal lines
|
||||
|
||||
GetDrawingEngine()->StrokeLine(BPoint(frame.left, frame.top),
|
||||
drawingEngine->StrokeLine(BPoint(frame.left, frame.top),
|
||||
BPoint(frame.right, frame.top), ViewColor());
|
||||
|
||||
for (int32 row = 0; row < rows; row++) {
|
||||
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());
|
||||
}
|
||||
|
||||
// vertical lines
|
||||
|
||||
GetDrawingEngine()->StrokeLine(BPoint(frame.left, frame.top),
|
||||
drawingEngine->StrokeLine(BPoint(frame.left, frame.top),
|
||||
BPoint(frame.left, frame.bottom), ViewColor());
|
||||
|
||||
for (int32 column = 0; column < columns; 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());
|
||||
}
|
||||
|
||||
BRegion cRegion(VisibleRegion());
|
||||
GetDrawingEngine()->ConstrainClippingRegion(&cRegion);
|
||||
BRegion cRegion(fLocalClipping);
|
||||
drawingEngine->ConstrainClippingRegion(&cRegion);
|
||||
|
||||
// draw workspaces
|
||||
|
||||
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,18 +9,21 @@
|
||||
#define WORKSPACES_LAYER_H
|
||||
|
||||
|
||||
#include "Layer.h"
|
||||
#include "ViewLayer.h"
|
||||
|
||||
class WindowLayer;
|
||||
|
||||
|
||||
class WorkspacesLayer : public Layer {
|
||||
class WorkspacesLayer : public ViewLayer {
|
||||
public:
|
||||
WorkspacesLayer(BRect frame, const char* name, int32 token,
|
||||
uint32 resize, uint32 flags, DrawingEngine* driver);
|
||||
uint32 resize, uint32 flags);
|
||||
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);
|
||||
|
||||
private:
|
||||
@@ -30,11 +33,11 @@ class WorkspacesLayer : public Layer {
|
||||
const BRect& screenFrame, const BRect& windowFrame,
|
||||
BPoint windowPosition);
|
||||
|
||||
void _DrawWindow(const BRect& workspaceFrame,
|
||||
void _DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame,
|
||||
const BRect& screenFrame, WindowLayer* window,
|
||||
BPoint windowPosition, BRegion& backgroundRegion,
|
||||
bool active);
|
||||
void _DrawWorkspace(int32 index);
|
||||
void _DrawWorkspace(DrawingEngine* drawingEngine, int32 index);
|
||||
|
||||
void _DarkenColor(RGBColor& color) const;
|
||||
};
|
||||
|
||||
@@ -120,16 +120,16 @@ DrawingEngine::Update()
|
||||
}
|
||||
}
|
||||
|
||||
// SetHWInterface
|
||||
|
||||
void
|
||||
DrawingEngine::SetHWInterface(HWInterface* interface)
|
||||
{
|
||||
fGraphicsCard = interface;
|
||||
}
|
||||
|
||||
// ConstrainClippingRegion
|
||||
|
||||
void
|
||||
DrawingEngine::ConstrainClippingRegion(BRegion *region)
|
||||
DrawingEngine::ConstrainClippingRegion(const BRegion* region)
|
||||
{
|
||||
if (Lock()) {
|
||||
if (!region) {
|
||||
@@ -377,7 +377,7 @@ DrawingEngine::CopyRegion(/*const*/ BRegion* region,
|
||||
|
||||
// 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,
|
||||
// the case of different regions overlapping each other at source
|
||||
// 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
|
||||
// gut feeling.
|
||||
if (WriteLock()) {
|
||||
|
||||
for (int32 i = 0; i < rCount; i++) {
|
||||
BRegion* region = (BRegion*)list->ItemAt(i);
|
||||
BPoint* offset = (BPoint*)pList->ItemAt(i);
|
||||
@@ -583,7 +582,6 @@ DrawingEngine::StrokeRect(BRect r, const RGBColor &color)
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->StrokeRect(r, color.GetColor32());
|
||||
@@ -671,13 +669,12 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
|
||||
r = fPainter->ClipRect(r);
|
||||
if (r.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
|
||||
bool doInSoftware = true;
|
||||
// try hardware optimized version first
|
||||
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) &&
|
||||
(d->GetDrawingMode() == B_OP_COPY ||
|
||||
d->GetDrawingMode() == B_OP_OVER)) {
|
||||
|
||||
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
|
||||
&& (d->GetDrawingMode() == B_OP_COPY
|
||||
|| d->GetDrawingMode() == B_OP_OVER)) {
|
||||
if (d->GetPattern() == B_SOLID_HIGH) {
|
||||
BRegion region(r);
|
||||
region.IntersectWith(fPainter->ClippingRegion());
|
||||
@@ -691,13 +688,12 @@ DrawingEngine::FillRect(BRect r, const DrawState *d)
|
||||
}
|
||||
}
|
||||
if (doInSoftware) {
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
fPainter->FillRect(r);
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(r);
|
||||
}
|
||||
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
@@ -715,16 +711,16 @@ DrawingEngine::StrokeRegion(BRegion& r, const DrawState *d)
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
|
||||
|
||||
BRect touched = fPainter->StrokeRect(r.RectAt(0));
|
||||
|
||||
|
||||
int32 count = r.CountRects();
|
||||
for (int32 i = 1; i < count; i++) {
|
||||
touched = touched | fPainter->StrokeRect(r.RectAt(i));
|
||||
}
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
@@ -744,13 +740,12 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
|
||||
BRect clipped = fPainter->ClipRect(r.Frame());
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
|
||||
bool doInSoftware = true;
|
||||
// try hardware optimized version first
|
||||
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) &&
|
||||
(d->GetDrawingMode() == B_OP_COPY ||
|
||||
d->GetDrawingMode() == B_OP_OVER)) {
|
||||
|
||||
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0
|
||||
&& (d->GetDrawingMode() == B_OP_COPY
|
||||
|| d->GetDrawingMode() == B_OP_OVER)) {
|
||||
if (d->GetPattern() == B_SOLID_HIGH) {
|
||||
fGraphicsCard->FillRegion(r, d->HighColor());
|
||||
doInSoftware = false;
|
||||
@@ -759,20 +754,20 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
|
||||
doInSoftware = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (doInSoftware) {
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
|
||||
|
||||
BRect touched = fPainter->FillRect(r.RectAt(0));
|
||||
|
||||
|
||||
int32 count = r.CountRects();
|
||||
for (int32 i = 1; i < count; i++) {
|
||||
touched = touched | fPainter->FillRect(r.RectAt(i));
|
||||
}
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
}
|
||||
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
@@ -780,58 +775,96 @@ DrawingEngine::FillRegion(BRegion& r, const DrawState *d)
|
||||
}
|
||||
}
|
||||
|
||||
// DrawRoundRect
|
||||
|
||||
// FillRegion
|
||||
void
|
||||
DrawingEngine::DrawRoundRect(BRect r, const float &xrad,
|
||||
const float &yrad, const DrawState *d,
|
||||
bool filled)
|
||||
DrawingEngine::FillRegion(BRegion& r, const RGBColor& color)
|
||||
{
|
||||
if (Lock()) {
|
||||
// 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);
|
||||
// NOTE: Write locking because we might use HW acceleration.
|
||||
// This needs to be investigated, I'm doing this because of
|
||||
// gut feeling.
|
||||
if (WriteLock()) {
|
||||
BRect clipped = fPainter->ClipRect(r.Frame());
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
|
||||
: fPainter->StrokeRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
|
||||
bool doInSoftware = true;
|
||||
// try hardware optimized version first
|
||||
if ((fAvailableHWAccleration & HW_ACC_FILL_REGION) != 0) {
|
||||
fGraphicsCard->FillRegion(r, color);
|
||||
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();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
WriteUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
// DrawShape
|
||||
|
||||
void
|
||||
DrawingEngine::DrawShape(const BRect& bounds, const int32& opCount,
|
||||
const uint32* opList, const int32& ptCount,
|
||||
const BPoint* ptList, const DrawState* d,
|
||||
bool filled)
|
||||
DrawingEngine::DrawRoundRect(BRect r, float xrad, float yrad,
|
||||
const DrawState* d, bool filled)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
if (!Lock())
|
||||
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);
|
||||
BRect touched = fPainter->DrawShape(opCount, opList,
|
||||
ptCount, ptList,
|
||||
filled);
|
||||
BRect touched = filled ? fPainter->FillRoundRect(r, xrad, yrad)
|
||||
: fPainter->StrokeRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
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
|
||||
DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
|
||||
const DrawState* d, bool filled)
|
||||
const DrawState* d, bool filled)
|
||||
{
|
||||
if (Lock()) {
|
||||
BRect clipped(bounds);
|
||||
@@ -840,13 +873,13 @@ DrawingEngine::DrawTriangle(BPoint* pts, const BRect& bounds,
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
|
||||
fPainter->SetDrawState(d);
|
||||
if (filled)
|
||||
fPainter->FillTriangle(pts[0], pts[1], pts[2]);
|
||||
else
|
||||
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
@@ -892,9 +925,9 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
|
||||
touched = fPainter->ClipRect(touched);
|
||||
if (touched.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
|
||||
touched = fPainter->StrokeLine(start, end, context);
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
@@ -905,13 +938,12 @@ DrawingEngine::StrokeLine(const BPoint &start, const BPoint &end, DrawState* con
|
||||
|
||||
// StrokeLineArray
|
||||
void
|
||||
DrawingEngine::StrokeLineArray(const int32 &numlines,
|
||||
const LineArrayData *linedata,
|
||||
const DrawState *d)
|
||||
DrawingEngine::StrokeLineArray(int32 numLines,
|
||||
const LineArrayData *linedata, const DrawState *d)
|
||||
{
|
||||
if(!d || !linedata || numlines <= 0)
|
||||
if (!d || !linedata || numLines <= 0)
|
||||
return;
|
||||
|
||||
|
||||
if (Lock()) {
|
||||
// figure out bounding box for line array
|
||||
const LineArrayData *data = (const LineArrayData *)&(linedata[0]);
|
||||
@@ -919,7 +951,8 @@ DrawingEngine::StrokeLineArray(const int32 &numlines,
|
||||
min_c(data->pt1.y, data->pt2.y),
|
||||
max_c(data->pt1.x, data->pt2.x),
|
||||
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]);
|
||||
BRect box(min_c(data->pt1.x, data->pt2.x),
|
||||
min_c(data->pt1.y, data->pt2.y),
|
||||
@@ -931,20 +964,20 @@ DrawingEngine::StrokeLineArray(const int32 &numlines,
|
||||
touched = fPainter->ClipRect(touched);
|
||||
if (touched.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
|
||||
DrawState context;
|
||||
context.SetDrawingMode(B_OP_COPY);
|
||||
|
||||
|
||||
data = (const LineArrayData *)&(linedata[0]);
|
||||
context.SetHighColor(data->color);
|
||||
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]);
|
||||
context.SetHighColor(data->color);
|
||||
fPainter->StrokeLine(data->pt1, data->pt2, &context);
|
||||
}
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
@@ -1007,11 +1040,11 @@ DrawingEngine::DrawString(const char* string, int32 length,
|
||||
if (b.IsValid()) {
|
||||
//printf("bounding box '%s': %lld µs\n", string, system_time() - now);
|
||||
fGraphicsCard->HideSoftwareCursor(b);
|
||||
|
||||
|
||||
//now = system_time();
|
||||
BRect touched = fPainter->DrawString(string, length, pt, delta);
|
||||
//printf("drawing string: %lld µs\n", system_time() - now);
|
||||
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
@@ -1119,22 +1152,20 @@ DrawingEngine::DumpToBitmap()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// _CopyRect
|
||||
|
||||
BRect
|
||||
DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
|
||||
{
|
||||
BRect dst;
|
||||
RenderingBuffer* buffer = fGraphicsCard->DrawingBuffer();
|
||||
if (buffer) {
|
||||
|
||||
BRect clip(0, 0, buffer->Width() - 1, buffer->Height() - 1);
|
||||
|
||||
dst = src;
|
||||
dst.OffsetBy(xOffset, yOffset);
|
||||
|
||||
if (clip.Intersects(src) && clip.Intersects(dst)) {
|
||||
|
||||
uint32 bpr = buffer->BytesPerRow();
|
||||
uint32 bytesPerRow = buffer->BytesPerRow();
|
||||
uint8* bits = (uint8*)buffer->Bits();
|
||||
|
||||
// clip source rect
|
||||
@@ -1146,12 +1177,12 @@ DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
|
||||
src = src & dst;
|
||||
|
||||
// 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 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
|
||||
dst.OffsetBy(xOffset, yOffset);
|
||||
@@ -1160,10 +1191,10 @@ DrawingEngine::_CopyRect(BRect src, int32 xOffset, int32 yOffset) const
|
||||
return dst;
|
||||
}
|
||||
|
||||
// _CopyRect
|
||||
|
||||
void
|
||||
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 yIncrement;
|
||||
@@ -1179,14 +1210,14 @@ DrawingEngine::_CopyRect(uint8* src, uint32 width, uint32 height,
|
||||
|
||||
if (yOffset > 0) {
|
||||
// copy from bottom to top
|
||||
yIncrement = -bpr;
|
||||
src += (height - 1) * bpr;
|
||||
yIncrement = -bytesPerRow;
|
||||
src += (height - 1) * bytesPerRow;
|
||||
} else {
|
||||
// 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++) {
|
||||
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,
|
||||
// it is therefor yet "untransformed".
|
||||
const agg::rect& r = glyph->bounds;
|
||||
BRect glyphBounds(r.x1 + x, r.y1 + y - 1, r.x2 + x + 1, r.y2 + y);
|
||||
// NOTE: "- 1"/"+ 1" fixes some weird problem with the bounding box
|
||||
// might be a bug in AGG
|
||||
BRect glyphBounds(r.x1 + x, r.y1 + y - 1, r.x2 + x + 1, r.y2 + y + 1);
|
||||
// NOTE: "-1"/"+ 1" converts the glyph bounding box from pixel
|
||||
// indices to pixel area coordinates
|
||||
|
||||
// track bounding box
|
||||
if (glyphBounds.IsValid())
|
||||
|
||||
@@ -77,7 +77,6 @@ Server haiku_app_server :
|
||||
# Misc. Sources
|
||||
Decorator.cpp
|
||||
DebugInfoManager.cpp
|
||||
SubWindowList.cpp
|
||||
PNGDump.cpp
|
||||
RAMLinkMsgReader.cpp
|
||||
MessageLooper.cpp
|
||||
@@ -108,13 +107,13 @@ Server haiku_app_server :
|
||||
VirtualScreen.cpp
|
||||
BitmapHWInterface.cpp
|
||||
DefaultDecorator.cpp
|
||||
Layer.cpp
|
||||
OffscreenServerWindow.cpp
|
||||
OffscreenWindowLayer.cpp
|
||||
RootLayer.cpp
|
||||
ServerPicture.cpp
|
||||
ServerScreen.cpp
|
||||
ViewLayer.cpp
|
||||
WindowLayer.cpp
|
||||
WindowList.cpp
|
||||
Workspace.cpp
|
||||
WorkspacesLayer.cpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user