Merged app_server_new_clipping branch changes r15290 to 15418 back into trunk.

Also fixed Jamfile for the test environment.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15419 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-12-08 12:41:19 +00:00
parent af43bb3c94
commit e83820ed57
41 changed files with 5348 additions and 5375 deletions
+6 -7
View File
@@ -80,16 +80,15 @@ class Decorator {
bool GetMinimize();
bool 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,
+80 -123
View File
@@ -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_
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+1 -1
View File
@@ -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
+1 -1
View File
@@ -7,7 +7,7 @@
*
*/
#include "RootLayer.h"
//#include "RootLayer.h"
#include "DebugInfoManager.h"
+2 -2
View File
@@ -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
{
}
+15 -17
View File
@@ -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;
+2 -2
View File
@@ -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);
File diff suppressed because it is too large Load Diff
+82 -14
View File
@@ -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
+52 -3
View File
@@ -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();
}
}
+12
View File
@@ -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;
};
+2 -3
View File
@@ -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
-267
View File
@@ -1,267 +0,0 @@
/*
* Copyright (c) 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef _LAYER_H_
#define _LAYER_H_
#include "RGBColor.h"
#include "ServerWindow.h"
#include <GraphicsDefs.h>
#include <List.h>
#include <Locker.h>
#include <OS.h>
#include <String.h>
#include <Rect.h>
#include <Region.h>
enum {
B_LAYER_NONE = 1,
B_LAYER_MOVE = 2,
B_LAYER_SIMPLE_MOVE = 3,
B_LAYER_RESIZE = 4,
B_LAYER_MASK_RESIZE = 5,
};
enum {
B_LAYER_ACTION_NONE = 0,
B_LAYER_ACTION_MOVE,
B_LAYER_ACTION_RESIZE
};
class ServerApp;
class RootLayer;
class DrawingEngine;
class DrawState;
class ServerBitmap;
class PointerEvent {
public:
int32 code; // B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED,
// B_MOUSE_WHEEL_CHANGED
bigtime_t when;
BPoint where;
float wheel_delta_x;
float wheel_delta_y;
int32 modifiers;
int32 buttons; // B_PRIMARY_MOUSE_BUTTON, B_SECONDARY_MOUSE_BUTTON
// B_TERTIARY_MOUSE_BUTTON
int32 clicks;
};
class Layer {
public:
Layer(BRect frame, const char* name,
int32 token, uint32 resize,
uint32 flags, DrawingEngine* driver);
virtual ~Layer();
// name
virtual void SetName(const char* name);
inline const char* Name() const
{ return fName.String(); }
int32 ViewToken() const { return fViewToken; }
// children handling
void AddChild(Layer* child, ServerWindow* serverWin);
void RemoveChild(Layer* child);
void RemoveSelf();
bool HasChild(Layer* layer);
Layer* Parent() const
{ return fParent; }
uint32 CountChildren() const;
Layer* LayerAt(BPoint where);
Layer* FirstChild() const;
Layer* LastChild() const;
Layer* NextLayer() const;
Layer* PreviousLayer() const;
void SetAsTopLayer(bool option)
{ fIsTopLayer = option; }
inline bool IsTopLayer() const
{ return fIsTopLayer; }
// visible state
void Show(bool invalidate = true);
void Hide(bool invalidate = true);
bool IsHidden() const;
bool IsVisuallyHidden() const;
// graphic state and attributes
void PushState();
void PopState();
DrawState* CurrentState() const { return fDrawState; }
void SetViewColor(const RGBColor& color);
inline const RGBColor& ViewColor() const
{ return fViewColor; }
void SetBackgroundBitmap(const ServerBitmap* bitmap);
inline const ServerBitmap* BackgroundBitmap() const
{ return fBackgroundBitmap; }
void SetOverlayBitmap(const ServerBitmap* bitmap);
inline const ServerBitmap* OverlayBitmap() const
{ return fOverlayBitmap; }
// coordinate system
BRect Bounds() const;
BRect Frame() const;
BPoint ScrollingOffset() const;
void SetDrawingOrigin(BPoint origin);
BPoint DrawingOrigin() const;
void SetScale(float scale);
float Scale() const;
void ConvertToParent(BPoint* pt) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(BRegion* reg) const;
void ConvertFromParent(BPoint* pt) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(BRegion* reg) const;
void ConvertToScreen(BPoint* pt) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(BRegion* reg) const;
void ConvertFromScreen(BPoint* pt) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(BRegion* reg) const;
void ConvertToScreenForDrawing(BPoint* pt) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* reg) const;
void ConvertFromScreenForDrawing(BPoint* pt) const;
virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y);
virtual void ScrollBy(float x, float y);
void CopyBits(BRect& src, BRect& dst,
int32 xOffset, int32 yOffset);
// input handling
virtual void MouseDown(BMessage *msg, BPoint where, int32* _viewToken);
virtual void MouseUp(BMessage *msg, BPoint where, int32* _viewToken);
virtual void MouseMoved(BMessage *msg, BPoint where, int32* _viewToken);
virtual void WorkspaceActivated(int32 index, bool active);
virtual void WorkspacesChanged(uint32 oldWorkspaces, uint32 newWorkspaces);
virtual void Activated(bool active);
// action hooks
virtual void MovedByHook(float dx, float dy);
virtual void ResizedByHook(float dx, float dy, bool automatic);
virtual void ScrolledByHook(float dx, float dy);
// app_server objects getters
ServerWindow* Window() const
{ return fWindow; }
ServerApp* App() const
{ return fWindow ? fWindow->App() : NULL; }
RootLayer* GetRootLayer() const
{ return fRootLayer; }
void SetRootLayer(RootLayer* rl)
{ fRootLayer = rl; }
DrawingEngine* GetDrawingEngine() const
{ return fDriver; }
void SetEventMask(uint32 eventMask, uint32 options);
uint32 EventMask() const
{ return fEventMask; }
uint32 EventOptions() const
{ return fEventOptions; }
inline uint32 ResizeMode() const
{ return fResizeMode; }
inline uint32 Flags() const
{ return fFlags; }
void SetFlags(uint32 flags);
// clipping stuff and redraw
void SetUserClipping(const BRegion& region);
// region is expected in layer coordinates
inline const BRegion& VisibleRegion() const { return fVisible; }
inline const BRegion& FullVisible() const { return fFullVisible; }
inline const BRegion& DrawingRegion() const { return fDrawingRegion; }
virtual void GetOnScreenRegion(BRegion& region);
void MarkForRebuild(const BRegion &dirty);
void TriggerRebuild();
void _GetAllRebuildDirty(BRegion *totalReg);
virtual void Draw(const BRect& updateRect);
virtual void _AllRedraw(const BRegion& invalid);
protected:
friend class RootLayer;
friend class ServerWindow;
bool _AddChildToList(Layer* child, Layer* before = NULL);
void _RemoveChildFromList(Layer* child);
// private clipping stuff
virtual void _ReserveRegions(BRegion &reg);
void _RebuildVisibleRegions( const BRegion &invalid,
const BRegion &parentLocalVisible,
const Layer *startFrom);
void _RebuildDrawingRegion();
void _ClearVisibleRegions();
void _ResizeLayerFrameBy(float x, float y);
void _RezizeLayerRedrawMore(BRegion &reg, float dx, float dy);
void _ResizeLayerFullUpdateOnResize(BRegion &reg, float dx, float dy);
// for updating client-side coordinates
void _AddToViewsWithInvalidCoords() const;
void _SendViewCoordUpdateMsg() const;
BString fName;
BRect fFrame;
BPoint fScrollingOffset;
BRegion fVisible;
BRegion fFullVisible;
BRegion fDirtyForRebuild;
BRegion fDrawingRegion;
DrawingEngine* fDriver;
RootLayer* fRootLayer;
ServerWindow* fWindow;
DrawState* fDrawState;
Layer* fParent;
Layer* fPreviousSibling;
Layer* fNextSibling;
Layer* fFirstChild;
Layer* fLastChild;
int32 fViewToken;
uint32 fFlags;
uint32 fResizeMode;
uint32 fEventMask;
uint32 fEventOptions;
bool fHidden;
bool fIsTopLayer;
RGBColor fViewColor;
const ServerBitmap* fBackgroundBitmap;
const ServerBitmap* fOverlayBitmap;
};
#endif // _LAYER_H_
+7 -1
View File
@@ -19,7 +19,7 @@
OffscreenWindowLayer::OffscreenWindowLayer(ServerBitmap* bitmap,
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;
}
+1 -1
View File
@@ -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);
-825
View File
@@ -1,825 +0,0 @@
/*
* Copyright 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Gabe Yoder <gyoder@stny.rr.com>
* DarkWyrm <bpmagic@columbus.rr.com>
* Adrian Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/
/** Class used for the top layer of each workspace's Layer tree */
#include "Decorator.h"
#include "DrawingEngine.h"
#include "HWInterface.h"
#include "Layer.h"
#include "RootLayer.h"
#include "ServerApp.h"
#include "ServerConfig.h"
#include "ServerProtocol.h"
#include "ServerScreen.h"
#include "ServerWindow.h"
#include "WindowLayer.h"
#include "WorkspacePrivate.h"
#include "WorkspacesLayer.h"
#include <File.h>
#include <List.h>
#include <Message.h>
#include <PortLink.h>
#include <Window.h>
#include <stdio.h>
#if DISPLAY_HAIKU_LOGO
#include "ServerBitmap.h"
#include "HaikuLogo.h"
static const float kGoldenProportion = (sqrtf(5.0) - 1.0) / 2.0;
#endif
//#define TRACE_ROOT_LAYER
#ifdef TRACE_ROOT_LAYER
# define STRACE(a) printf a
#else
# define STRACE(a) ;
#endif
RootLayer::RootLayer(const char *name, Desktop *desktop, DrawingEngine *driver)
: Layer(BRect(0, 0, 0, 0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver),
fDesktop(desktop),
fDragMessage(NULL),
fMouseEventWindow(NULL),
fAllRegionsLock("root layer region lock"),
fDirtyForRedraw(),
fWorkspace(0),
fWorkspacesLayer(NULL),
fFocus(NULL),
fFront(NULL),
fBack(NULL)
{
//NOTE: be careful about this one.
fRootLayer = this;
// Some stuff that will go away in the future but fills some gaps right now
#if ON_SCREEN_DEBUGGING_INFO
fDebugInfo.SetTo("");
#endif
fDrawState->SetHighColor(RGBColor(255, 255, 255));
#if DISPLAY_HAIKU_LOGO
fLogoBitmap = new UtilityBitmap(BRect(0.0, 0.0, kLogoWidth - 1.0,
kLogoHeight - 1.0),
kLogoFormat, 0);
if (fLogoBitmap->IsValid()) {
int32 size = min_c(sizeof(kLogoBits), fLogoBitmap->BitsLength());
memcpy(fLogoBitmap->Bits(), kLogoBits, size);
} else {
delete fLogoBitmap;
fLogoBitmap = NULL;
}
#endif // DISPLAY_HAIKU_LOGO
fHidden = false;
#if ON_SCREEN_DEBUGGING_INFO
DebugInfoManager::Default()->SetRootLayer(this);
#endif
fFrame = desktop->VirtualScreen().Frame();
// RootLayer starts with valid visible regions
fFullVisible.Set(Bounds());
fVisible.Set(Bounds());
// first make sure we are actualy visible
MarkForRebuild(Bounds());
MarkForRedraw(Bounds());
_UpdateWorkspace(fDesktop->WorkspaceAt(fDesktop->CurrentWorkspace()));
TriggerRebuild();
TriggerRedraw();
}
RootLayer::~RootLayer()
{
delete fDragMessage;
fFirstChild = NULL;
// this prevents the Layer destructor from freeing our children again
// (the Desktop destructor already took care of that)
// RootLayer object just uses Screen objects, it is not allowed to delete them.
#if DISPLAY_HAIKU_LOGO
delete fLogoBitmap;
#endif
}
void
RootLayer::MoveBy(float x, float y)
{
}
void
RootLayer::ResizeBy(float x, float y)
{
if (x == 0 && y == 0)
return;
// TODO: we should be able to update less here
//BRect previous = fFrame;
fFrame.right += x;
fFrame.bottom += y;
fFullVisible.Set(Bounds());
fVisible.Set(Bounds());
BRegion region(fFrame);
MarkForRebuild(region);
TriggerRebuild();
//region.Exclude(previous);
MarkForRedraw(region);
TriggerRedraw();
}
bool
RootLayer::_SetFocus(WindowLayer* focus, BRegion& update)
{
// TODO: test for FFM and B_LOCK_WINDOW_FOCUS
if (focus == fFocus && (focus->WindowFlags() & B_AVOID_FOCUS) == 0)
return true;
// make sure no window is chosen that doesn't want focus
while (focus != NULL && (focus->WindowFlags() & B_AVOID_FOCUS) != 0) {
focus = (WindowLayer*)focus->PreviousLayer();
}
if (fFocus != NULL) {
update.Include(&fFocus->VisibleRegion());
fFocus->SetFocus(false);
}
fFocus = focus;
if (focus != NULL) {
update.Include(&focus->VisibleRegion());
focus->SetFocus(true);
}
return true;
}
bool
RootLayer::SetFocus(WindowLayer* focus)
{
BAutolock _(fAllRegionsLock);
BRegion update;
bool success = _SetFocus(focus, update);
if (!success)
return false;
MarkForRedraw(update);
TriggerRedraw();
return true;
}
/*!
\brief Tries to move the specified window to the front of the screen.
If there are any modal windows on this screen, it might not actually
become the frontmost window, though, as modal windows stay in front
of their subset.
*/
void
RootLayer::_SetFront(WindowLayer* window, BRegion& update)
{
if (window == NULL) {
fBack = NULL;
fFront = NULL;
return;
}
if (!window->SupportsFront() && fFront != NULL)
return;
BRegion previous = window->FullVisible();
WindowLayer* frontmost = window->Frontmost();
_RemoveChildFromList(window);
if (frontmost != NULL && frontmost->IsModal()) {
// all modal windows follow their subsets to the front
// (ie. they are staying in front of them, but they are
// not supposed to change their order because of that)
WindowLayer* nextModal;
for (WindowLayer* modal = frontmost; modal != NULL ; modal = nextModal) {
nextModal = (WindowLayer*)modal->NextLayer();
if (nextModal == frontmost) {
// since we're adding the modal windows to the end of the list
// we're traversing, we must stop when we've reached the initial
// starting point again
nextModal = NULL;
} else if (nextModal != NULL
&& (!nextModal->IsModal() || !nextModal->HasInSubset(window)))
nextModal = NULL;
previous.Include(&modal->FullVisible());
WindowLayer* modalFrontmost = modal->Frontmost();
_RemoveChildFromList(modal);
_AddChildToList(modal, modalFrontmost);
BRegion modalRegion;
modal->GetOnScreenRegion(modalRegion);
// TODO: this is not what we want, we'd want the new visible region
update.Include(&modalRegion);
}
}
_AddChildToList(window, frontmost);
BRegion windowRegion;
window->GetOnScreenRegion(windowRegion);
// TODO: this is not what we want, we'd want the new visible region
update.Include(&windowRegion);
update.Exclude(&previous);
_UpdateFront();
if (window == fBack || fBack == NULL)
_UpdateBack();
}
/*! search the visible windows for a valid back window
(only normal windows can be back windows)
*/
void
RootLayer::_UpdateBack()
{
fBack = NULL;
for (WindowLayer* window = (WindowLayer*)FirstChild();
window != NULL; window = (WindowLayer*)window->NextLayer()) {
if (window->IsHidden() || !window->SupportsFront())
continue;
fBack = window;
break;
}
}
/*! search the visible windows for a valid front window
(only normal windows can be front windows)
*/
void
RootLayer::_UpdateFront()
{
// TODO: for now, just choose the top window
fFront = NULL;
for (WindowLayer* window = (WindowLayer*)LastChild();
window != NULL; window = (WindowLayer*)window->PreviousLayer()) {
if (window->IsHidden() || !window->SupportsFront())
continue;
fFront = window;
break;
}
}
void
RootLayer::_UpdateFronts()
{
_UpdateBack();
_UpdateFront();
}
void
RootLayer::ActivateWindow(WindowLayer* window)
{
BAutolock _(fAllRegionsLock);
BRegion changed;
_SetFront(window, changed);
// TODO: if this window has any floating windows, add them here
MarkForRebuild(changed);
TriggerRebuild();
_SetFocus(Front(), changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::SendBehindWindow(WindowLayer* windowLayer, WindowLayer* behindOf)
{
BAutolock _(fAllRegionsLock);
if (windowLayer == Back())
return;
bool wasFocus = windowLayer == Focus();
BRegion changed = windowLayer->FullVisible();
_RemoveChildFromList(windowLayer);
if (behindOf == NULL)
behindOf = Back();
_AddChildToList(windowLayer, behindOf);
// TODO: if this window has any floating windows, remove them here
MarkForRebuild(changed);
TriggerRebuild();
_UpdateFronts();
_SetFocus(Front(), changed);
changed.Exclude(&windowLayer->FullVisible());
if (wasFocus != (Focus() == windowLayer))
changed.Include(&windowLayer->VisibleRegion());
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::AddWindow(WindowLayer* window)
{
STRACE(("AddWindowLayer(%p \"%s\")\n", window, window->Name()));
if (window->SupportsFront())
_AddChildToList(window, window->Frontmost((WindowLayer*)FirstChild()));
else
_AddChildToList(window, Back());
window->SetRootLayer(this);
if (!window->IsHidden())
ActivateWindow(window);
}
void
RootLayer::RemoveWindow(WindowLayer* window)
{
if (!window->IsHidden())
HideWindow(window);
_RemoveChildFromList(window);
LayerRemoved(window);
window->SetRootLayer(NULL);
}
void
RootLayer::_UpdateWorkspace(Workspace::Private& workspace)
{
fColor = workspace.Color();
#if ON_SCREEN_DEBUGGING_INFO
fDrawState->SetLowColor(fColor);
#endif
}
void
RootLayer::SetWorkspace(int32 index, Workspace::Private& previousWorkspace,
Workspace::Private& workspace)
{
BAutolock _(fAllRegionsLock);
int32 previousIndex = fWorkspace;
// build region of windows that are no longer visible in the new workspace
// and move windows to the previous workspace's window list
BRegion changed;
while (WindowLayer* window = (WindowLayer*)FirstChild()) {
// move the window into the workspace's window list
_RemoveChildFromList(window);
BPoint position = window->Frame().LeftTop();
previousWorkspace.AddWindow(window, &position);
if (window->IsHidden())
continue;
if (!window->OnWorkspace(index)) {
// this window will no longer be visible
changed.Include(&window->FullVisible());
}
}
fWorkspace = index;
_UpdateWorkspace(workspace);
// add new windows, and include them in the changed region - but only
// those that were not visible before (or whose position changed)
while (workspace.CountWindows() != 0) {
window_layer_info* info = workspace.WindowAt(0);
WindowLayer* window = info->window;
BPoint position = info->position;
// move window into the RootLayer's list
workspace.RemoveWindowAt(0);
_AddChildToList(window);
if (window->IsHidden())
continue;
if (position == kInvalidWindowPosition) {
// if you enter a workspace for the first time, the position
// of the window in the previous workspace is adopted
position = window->Frame().LeftTop();
// TODO: make sure the window is still on-screen if it
// was before!
}
if (!window->OnWorkspace(previousIndex)) {
// this window was not visible before
// TODO: what we really want here is the visible region of the window
BRegion region;
window->GetOnScreenRegion(region);
changed.Include(&region);
} else if (window->Frame().LeftTop() != position) {
// the window was visible before, but its on-screen location changed
BPoint offset = position - window->Frame().LeftTop();
window->MoveBy(offset.x, offset.y);
// TODO: we're playing dumb here - what we need is a MoveBy() that
// gives us a dirty region back, and since the new clipping code
// will give us just that, we don't take any special measurement
// here
GetOnScreenRegion(changed);
} else {
// the window is still visible and on the same location
continue;
}
}
_UpdateFronts();
_SetFocus(Front(), changed);
MarkForRebuild(changed);
TriggerRebuild();
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::HideWindow(WindowLayer* window)
{
BAutolock _(fAllRegionsLock);
BRegion changed = window->FullVisible();
window->Hide();
_UpdateFronts();
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
fWorkspacesLayer = NULL;
// TODO: if this window has any floating windows, remove them here
MarkForRebuild(changed);
TriggerRebuild();
if (window == Focus())
_SetFocus(Front(), changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
void
RootLayer::ShowWindow(WindowLayer* window, bool toFront)
{
STRACE(("ShowWindowLayer(%p)\n", window));
if (!window->IsHidden())
return;
BAutolock _(fAllRegionsLock);
window->Show();
BRegion changed = window->FullVisible();
if (toFront)
_SetFront(window, changed);
else
_UpdateFront();
// TODO: if this window has any floating windows, remove them here
// TODO: support FFM
if (Front() == window || Focus() == NULL)
_SetFocus(window, changed);
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
fWorkspacesLayer = window->TopLayer();
}
void
RootLayer::MoveWindowBy(WindowLayer* window, float x, float y)
{
BAutolock _(fAllRegionsLock);
// TODO: the MoveBy() should just return a dirty region
window->MoveBy(x, y);
BRegion changed;
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::ResizeWindowBy(WindowLayer* window, float x, float y)
{
BAutolock _(fAllRegionsLock);
// TODO: the MoveBy() should just return a dirty region
window->ResizeBy(x, y);
BRegion changed;
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::SetWindowLook(WindowLayer *window, window_look newLook)
{
if (window->Look() == newLook)
return;
BAutolock _(fAllRegionsLock);
BRegion changed;
window->SetLook(newLook, window->Parent() ? &changed : NULL);
if (window->Parent() != NULL) {
MarkForRebuild(changed);
TriggerRebuild();
}
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::SetWindowFeel(WindowLayer *window, window_feel newFeel)
{
if (window->Feel() == newFeel)
return;
BAutolock _(fAllRegionsLock);
window->SetFeel(newFeel);
// TODO: implement window feels!
}
void
RootLayer::SetWindowFlags(WindowLayer *window, uint32 newFlags)
{
if (window->WindowFlags() == newFlags)
return;
BAutolock _(fAllRegionsLock);
BRegion changed;
window->SetWindowFlags(newFlags, window->Parent() ? &changed : NULL);
if (window->Parent() != NULL) {
MarkForRebuild(changed);
TriggerRebuild();
}
_WindowsChanged(changed);
if (changed.CountRects() > 0) {
MarkForRedraw(changed);
TriggerRedraw();
}
}
void
RootLayer::_WindowsChanged(BRegion& region)
{
if (fWorkspacesLayer == NULL)
return;
region.Include(&fWorkspacesLayer->VisibleRegion());
}
void
RootLayer::UpdateWorkspaces()
{
BAutolock _(fAllRegionsLock);
if (fWorkspacesLayer == NULL)
return;
BRegion changed;
_WindowsChanged(changed);
MarkForRedraw(changed);
TriggerRedraw();
}
WindowLayer*
RootLayer::WindowAt(BPoint where)
{
if (VisibleRegion().Contains(where))
return NULL;
for (Layer* child = LastChild(); child; child = child->PreviousLayer()) {
if (child->FullVisible().Contains(where))
return dynamic_cast<WindowLayer*>(child);
}
return NULL;
}
void
RootLayer::SetMouseEventWindow(WindowLayer* window)
{
fMouseEventWindow = window;
}
void
RootLayer::LayerRemoved(Layer* layer)
{
if (fMouseEventWindow == layer)
fMouseEventWindow = NULL;
if (fWorkspacesLayer == layer)
fWorkspacesLayer = NULL;
}
void
RootLayer::SetDragMessage(BMessage* msg)
{
if (fDragMessage) {
delete fDragMessage;
fDragMessage = NULL;
}
if (msg)
fDragMessage = new BMessage(*msg);
}
BMessage *
RootLayer::DragMessage() const
{
return fDragMessage;
}
void
RootLayer::Draw(const BRect& rect)
{
fDriver->FillRect(rect, fColor);
#if ON_SCREEN_DEBUGGING_INFO
BPoint location(5, 40);
float textHeight = 15.0; // be lazy
const char* p = fDebugInfo.String();
const char* start = p;
while (*p) {
p++;
if (*p == 0 || *p == '\n') {
fDriver->DrawString(start, p - start, location,
fDrawState);
// NOTE: Eventually, this will be below the screen!
location.y += textHeight;
start = p + 1;
}
}
#endif // ON_SCREEN_DEBUGGING_INFO
#if DISPLAY_HAIKU_LOGO
if (fLogoBitmap) {
BPoint logoPos;
logoPos.x = floorf(min_c(fFrame.left + fFrame.Width() * kGoldenProportion,
fFrame.right - (kLogoWidth + kLogoHeight / 2.0)));
logoPos.y = floorf(fFrame.bottom - kLogoHeight * 1.5);
BRect bitmapBounds = fLogoBitmap->Bounds();
fDriver->DrawBitmap(fLogoBitmap, bitmapBounds,
bitmapBounds.OffsetToCopy(logoPos), fDrawState);
}
#endif // DISPLAY_HAIKU_LOGO
}
#if ON_SCREEN_DEBUGGING_INFO
void
RootLayer::AddDebugInfo(const char* string)
{
if (Lock()) {
fDebugInfo << string;
MarkForRedraw(VisibleRegion());
TriggerRedraw();
Unlock();
}
}
#endif // ON_SCREEN_DEBUGGING_INFO
void
RootLayer::MarkForRedraw(const BRegion &dirty)
{
BAutolock locker(fAllRegionsLock);
fDirtyForRedraw.Include(&dirty);
}
void
RootLayer::TriggerRedraw()
{
BAutolock locker(fAllRegionsLock);
#if 0
// for debugging
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
RGBColor color(rand()%255, rand()%255, rand()%255);
GetDrawingEngine()->FillRect(Bounds(), color);
snooze(200000);
GetDrawingEngine()->ConstrainClippingRegion(NULL);
#endif
_AllRedraw(fDirtyForRedraw);
fDirtyForRedraw.MakeEmpty();
}
-142
View File
@@ -1,142 +0,0 @@
/*
* Copyright 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Gabe Yoder <gyoder@stny.rr.com>
* DarkWyrm <bpmagic@columbus.rr.com>
* Adrian Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef ROOT_LAYER_H
#define ROOT_LAYER_H
#include <List.h>
#include <Locker.h>
#include <MessageQueue.h>
#include "DebugInfoManager.h"
#include "Desktop.h"
#include "Layer.h"
#include "Workspace.h"
class DrawingEngine;
class HWInterface;
class RGBColor;
class Screen;
class WindowLayer;
namespace BPrivate {
class PortLink;
};
#ifndef DISPLAY_HAIKU_LOGO
# define DISPLAY_HAIKU_LOGO 1
#endif
#if DISPLAY_HAIKU_LOGO
class UtilityBitmap;
#endif
class RootLayer : public Layer {
public:
RootLayer(const char *name, Desktop *desktop,
DrawingEngine *driver);
virtual ~RootLayer();
Desktop* GetDesktop() const { return fDesktop; }
virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y);
virtual void ScrollBy(float x, float y)
{ /* not allowed */ }
void HideWindow(WindowLayer* window);
void ShowWindow(WindowLayer* window, bool toFront = true);
void MoveWindowBy(WindowLayer* window, float x, float y);
void ResizeWindowBy(WindowLayer* window, float x, float y);
bool SetFocus(WindowLayer* focus);
WindowLayer* Focus() const { return fFocus; }
WindowLayer* Front() const { return fFront; }
WindowLayer* Back() const { return fBack; }
void SetWorkspace(int32 index,
Workspace::Private& previousWorkspace,
Workspace::Private& workspace);
void SetDragMessage(BMessage *msg);
BMessage* DragMessage() const;
WindowLayer* WindowAt(BPoint where);
WindowLayer* MouseEventWindow() const { return fMouseEventWindow; }
void SetMouseEventWindow(WindowLayer* layer);
void LayerRemoved(Layer* layer);
// Other methods
bool Lock() { return fAllRegionsLock.Lock(); }
void Unlock() { fAllRegionsLock.Unlock(); }
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
void ActivateWindow(WindowLayer* window);
void SendBehindWindow(WindowLayer* window, WindowLayer* front);
void SetWindowLook(WindowLayer *window, window_look newLook);
void SetWindowFeel(WindowLayer *window, window_feel newFeel);
void SetWindowFlags(WindowLayer *window, uint32 newFlags);
void UpdateWorkspaces();
void MarkForRedraw(const BRegion &dirty);
void TriggerRedraw();
void Draw(const BRect &r);
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
void AddWindow(WindowLayer* window);
void RemoveWindow(WindowLayer* window);
private:
bool _SetFocus(WindowLayer* focus, BRegion& update);
void _SetFront(WindowLayer* front, BRegion& update);
void _UpdateBack();
void _UpdateFront();
void _UpdateFronts();
void _WindowsChanged(BRegion& region);
void _UpdateWorkspace(Workspace::Private& workspace);
Desktop* fDesktop;
BMessage* fDragMessage;
WindowLayer* fMouseEventWindow;
BLocker fAllRegionsLock;
BRegion fDirtyForRedraw;
int32 fWorkspace;
RGBColor fColor;
Layer* fWorkspacesLayer;
WindowLayer* fFocus;
WindowLayer* fFront;
WindowLayer* fBack;
#if ON_SCREEN_DEBUGGING_INFO
friend class DebugInfoManager;
void AddDebugInfo(const char* string);
BString fDebugInfo;
#endif
#if DISPLAY_HAIKU_LOGO
UtilityBitmap* fLogoBitmap;
#endif
};
#endif // ROOT_LAYER_H
+43 -58
View File
@@ -38,6 +38,7 @@
#include "CursorManager.h"
#include "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);
+2 -2
View File
@@ -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;
File diff suppressed because it is too large Load Diff
+19 -8
View File
@@ -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;
};
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <adioanca@cotty.iren.ro>
*/
/** List class for tracking floating and modal windows */
#include "SubWindowList.h"
#include "WindowLayer.h"
#include "ServerWindow.h"
#include <List.h>
#include <stdio.h>
SubWindowList::SubWindowList()
{
}
SubWindowList::~SubWindowList()
{
}
void
SubWindowList::AddWindowLayer(WindowLayer *windowLayer)
{
if (HasItem(windowLayer))
return;
int32 borderFeel = windowLayer->Feel();;
int32 location = 0;
for (; location < CountItems(); location++) {
int32 feelTemp = ((WindowLayer*)ItemAt(location))->Feel();
// in short: if 'windowLayer' is a floating window and 'temp' a modal one
if ((borderFeel == B_FLOATING_SUBSET_WINDOW_FEEL
|| borderFeel == B_FLOATING_APP_WINDOW_FEEL
|| borderFeel == B_FLOATING_ALL_WINDOW_FEEL)
&& (feelTemp == B_MODAL_SUBSET_WINDOW_FEEL
|| feelTemp == B_MODAL_APP_WINDOW_FEEL
|| feelTemp == B_MODAL_ALL_WINDOW_FEEL)) {
// means we found the place for our window('windowLayer')
break;
}
}
AddItem(windowLayer, location);
}
void
SubWindowList::AddSubWindowList(SubWindowList *list)
{
int32 i = 0;
for (; i < CountItems(); i++) {
int32 feel = ((WindowLayer*)ItemAt(i))->Feel();
if (feel == B_MODAL_SUBSET_WINDOW_FEEL
|| feel == B_MODAL_APP_WINDOW_FEEL
|| feel == B_MODAL_ALL_WINDOW_FEEL)
break;
}
for (int32 j = 0; j < list->CountItems(); j++) {
void *item = list->ItemAt(j);
int32 feel = ((WindowLayer*)item)->Feel();
if (feel == B_MODAL_SUBSET_WINDOW_FEEL
|| feel == B_MODAL_APP_WINDOW_FEEL
|| feel == B_MODAL_ALL_WINDOW_FEEL) {
AddItem(item, CountItems());
} else {
AddItem(item, i);
i++;
}
}
}
void
SubWindowList::PrintToStream() const
{
printf("Floating and modal windows list:\n");
WindowLayer* windowLayer = NULL;
for (int32 i=0; i<CountItems(); i++) {
windowLayer = (WindowLayer*)ItemAt(i);
printf("\t%s", windowLayer->Name());
if (windowLayer->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_SUBSET_WINDOW_FEEL");
if (windowLayer->Feel() == B_FLOATING_APP_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_APP_WINDOW_FEEL");
if (windowLayer->Feel() == B_FLOATING_ALL_WINDOW_FEEL)
printf("\t%s\n", "B_FLOATING_ALL_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_SUBSET_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_APP_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_APP_WINDOW_FEEL");
if (windowLayer->Feel() == B_MODAL_ALL_WINDOW_FEEL)
printf("\t%s\n", "B_MODAL_ALL_WINDOW_FEEL");
// this should NOT happen
if (windowLayer->Feel() == B_NORMAL_WINDOW_FEEL)
printf("\t%s\n", "B_NORMAL_WINDOW_FEEL");
}
}
-32
View File
@@ -1,32 +0,0 @@
/*
* Copyright 2001-2005, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Adrian Oanca <adioanca@cotty.iren.ro>
*/
#ifndef _SUB_WINDOW_LIST_H_
#define _SUB_WINDOW_LIST_H_
#include <List.h>
#include <Window.h>
class WindowLayer;
class SubWindowList : public BList {
public:
SubWindowList();
virtual ~SubWindowList();
void AddWindowLayer(WindowLayer *windowLayer);
// special
void AddSubWindowList(SubWindowList *list);
// debugging methods
void PrintToStream() const;
};
#endif /* _SUB_WINDOW_LIST_H_ */
File diff suppressed because it is too large Load Diff
+212
View File
@@ -0,0 +1,212 @@
/*
* Copyright (c) 2001-2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
*/
#ifndef VIEW_LAYER_H
#define VIEW_LAYER_H
#include "RGBColor.h"
#include <GraphicsDefs.h>
#include <Region.h>
#include <String.h>
class BList;
class DrawState;
class DrawingEngine;
class WindowLayer;
class ViewLayer {
public:
ViewLayer(BRect frame, const char* name,
int32 token, uint32 resizeMode,
uint32 flags);
virtual ~ViewLayer();
void SetName(const char* string);
const char* Name() const
{ return fName.String(); }
int32 Token() const
{ return fToken; }
BRect Frame() const
{ return fFrame; }
BRect Bounds() const;
void SetResizeMode(uint32 resizeMode)
{ fResizeMode = resizeMode; }
uint32 Flags() const
{ return fFlags; }
void SetFlags(uint32 flags);
BPoint ScrollingOffset() const;
void SetDrawingOrigin(BPoint origin);
BPoint DrawingOrigin() const;
void SetScale(float scale);
float Scale() const;
void SetUserClipping(const BRegion& region);
// region is expected in layer coordinates
// converts the given frame up the view hierarchy and
// clips to each views bounds
void ConvertToVisibleInTopView(BRect* bounds) const;
void AttachedToWindow(WindowLayer* window);
void DetachedFromWindow();
WindowLayer* Window() const { return fWindow; }
// tree stuff
void AddChild(ViewLayer* layer);
bool RemoveChild(ViewLayer* layer);
inline ViewLayer* Parent() const
{ return fParent; }
ViewLayer* FirstChild() const;
ViewLayer* LastChild() const;
ViewLayer* PreviousSibling() const;
ViewLayer* NextSibling() const;
ViewLayer* TopLayer();
uint32 CountChildren(bool deep = false) const;
void CollectTokensForChildren(BList* tokenMap) const;
ViewLayer* ViewAt(const BPoint& where,
BRegion* windowContentClipping);
// coordinate conversion
void ConvertToParent(BPoint* point) const;
void ConvertToParent(BRect* rect) const;
void ConvertToParent(BRegion* region) const;
void ConvertFromParent(BPoint* point) const;
void ConvertFromParent(BRect* rect) const;
void ConvertFromParent(BRegion* region) const;
void ConvertToScreen(BPoint* point) const;
void ConvertToScreen(BRect* rect) const;
void ConvertToScreen(BRegion* region) const;
void ConvertFromScreen(BPoint* point) const;
void ConvertFromScreen(BRect* rect) const;
void ConvertFromScreen(BRegion* region) const;
void ConvertToScreenForDrawing(BPoint* point) const;
void ConvertToScreenForDrawing(BRect* rect) const;
void ConvertToScreenForDrawing(BRegion* region) const;
void ConvertFromScreenForDrawing(BPoint* point) const;
// used when updating the pen position
void MoveBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ResizeBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ScrollBy(int32 dx, int32 dy,
BRegion* dirtyRegion);
void ParentResized(int32 dx, int32 dy,
BRegion* dirtyRegion);
void CopyBits(BRect src, BRect dst,
BRegion& windowContentClipping);
const BRegion& LocalClipping() const { return fLocalClipping; }
const RGBColor& ViewColor() const
{ return fViewColor; }
void SetViewColor(const RGBColor& color)
{ fViewColor = color; }
void PushState();
void PopState();
DrawState* CurrentState() const { return fDrawState; }
void SetEventMask(uint32 eventMask, uint32 options);
uint32 EventMask() const
{ return fEventMask; }
uint32 EventOptions() const
{ return fEventOptions; }
// for background clearing
virtual void Draw(DrawingEngine* drawingEngine,
BRegion* effectiveClipping,
BRegion* windowContentClipping,
bool deep = false);
void SetHidden(bool hidden);
bool IsHidden() const;
// takes into account parent views hidden status
bool IsVisible() const
{ return fVisible; }
// update visible status for this view and all children
// according to the parents visibility
void UpdateVisibleDeep(bool parentVisible);
// clipping
void RebuildClipping(bool deep);
BRegion& ScreenClipping(BRegion* windowContentClipping,
bool force = false) const;
void InvalidateScreenClipping(bool deep);
bool IsScreenClippingValid() const
{ return fScreenClippingValid; }
// debugging
void PrintToStream() const;
protected:
void _MoveScreenClipping(int32 x, int32 y,
bool deep);
BString fName;
int32 fToken;
// area within parent coordinate space
BRect fFrame;
// scrolling offset
BPoint fScrollingOffset;
RGBColor fViewColor;
DrawState* fDrawState;
uint32 fResizeMode;
uint32 fFlags;
bool fHidden;
bool fVisible;
uint32 fEventMask;
uint32 fEventOptions;
WindowLayer* fWindow;
ViewLayer* fParent;
ViewLayer* fFirstChild;
ViewLayer* fPreviousSibling;
ViewLayer* fNextSibling;
ViewLayer* fLastChild;
// clipping
BRegion fLocalClipping;
mutable BRegion fScreenClipping;
mutable bool fScreenClippingValid;
};
#endif // LAYER_H
File diff suppressed because it is too large Load Diff
+221 -95
View File
@@ -12,98 +12,135 @@
#include "Decorator.h"
#include "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 &reg);
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
+112
View File
@@ -0,0 +1,112 @@
/*
* Copyright (c) 2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#include "WindowLayer.h"
const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
window_anchor::window_anchor()
:
next(NULL),
previous(NULL),
position(kInvalidWindowPosition)
{
}
// #pragma mark -
WindowList::WindowList(int32 index)
:
fIndex(index),
fFirstWindow(NULL),
fLastWindow(NULL)
{
}
WindowList::~WindowList()
{
}
void
WindowList::SetIndex(int32 index)
{
fIndex = index;
}
void
WindowList::AddWindow(WindowLayer* window, WindowLayer* before)
{
window_anchor& windowAnchor = window->Anchor(fIndex);
if (before != NULL) {
window_anchor& beforeAnchor = before->Anchor(fIndex);
// add view before this one
windowAnchor.next = before;
windowAnchor.previous = beforeAnchor.previous;
if (windowAnchor.previous != NULL)
windowAnchor.previous->Anchor(fIndex).next = window;
beforeAnchor.previous = window;
if (fFirstWindow == before)
fFirstWindow = window;
} else {
// add view to the end of the list
if (fLastWindow != NULL) {
fLastWindow->Anchor(fIndex).next = window;
windowAnchor.previous = fLastWindow;
} else {
fFirstWindow = window;
windowAnchor.previous = NULL;
}
windowAnchor.next = NULL;
fLastWindow = window;
}
}
void
WindowList::RemoveWindow(WindowLayer* window)
{
// TODO: Axel, the same window can be removed in the same list
// more than once, would that be a bug?
window_anchor& windowAnchor = window->Anchor(fIndex);
if (fFirstWindow == window) {
// it's the first child
fFirstWindow = windowAnchor.next;
} else {
// it must have a previous sibling if it was not
// previously removed from this list
if (windowAnchor.previous)
windowAnchor.previous->Anchor(fIndex).next = windowAnchor.next;
}
if (fLastWindow == window) {
// it's the last child
fLastWindow = windowAnchor.previous;
} else {
// it must have a next sibling if it was not
// previously removed from this list
if (windowAnchor.next)
windowAnchor.next->Anchor(fIndex).previous = windowAnchor.previous;
}
windowAnchor.previous = NULL;
windowAnchor.next = NULL;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2005, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef WINDOW_LIST_H
#define WINDOW_LIST_H
#include <SupportDefs.h>
#include <Point.h>
class WindowLayer;
class WindowList {
public:
WindowList(int32 index = 0);
~WindowList();
void SetIndex(int32 index);
int32 Index() const { return fIndex; }
WindowLayer* FirstWindow() { return fFirstWindow; }
WindowLayer* LastWindow() { return fLastWindow; }
void AddWindow(WindowLayer* window, WindowLayer* before = NULL);
void RemoveWindow(WindowLayer* window);
private:
int32 fIndex;
WindowLayer* fFirstWindow;
WindowLayer* fLastWindow;
};
enum window_lists {
kAllWindowList = 32,
kFloatingList,
kWorkingList,
};
struct window_anchor {
window_anchor();
WindowLayer* next;
WindowLayer* previous;
BPoint position;
};
extern const BPoint kInvalidWindowPosition;
#endif // WINDOW_LIST_H
+14 -64
View File
@@ -7,8 +7,9 @@
*/
#include "RootLayer.h"
#include "Desktop.h"
#include "Workspace.h"
#include "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;
}
-1
View File
@@ -35,7 +35,6 @@ class Workspace {
private:
Workspace::Private& fWorkspace;
Desktop& fDesktop;
int32 fIndex;
WindowLayer* fCurrent;
bool fCurrentWorkspace;
};
+5 -17
View File
@@ -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 */
+35 -33
View File
@@ -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 -6
View File
@@ -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;
};
+118 -87
View File
@@ -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())
+2 -3
View File
@@ -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