offscreen bitmaps work, tested on Haiku as well, supports all colorspaces that BBitmap::ImportBits() supports. It uses a fallback for non-B_RGB(A)32 bitmaps. Added support for B_SUB_PIXEL_PRECISION view flags, though it is a bit hacky, since I had to add it to LayerData, even though it is not a true part of stack data. Added Layer::SetFlags() to enforce code path and update fLayerData. Cleaned up DisplayDriverPainter and DisplayDriver API (changed some const BRect& rect to simply BRect rect in order to be able to reuse it in the code), moved Painter.h, the test environment only draws the changed part of the frame buffer again - this causes a lot less CPU overhead, Painter special cases stroke width of 1.0 to use square caps, which is similar to R5 implementation and removes a lot of problems with non-straight line drawing, ServerWindow uses the DisplayDriver from it's WinBorder instead of the one from the Desktop (needed for offscreen windows, which have their own DisplayDriverPainter), it also checks for GetRootLayer() == NULL, because offscreen layers are not attached to a RootLayer, there was a fix for scrolling which worked at least in the test environment, it is now defunced, because Adi moved _CopyBits to Layer... I need to reenable it later, LayerData has no more fEscapementDelta, also fixed fFontAliasing (which was thought to overriding the font flags, and now works as such again), Desktop initialises the menu_info and scroll_bar_info stuff, which makes ScrollBars work actually... hope I didn't forget something.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13448 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -110,6 +110,7 @@ class Decorator {
|
||||
{ return (_colors) ? *_colors : ColorSet(); }
|
||||
|
||||
virtual void GetFootprint(BRegion *region);
|
||||
|
||||
virtual click_type Clicked(BPoint pt, int32 buttons,
|
||||
int32 modifiers);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ class BRect;
|
||||
class BRegion;
|
||||
|
||||
class DrawData;
|
||||
class HWInterface;
|
||||
class RGBColor;
|
||||
class ServerBitmap;
|
||||
class ServerCursor;
|
||||
@@ -60,6 +61,8 @@ public:
|
||||
// call this on mode changes!
|
||||
virtual void Update() = 0;
|
||||
|
||||
virtual void SetHWInterface(HWInterface* interface) = 0;
|
||||
|
||||
// clipping for all drawing functions
|
||||
virtual void ConstrainClippingRegion(BRegion* region) = 0;
|
||||
|
||||
@@ -73,14 +76,14 @@ public:
|
||||
int32 rCount,
|
||||
BRegion* clipReg) = 0;
|
||||
|
||||
virtual void InvertRect( const BRect &r) = 0;
|
||||
virtual void InvertRect( BRect r) = 0;
|
||||
|
||||
virtual void DrawBitmap( ServerBitmap *bitmap,
|
||||
const BRect &source,
|
||||
const BRect &dest,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillArc( const BRect &r,
|
||||
virtual void FillArc( BRect r,
|
||||
const float &angle,
|
||||
const float &span,
|
||||
const DrawData *d) = 0;
|
||||
@@ -88,24 +91,24 @@ public:
|
||||
virtual void FillBezier( BPoint *pts,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillEllipse( const BRect &r,
|
||||
virtual void FillEllipse( BRect r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillPolygon( BPoint *ptlist,
|
||||
int32 numpts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillRect( const BRect &r,
|
||||
virtual void FillRect( BRect r,
|
||||
const RGBColor &color) = 0;
|
||||
|
||||
virtual void FillRect( const BRect &r,
|
||||
virtual void FillRect( BRect r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillRegion( BRegion &r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillRoundRect( const BRect &r,
|
||||
virtual void FillRoundRect( BRect r,
|
||||
const float &xrad,
|
||||
const float &yrad,
|
||||
const DrawData *d) = 0;
|
||||
@@ -118,10 +121,10 @@ public:
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void FillTriangle( BPoint *pts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void StrokeArc( const BRect &r,
|
||||
virtual void StrokeArc( BRect r,
|
||||
const float &angle,
|
||||
const float &span,
|
||||
const DrawData *d) = 0;
|
||||
@@ -129,7 +132,7 @@ public:
|
||||
virtual void StrokeBezier( BPoint *pts,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void StrokeEllipse( const BRect &r,
|
||||
virtual void StrokeEllipse( BRect r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
// this version used by Decorator
|
||||
@@ -154,21 +157,21 @@ public:
|
||||
|
||||
virtual void StrokePolygon( BPoint *ptlist,
|
||||
int32 numpts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d,
|
||||
bool is_closed=true) = 0;
|
||||
|
||||
// this version used by Decorator
|
||||
virtual void StrokeRect( const BRect &r,
|
||||
virtual void StrokeRect( BRect r,
|
||||
const RGBColor &color) = 0;
|
||||
|
||||
virtual void StrokeRect( const BRect &r,
|
||||
virtual void StrokeRect( BRect r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void StrokeRegion( BRegion &r,
|
||||
const DrawData *d) = 0;
|
||||
|
||||
virtual void StrokeRoundRect(const BRect &r,
|
||||
virtual void StrokeRoundRect(BRect r,
|
||||
const float &xrad,
|
||||
const float &yrad,
|
||||
const DrawData *d) = 0;
|
||||
@@ -187,24 +190,27 @@ public:
|
||||
// Font-related calls
|
||||
|
||||
// DrawData is NOT const because this call updates the pen position in the passed DrawData
|
||||
virtual void DrawString( const char *string,
|
||||
const int32 &length,
|
||||
const BPoint &pt,
|
||||
DrawData *d) = 0;
|
||||
virtual void DrawString( const char* string,
|
||||
int32 length,
|
||||
const BPoint& pt,
|
||||
DrawData* d,
|
||||
escapement_delta *delta = NULL) = 0;
|
||||
|
||||
virtual void DrawString( const char *string,
|
||||
/* virtual void DrawString( const char *string,
|
||||
const int32 &length,
|
||||
const BPoint &pt,
|
||||
const RGBColor &color,
|
||||
escapement_delta *delta=NULL) = 0;
|
||||
escapement_delta *delta = NULL) = 0;*/
|
||||
|
||||
virtual float StringWidth( const char *string,
|
||||
virtual float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const DrawData *d) = 0;
|
||||
const DrawData* d,
|
||||
escapement_delta *delta = NULL) = 0;
|
||||
|
||||
virtual float StringWidth( const char *string,
|
||||
virtual float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const ServerFont &font) = 0;
|
||||
const ServerFont& font,
|
||||
escapement_delta *delta = NULL) = 0;
|
||||
|
||||
virtual float StringHeight( const char *string,
|
||||
int32 length,
|
||||
|
||||
@@ -49,11 +49,11 @@ class DrawData {
|
||||
public:
|
||||
DrawData();
|
||||
DrawData(const DrawData& from);
|
||||
// used for the State stack, no
|
||||
// true 1:1 copy!
|
||||
DrawData(const DrawData* from);
|
||||
virtual ~DrawData();
|
||||
|
||||
// NOTE: this operator will not make a 1:1 copy, it is used
|
||||
// for the state stack and therefor origin and scale are reset
|
||||
// to B_ORIGIN and 1.0.
|
||||
DrawData& operator=(const DrawData& from);
|
||||
|
||||
// coordinate transformation
|
||||
@@ -112,15 +112,10 @@ class DrawData {
|
||||
inline const ServerFont& Font() const
|
||||
{ return fFont; }
|
||||
|
||||
// TODO: remove (is contained in SeverFont::Flags())
|
||||
void SetFontAntiAliasing(bool antiAliasing);
|
||||
inline bool FontAntiAliasing() const
|
||||
{ return fFontAntiAliasing; }
|
||||
|
||||
// TODO: remove (should be part of DisplayDriver::DrawString() as in BView)
|
||||
void SetEscapementDelta(escapement_delta delta);
|
||||
inline escapement_delta EscapementDelta() const
|
||||
{ return fEscapementDelta; }
|
||||
// overrides aliasing flag contained in SeverFont::Flags())
|
||||
void SetForceFontAliasing(bool aliasing);
|
||||
inline bool ForceFontAliasing() const
|
||||
{ return fFontAliasing; }
|
||||
|
||||
// postscript style settings
|
||||
void SetLineCapMode(cap_mode mode);
|
||||
@@ -139,6 +134,9 @@ class DrawData {
|
||||
inline BPoint Transform(const BPoint& point) const;
|
||||
inline BRect Transform(const BRect& rect) const;
|
||||
|
||||
void SetSubPixelPrecise(bool precise);
|
||||
inline bool SubPixelPrecise() const
|
||||
{ return fSubPixelPrecise; }
|
||||
|
||||
protected:
|
||||
BPoint fOrigin;
|
||||
@@ -158,10 +156,19 @@ class DrawData {
|
||||
float fPenSize;
|
||||
|
||||
ServerFont fFont;
|
||||
// TODO: Remove, see above
|
||||
bool fFontAntiAliasing;
|
||||
escapement_delta fEscapementDelta;
|
||||
//
|
||||
// overrides font aliasing flag
|
||||
bool fFontAliasing;
|
||||
|
||||
// This is not part of the normal state stack.
|
||||
// Layer will update it in PushState/PopState.
|
||||
// A BView can have a flag "B_SUBPIXEL_PRECISE",
|
||||
// I never knew what it does on R5, but I can use
|
||||
// it in Painter to actually draw stuff with
|
||||
// sub-pixel coordinates. It means
|
||||
// StrokeLine(BPoint(10, 5), BPoint(20, 9));
|
||||
// will look different from
|
||||
// StrokeLine(BPoint(10.3, 5.8), BPoint(20.6, 9.5));
|
||||
bool fSubPixelPrecise;
|
||||
|
||||
cap_mode fLineCapMode;
|
||||
join_mode fLineJoinMode;
|
||||
@@ -174,7 +181,10 @@ class DrawData {
|
||||
class LayerData : public DrawData {
|
||||
public:
|
||||
LayerData();
|
||||
LayerData(const LayerData &data);
|
||||
LayerData(const LayerData& data);
|
||||
// this version used for the state
|
||||
// stack, sets prevState to data too
|
||||
LayerData(LayerData* data);
|
||||
virtual ~LayerData();
|
||||
|
||||
LayerData& operator=(const LayerData &from);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define RENDERING_BUFFER_H
|
||||
|
||||
#include <GraphicsDefs.h>
|
||||
#include <Rect.h>
|
||||
|
||||
class RenderingBuffer {
|
||||
public:
|
||||
@@ -22,6 +23,11 @@ class RenderingBuffer {
|
||||
|
||||
inline uint32 BitsLength() const
|
||||
{ return Height() * BytesPerRow(); }
|
||||
|
||||
inline BRect Bounds() const
|
||||
{ return BRect(0.0, 0.0,
|
||||
Width() - 1,
|
||||
Height() - 1); }
|
||||
};
|
||||
|
||||
#endif // RENDERING_BUFFER_H
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
# define DEFAULT_BOLD_FONT_FAMILY "Bitstream Vera Sans"
|
||||
# define FALLBACK_BOLD_FONT_FAMILY "Swis721 BT"
|
||||
# define DEFAULT_BOLD_FONT_STYLE "Bold"
|
||||
# define DEFAULT_BOLD_FONT_SIZE 11
|
||||
# define DEFAULT_BOLD_FONT_SIZE 12
|
||||
# define DEFAULT_FIXED_FONT_FAMILY "Bitstream Vera Sans Mono"
|
||||
# define FALLBACK_FIXED_FONT_FAMILY "Courier10 BT"
|
||||
# define DEFAULT_FIXED_FONT_STYLE "Roman"
|
||||
|
||||
@@ -332,7 +332,7 @@ MemPool::ReallocateBuffer(void *buf, ssize_t size)
|
||||
void
|
||||
MemPool::ReleaseBuffer(void *buf)
|
||||
{
|
||||
struct bfhead *b, *bn;
|
||||
struct bfhead *b, *bn;
|
||||
|
||||
b = BFH(((char *) buf) - sizeof(struct bhead));
|
||||
|
||||
|
||||
@@ -341,7 +341,7 @@ DefaultDecorator::_DoLayout()
|
||||
fTabOffset = 0;
|
||||
// distance from one item of the tab bar to another.
|
||||
// In this case the text and close/zoom rects
|
||||
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 12 : 20;
|
||||
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 10 : 18;
|
||||
|
||||
font_height fh;
|
||||
_drawdata.Font().Height(&fh);
|
||||
|
||||
@@ -49,9 +49,32 @@
|
||||
|
||||
|
||||
Desktop::Desktop()
|
||||
: fWinBorderList(64),
|
||||
fWinLock("desktop window list lock"),
|
||||
fRootLayerList(2),
|
||||
fActiveRootLayer(NULL),
|
||||
fScreenList(2),
|
||||
fActiveScreen(NULL),
|
||||
fMouseMode(B_NORMAL_MOUSE),
|
||||
fFFMouseMode(false)
|
||||
{
|
||||
fActiveRootLayer = NULL;
|
||||
fActiveScreen = NULL;
|
||||
// init scrollbar info
|
||||
fScrollBarInfo.proportional = true;
|
||||
fScrollBarInfo.double_arrows = false;
|
||||
// look of the knob (R5: (0, 1, 2), 1 = default)
|
||||
fScrollBarInfo.knob = 1;
|
||||
fScrollBarInfo.min_knob_size = 15;
|
||||
|
||||
// init menu info
|
||||
fMenuInfo.font_size = 12.0;
|
||||
// TODO: ...
|
||||
// fMenuInfo.f_family;
|
||||
// fMenuInfo.f_style;
|
||||
// fMenuInfo.background_color = gColorSet->menu_background;
|
||||
// look of the separator (R5: (0, 1, 2), default ?)
|
||||
fMenuInfo.separator = 0;
|
||||
fMenuInfo.click_to_open = true;
|
||||
fMenuInfo.triggers_always_shown = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +133,11 @@ Desktop::_AddGraphicsCard(HWInterface* interface)
|
||||
if (screen->Initialize() >= B_OK && fScreenList.AddItem((void*)screen)) {
|
||||
|
||||
// TODO: be careful of screen initialization - monitor may not support 640x480
|
||||
#if __HAIKU__
|
||||
screen->SetMode(1400, 1050, B_RGB32, 60.f);
|
||||
#else
|
||||
screen->SetMode(800, 600, B_RGB32, 60.f);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
delete screen;
|
||||
|
||||
@@ -33,7 +33,6 @@ if ( $(TARGET_PLATFORM) = haiku ) {
|
||||
} else {
|
||||
VIEW_DRIVER_SOURCES =
|
||||
fake_input_server.cpp
|
||||
BBitmapBuffer.cpp
|
||||
BitmapBuffer.cpp
|
||||
AccelerantBuffer.cpp
|
||||
AccelerantHWInterface.cpp
|
||||
@@ -90,8 +89,12 @@ Server app_server :
|
||||
# DisplayDriver Classes
|
||||
$(VIEW_DRIVER_SOURCES)
|
||||
|
||||
BBitmapBuffer.cpp
|
||||
BitmapHWInterface.cpp
|
||||
DefaultDecorator.cpp
|
||||
Layer.cpp
|
||||
OffscreenServerWindow.cpp
|
||||
OffscreenWinBorder.cpp
|
||||
RootLayer.cpp
|
||||
ServerPicture.cpp
|
||||
ServerScreen.cpp
|
||||
|
||||
+40
-12
@@ -61,12 +61,6 @@
|
||||
# define RBTRACE(x) ;
|
||||
#endif
|
||||
|
||||
enum {
|
||||
B_LAYER_ACTION_NONE = 0,
|
||||
B_LAYER_ACTION_MOVE,
|
||||
B_LAYER_ACTION_RESIZE
|
||||
};
|
||||
|
||||
Layer::Layer(BRect frame, const char* name, int32 token,
|
||||
uint32 resize, uint32 flags, DisplayDriver* driver)
|
||||
:
|
||||
@@ -129,6 +123,19 @@ CRITICAL(helper);
|
||||
if (!fDriver)
|
||||
CRITICAL("You MUST have a valid driver to init a Layer object\n");
|
||||
|
||||
// NOTE: This flag is forwarded to a LayerData setting, even
|
||||
// though it is actually not part of a "state". However,
|
||||
// it is an important detail of a graphics context, and we
|
||||
// have no other means to pass this setting on to the DisplayDriver
|
||||
// other than through the LayerData. If we ever add a flag
|
||||
// B_ANTI_ALIASING to the view flags, it would have to be passed
|
||||
// in the same way. Though when breaking binary compatibility,
|
||||
// we might want to make this an actual part of a "state" (with
|
||||
// a different API to set these).
|
||||
// Note that the flag is also tested (updated) in Push/PopState and
|
||||
// SetFlags().
|
||||
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||
|
||||
STRACE(("Layer(%s) successfuly created\n", Name()));
|
||||
}
|
||||
|
||||
@@ -139,9 +146,6 @@ Layer::~Layer()
|
||||
|
||||
// TODO: uncomment!
|
||||
//PruneTree();
|
||||
|
||||
// fServerWin->RemoveChild(fDriver);
|
||||
// delete fDriver;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -210,7 +214,7 @@ Layer::AddChild(Layer* layer, ServerWindow* serverWin)
|
||||
} else {
|
||||
// go right or up
|
||||
|
||||
if (c == stop) // out trip is over
|
||||
if (c == stop) // our trip is over
|
||||
break;
|
||||
|
||||
if (c->fLowerSibling) {
|
||||
@@ -466,6 +470,21 @@ Layer::BottomChild() const
|
||||
return fCurrent;
|
||||
}
|
||||
|
||||
// SetName
|
||||
void
|
||||
Layer::SetName(const char* name)
|
||||
{
|
||||
fName.SetTo(name);
|
||||
}
|
||||
|
||||
// SetFlags
|
||||
void
|
||||
Layer::SetFlags(uint32 flags)
|
||||
{
|
||||
fFlags = flags;
|
||||
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||
}
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
|
||||
//! Rebuilds the layer's "completely visible" region
|
||||
@@ -987,9 +1006,10 @@ Layer::IsHidden(void) const
|
||||
void
|
||||
Layer::PushState()
|
||||
{
|
||||
LayerData *data = new LayerData(*fLayerData);
|
||||
data->prevState = fLayerData;
|
||||
LayerData *data = new LayerData(fLayerData);
|
||||
fLayerData = data;
|
||||
|
||||
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1005,6 +1025,8 @@ Layer::PopState()
|
||||
fLayerData = fLayerData->prevState;
|
||||
data->prevState = NULL;
|
||||
delete data;
|
||||
|
||||
fLayerData->SetSubPixelPrecise(fFlags & B_SUBPIXEL_PRECISE);
|
||||
}
|
||||
|
||||
|
||||
@@ -1762,6 +1784,12 @@ Layer::do_CopyBits(BRect& src, BRect& dst, int32 xOffset, int32 yOffset) {
|
||||
// are triggering BView::Draw() to be called
|
||||
// and for these parts only.
|
||||
|
||||
// TODO: having moved this into Layer broke
|
||||
// offscreen windows (bitmaps)
|
||||
// -> move back into ServerWindow...
|
||||
if (!GetRootLayer())
|
||||
return;
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
|
||||
// the region that is going to be copied
|
||||
|
||||
+16
-4
@@ -51,6 +51,12 @@ enum {
|
||||
B_LAYER_MASK_RESIZE = 5,
|
||||
};
|
||||
|
||||
enum {
|
||||
B_LAYER_ACTION_NONE = 0,
|
||||
B_LAYER_ACTION_MOVE,
|
||||
B_LAYER_ACTION_RESIZE
|
||||
};
|
||||
|
||||
enum {
|
||||
B_LAYER_CHILDREN_DEPENDANT = 0x1000U,
|
||||
};
|
||||
@@ -91,14 +97,18 @@ class Layer {
|
||||
virtual Layer* LowerSibling() const;
|
||||
virtual Layer* UpperSibling() const;
|
||||
virtual Layer* BottomChild() const;
|
||||
|
||||
const char* Name() const
|
||||
|
||||
virtual void SetName(const char* name);
|
||||
inline const char* Name() const
|
||||
{ return fName.String(); }
|
||||
inline uint32 Flags() const
|
||||
{ return fFlags; }
|
||||
|
||||
inline uint32 ResizeMode() const
|
||||
{ return fResizeMode; }
|
||||
|
||||
virtual void SetFlags(uint32 flags);
|
||||
inline uint32 Flags() const
|
||||
{ return fFlags; }
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
virtual void RebuildFullRegion();
|
||||
void StartRebuildRegions(const BRegion& reg,
|
||||
@@ -276,6 +286,8 @@ class Layer {
|
||||
friend class RootLayer;
|
||||
friend class WinBorder;
|
||||
friend class ServerWindow;
|
||||
// TODO: remove, is here for debugging purposes only
|
||||
friend class OffscreenWinBorder;
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
void move_layer(float x, float y);
|
||||
|
||||
@@ -35,7 +35,8 @@ DrawData::DrawData()
|
||||
fPenLocation(0.0, 0.0),
|
||||
fPenSize(1.0),
|
||||
fFont(),
|
||||
fFontAntiAliasing(true),
|
||||
fFontAliasing(false),
|
||||
fSubPixelPrecise(false),
|
||||
fLineCapMode(B_BUTT_CAP),
|
||||
fLineJoinMode(B_BEVEL_JOIN),
|
||||
fMiterLimit(B_DEFAULT_MITER_LIMIT)
|
||||
@@ -43,9 +44,6 @@ DrawData::DrawData()
|
||||
if (gFontServer && gFontServer->GetSystemPlain())
|
||||
fFont = *(gFontServer->GetSystemPlain());
|
||||
|
||||
fEscapementDelta.space = 0;
|
||||
fEscapementDelta.nonspace = 0;
|
||||
|
||||
fUnscaledFontSize = fFont.Size();
|
||||
}
|
||||
|
||||
@@ -56,6 +54,42 @@ DrawData::DrawData(const DrawData& from)
|
||||
*this = from;
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
DrawData::DrawData(const DrawData* from)
|
||||
: fOrigin(0.0, 0.0),
|
||||
fScale(1.0),
|
||||
fClippingRegion(NULL)
|
||||
{
|
||||
if (from->fClippingRegion) {
|
||||
SetClippingRegion(*(from->fClippingRegion));
|
||||
}
|
||||
|
||||
fHighColor = from->fHighColor;
|
||||
fLowColor = from->fLowColor;
|
||||
fPattern = from->fPattern;
|
||||
|
||||
fDrawingMode = from->fDrawingMode;
|
||||
fAlphaSrcMode = from->fAlphaSrcMode;
|
||||
fAlphaFncMode = from->fAlphaFncMode;
|
||||
|
||||
fPenLocation = from->fPenLocation;
|
||||
fPenSize = from->fPenSize;
|
||||
|
||||
fFont = from->fFont;
|
||||
fFontAliasing = from->fFontAliasing;
|
||||
|
||||
fSubPixelPrecise = from->fSubPixelPrecise;
|
||||
|
||||
fLineCapMode = from->fLineCapMode;
|
||||
fLineJoinMode = from->fLineJoinMode;
|
||||
fMiterLimit = from->fMiterLimit;
|
||||
|
||||
// Since fScale is reset to 1.0, the unscaled
|
||||
// font size is the current size of the font
|
||||
// (which is from->fUnscaledFontSize * from->fScale)
|
||||
fUnscaledFontSize = fFont.Size();
|
||||
}
|
||||
|
||||
// destructor
|
||||
DrawData::~DrawData()
|
||||
{
|
||||
@@ -66,16 +100,8 @@ DrawData::~DrawData()
|
||||
DrawData&
|
||||
DrawData::operator=(const DrawData& from)
|
||||
{
|
||||
// NOTE: This function is intended for use by the Layer
|
||||
// state stack only.
|
||||
// So it does not make a true copy of the DrawData, but resets
|
||||
// fOrigin and fScale and uses the current the font size as
|
||||
// fUnscaledFontSize.
|
||||
|
||||
// fOrigin = from.fOrigin;
|
||||
// fScale = from.fScale;
|
||||
fOrigin = BPoint(0.0, 0.0);
|
||||
fScale = 1.0;
|
||||
fOrigin = from.fOrigin;
|
||||
fScale = from.fScale;
|
||||
|
||||
if (from.fClippingRegion) {
|
||||
SetClippingRegion(*(from.fClippingRegion));
|
||||
@@ -96,18 +122,15 @@ DrawData::operator=(const DrawData& from)
|
||||
fPenSize = from.fPenSize;
|
||||
|
||||
fFont = from.fFont;
|
||||
fFontAntiAliasing = from.fFontAntiAliasing;
|
||||
fEscapementDelta = from.fEscapementDelta;
|
||||
fFontAliasing = from.fFontAliasing;
|
||||
|
||||
fSubPixelPrecise = from.fSubPixelPrecise;
|
||||
|
||||
fLineCapMode = from.fLineCapMode;
|
||||
fLineJoinMode = from.fLineJoinMode;
|
||||
fMiterLimit = from.fMiterLimit;
|
||||
|
||||
// fUnscaledFontSize = from.fUnscaledFontSize;
|
||||
// Since fScale is reset to 1.0, the unscaled
|
||||
// font size is the current size of the font
|
||||
// (which is from.fFont.Size() * from.fScale)
|
||||
fUnscaledFontSize = fFont.Size();
|
||||
fUnscaledFontSize = from.fUnscaledFontSize;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -269,18 +292,18 @@ DrawData::SetFont(const ServerFont& font, uint32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
// SetFontAntiAliasing
|
||||
// SetForceFontAliasing
|
||||
void
|
||||
DrawData::SetFontAntiAliasing(bool antiAliasing)
|
||||
DrawData::SetForceFontAliasing(bool aliasing)
|
||||
{
|
||||
fFontAntiAliasing = antiAliasing;
|
||||
fFontAliasing = aliasing;
|
||||
}
|
||||
|
||||
// SetEscapementDelta
|
||||
// SetSubPixelPrecise
|
||||
void
|
||||
DrawData::SetEscapementDelta(escapement_delta delta)
|
||||
DrawData::SetSubPixelPrecise(bool precise)
|
||||
{
|
||||
fEscapementDelta = delta;
|
||||
fSubPixelPrecise = precise;
|
||||
}
|
||||
|
||||
// SetLineCapMode
|
||||
@@ -315,12 +338,20 @@ LayerData::LayerData()
|
||||
}
|
||||
|
||||
// LayerData
|
||||
LayerData::LayerData(const LayerData &data)
|
||||
LayerData::LayerData(const LayerData& data)
|
||||
: DrawData()
|
||||
{
|
||||
fClippingRegion = NULL;
|
||||
*this = data;
|
||||
}
|
||||
|
||||
// LayerData
|
||||
LayerData::LayerData(LayerData* data)
|
||||
: DrawData(data),
|
||||
prevState(data)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
LayerData::~LayerData()
|
||||
{
|
||||
@@ -333,7 +364,7 @@ LayerData::operator=(const LayerData& from)
|
||||
{
|
||||
DrawData::operator=(from);
|
||||
|
||||
prevState = from.prevState;
|
||||
prevState = from.prevState;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -450,10 +481,7 @@ LayerData::ReadFromLink(BPrivate::LinkReceiver& link)
|
||||
link.Read<int8>((int8*)&fAlphaSrcMode);
|
||||
link.Read<int8>((int8*)&fAlphaFncMode);
|
||||
link.Read<float>(&fScale);
|
||||
link.Read<bool>(&fFontAntiAliasing);
|
||||
|
||||
// TODO: ahm... which way arround?
|
||||
fFontAntiAliasing = !fFontAntiAliasing;
|
||||
link.Read<bool>(&fFontAliasing);
|
||||
|
||||
fHighColor = highColor;
|
||||
fLowColor = lowColor;
|
||||
@@ -505,7 +533,7 @@ LayerData::WriteToLink(BPrivate::LinkSender& link) const
|
||||
link.Attach<uint8>((uint8)fAlphaSrcMode);
|
||||
link.Attach<uint8>((uint8)fAlphaFncMode);
|
||||
link.Attach<float>(fScale);
|
||||
link.Attach<bool>(!fFontAntiAliasing);
|
||||
link.Attach<bool>(fFontAliasing);
|
||||
|
||||
int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0;
|
||||
link.Attach<int32>(clippingRectCount);
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#include "OffscreenWinBorder.h"
|
||||
#include "ServerBitmap.h"
|
||||
|
||||
#include "OffscreenServerWindow.h"
|
||||
|
||||
// constructor
|
||||
OffscreenServerWindow::OffscreenServerWindow(const char *title,
|
||||
ServerApp *app,
|
||||
port_id clientPort,
|
||||
port_id looperPort,
|
||||
int32 handlerID,
|
||||
ServerBitmap* bitmap)
|
||||
: ServerWindow(title, app, clientPort, looperPort, handlerID),
|
||||
fBitmap(bitmap)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
OffscreenServerWindow::~OffscreenServerWindow()
|
||||
{
|
||||
}
|
||||
|
||||
// SendMessageToClient
|
||||
void
|
||||
OffscreenServerWindow::SendMessageToClient(const BMessage* msg, int32 target,
|
||||
bool usePreferred) const
|
||||
{
|
||||
// We're a special kind of window. The client BWindow thread is not running,
|
||||
// so we cannot post messages to the client. In order to not mess arround
|
||||
// with all the other code, we simply make this function virtual and
|
||||
// don't do anything in this implementation.
|
||||
}
|
||||
|
||||
// MakeWinBorder
|
||||
WinBorder*
|
||||
OffscreenServerWindow::MakeWinBorder(BRect frame, const char* name,
|
||||
uint32 look, uint32 feel, uint32 flags,
|
||||
uint32 workspace)
|
||||
{
|
||||
return new OffscreenWinBorder(fBitmap, name, this);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
#ifndef OFFSCREEN_SERVER_WINDOW_H
|
||||
#define OFFSCREEN_SERVER_WINDOW_H
|
||||
|
||||
|
||||
#include "ServerWindow.h"
|
||||
|
||||
class OffscreenServerWindow : public ServerWindow {
|
||||
public:
|
||||
OffscreenServerWindow(const char *title,
|
||||
ServerApp *app,
|
||||
port_id clientPort,
|
||||
port_id looperPort,
|
||||
int32 handlerID,
|
||||
ServerBitmap* bitmap);
|
||||
virtual ~OffscreenServerWindow();
|
||||
|
||||
// util methods.
|
||||
virtual void SendMessageToClient(const BMessage* msg,
|
||||
int32 target = B_NULL_TOKEN,
|
||||
bool usePreferred = false) const;
|
||||
|
||||
virtual WinBorder* MakeWinBorder(BRect frame,
|
||||
const char* name,
|
||||
uint32 look, uint32 feel,
|
||||
uint32 flags, uint32 workspace);
|
||||
private:
|
||||
ServerBitmap* fBitmap;
|
||||
};
|
||||
|
||||
#endif // OFFSCREEN_SERVER_WINDOW_H
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Debug.h>
|
||||
#include "DebugInfoManager.h"
|
||||
|
||||
#include "BitmapHWInterface.h"
|
||||
#include "DisplayDriverPainter.h"
|
||||
#include "ServerBitmap.h"
|
||||
|
||||
#include "OffscreenWinBorder.h"
|
||||
|
||||
|
||||
// constructor
|
||||
OffscreenWinBorder::OffscreenWinBorder(ServerBitmap* bitmap,
|
||||
const char* name,
|
||||
ServerWindow* window)
|
||||
: WinBorder(bitmap->Bounds(), name,
|
||||
B_NO_BORDER_WINDOW_LOOK,
|
||||
B_NORMAL_WINDOW_FEEL,
|
||||
0, 0, window,
|
||||
new DisplayDriverPainter()),
|
||||
fBitmap(bitmap),
|
||||
fHWInterface(new BitmapHWInterface(fBitmap))
|
||||
{
|
||||
fDriver->SetHWInterface(fHWInterface);
|
||||
fDriver->Initialize();
|
||||
fDriver->Update();
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
fFull.Set(fFrame);
|
||||
#endif
|
||||
}
|
||||
|
||||
// destructor
|
||||
OffscreenWinBorder::~OffscreenWinBorder()
|
||||
{
|
||||
fHWInterface->WriteLock();
|
||||
// Unlike normal Layers, we own the DisplayDriver instance
|
||||
fDriver->Shutdown();
|
||||
delete fDriver;
|
||||
fHWInterface->Shutdown();
|
||||
fHWInterface->WriteUnlock();
|
||||
delete fHWInterface;
|
||||
}
|
||||
|
||||
void
|
||||
OffscreenWinBorder::Draw(const BRect &r)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
void
|
||||
OffscreenWinBorder::MoveBy(float x, float y)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
void
|
||||
OffscreenWinBorder::ResizeBy(float x, float y)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
// SetTopLayer
|
||||
void
|
||||
OffscreenWinBorder::SetTopLayer(Layer* layer)
|
||||
{
|
||||
WinBorder::SetTopLayer(layer);
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
fTopLayer->fFull.Set(fFrame.OffsetToCopy(0.0, 0.0));
|
||||
fTopLayer->fHidden = false;
|
||||
fTopLayer->fVisible = fTopLayer->fFull;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Author: Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#ifndef OFFSCREEN_WINBORDER_H
|
||||
#define OFFSCREEN_WINBORDER_H
|
||||
|
||||
#include "WinBorder.h"
|
||||
|
||||
class BitmapHWInterface;
|
||||
class ServerBitmap;
|
||||
|
||||
class OffscreenWinBorder : public WinBorder {
|
||||
public:
|
||||
OffscreenWinBorder(ServerBitmap* bitmap,
|
||||
const char* name,
|
||||
ServerWindow* window);
|
||||
virtual ~OffscreenWinBorder();
|
||||
|
||||
virtual void Draw(const BRect &r);
|
||||
|
||||
virtual void MoveBy(float x, float y);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
|
||||
virtual bool IsOffscreenWindow() const
|
||||
{ return true; }
|
||||
|
||||
virtual void SetTopLayer(Layer* layer);
|
||||
|
||||
private:
|
||||
ServerBitmap* fBitmap;
|
||||
BitmapHWInterface* fHWInterface;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -238,9 +238,8 @@ status_t PicturePlayer::Play(int32 tableEntries,void *userData, LayerData *d)
|
||||
escapement_delta delta;
|
||||
delta.nonspace = deltax;
|
||||
delta.space = deltay;
|
||||
fldata.SetEscapementDelta(delta);
|
||||
|
||||
fdriver->DrawString(string, len, fldata.PenLocation(), &fldata);
|
||||
fdriver->DrawString(string, len, fldata.PenLocation(), &fldata, &delta);
|
||||
delete string;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
#include "FontServer.h"
|
||||
#include "HWInterface.h"
|
||||
#include "LayerData.h"
|
||||
#include "OffscreenServerWindow.h"
|
||||
#include "RAMLinkMsgReader.h"
|
||||
//#include "RGBColor.h"
|
||||
#include "RootLayer.h"
|
||||
#include "ServerBitmap.h"
|
||||
#include "ServerConfig.h"
|
||||
@@ -165,7 +165,11 @@ ServerApp::~ServerApp(void)
|
||||
|
||||
if (tries < 0) {
|
||||
// This really shouldn't happen, as it shows we're buggy
|
||||
#if __HAIKU__
|
||||
syslog(LOG_ERR, "ServerApp %s needs to kill some server windows...\n", Signature());
|
||||
#else
|
||||
fprintf(stderr, "ServerApp %s needs to kill some server windows...\n", Signature());
|
||||
#endif
|
||||
|
||||
// there still seem to be some windows left - kill them!
|
||||
fWindowListLock.Lock();
|
||||
@@ -187,7 +191,7 @@ ServerApp::~ServerApp(void)
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < fPictureList.CountItems(); i++) {
|
||||
delete static_cast<ServerPicture *>(fPictureList.ItemAt(i));
|
||||
delete (ServerPicture*)fPictureList.ItemAt(i);
|
||||
}
|
||||
|
||||
// although this isn't pretty, ATM we have only one RootLayer.
|
||||
@@ -409,7 +413,10 @@ ServerApp::_MessageLooper()
|
||||
|
||||
case AS_CREATE_WINDOW:
|
||||
{
|
||||
// Create the ServerWindow to node monitor a new OBWindow
|
||||
// Create a ServerWindow
|
||||
// NOTE/TODO: Code duplication in part to below case.
|
||||
// Watch out, if you make changes here, you might have to do them below.
|
||||
// Go ahead and fix if you have an idea for unification...
|
||||
|
||||
// Attached data:
|
||||
// 2) BRect window frame
|
||||
@@ -450,12 +457,13 @@ ServerApp::_MessageLooper()
|
||||
|
||||
// ServerWindow constructor will reply with port_id of a newly created port
|
||||
ServerWindow *window = new ServerWindow(title, this, clientReplyPort,
|
||||
looperPort, token, frame, look, feel, flags, workspaces);
|
||||
looperPort, token);
|
||||
|
||||
STRACE(("\nServerApp %s: New Window %s (%.1f,%.1f,%.1f,%.1f)\n",
|
||||
fSignature(), title, frame.left, frame.top, frame.right, frame.bottom));
|
||||
|
||||
if (window->InitCheck() == B_OK && window->Run()) {
|
||||
|
||||
// NOTE: the reply to the client is handled in window->Run()
|
||||
if (window->Init(frame, look, feel, flags, workspaces) >= B_OK && window->Run()) {
|
||||
// add the window to the list
|
||||
if (fWindowListLock.Lock()) {
|
||||
fWindowList.AddItem(window);
|
||||
@@ -473,6 +481,80 @@ ServerApp::_MessageLooper()
|
||||
// We don't have to free the title, as it's owned by the ServerWindow now
|
||||
break;
|
||||
}
|
||||
case AS_CREATE_OFFSCREEN_WINDOW:
|
||||
{
|
||||
// Create an OffscreenServerWindow
|
||||
// NOTE/TODO: Code duplication in part to above case.
|
||||
|
||||
// Attached data:
|
||||
// 2) BRect window frame
|
||||
// 3) uint32 window look
|
||||
// 4) uint32 window feel
|
||||
// 5) uint32 window flags
|
||||
// 6) uint32 workspace index
|
||||
// 7) int32 BHandler token of the window
|
||||
// 8) port_id window's message port
|
||||
// 9) const char * title
|
||||
|
||||
BRect frame;
|
||||
int32 bitmapToken;
|
||||
uint32 look;
|
||||
uint32 feel;
|
||||
uint32 flags;
|
||||
uint32 workspaces;
|
||||
int32 token = B_NULL_TOKEN;
|
||||
port_id clientReplyPort = -1;
|
||||
port_id looperPort = -1;
|
||||
char *title = NULL;
|
||||
|
||||
receiver.Read<int32>(&bitmapToken);
|
||||
receiver.Read<BRect>(&frame);
|
||||
receiver.Read<uint32>(&look);
|
||||
receiver.Read<uint32>(&feel);
|
||||
receiver.Read<uint32>(&flags);
|
||||
receiver.Read<uint32>(&workspaces);
|
||||
receiver.Read<int32>(&token);
|
||||
receiver.Read<port_id>(&clientReplyPort);
|
||||
receiver.Read<port_id>(&looperPort);
|
||||
if (receiver.ReadString(&title) != B_OK)
|
||||
break;
|
||||
|
||||
if (!frame.IsValid()) {
|
||||
// make sure we pass a valid rectangle to ServerWindow
|
||||
frame.right = frame.left + 1;
|
||||
frame.bottom = frame.top + 1;
|
||||
}
|
||||
ServerBitmap* bitmap = FindBitmap(bitmapToken);
|
||||
|
||||
bool success = false;
|
||||
|
||||
if (bitmap) {
|
||||
// ServerWindow constructor will reply with port_id of a newly created port
|
||||
OffscreenServerWindow *window = new OffscreenServerWindow(title, this, clientReplyPort,
|
||||
looperPort, token, bitmap);
|
||||
|
||||
// NOTE: the reply to the client is handled in window->Run()
|
||||
success = window->Init(frame, look, feel, flags, workspaces) >= B_OK && window->Run();
|
||||
|
||||
// add the window to the list
|
||||
if (success && fWindowListLock.Lock()) {
|
||||
success = fWindowList.AddItem(window);
|
||||
fWindowListLock.Unlock();
|
||||
}
|
||||
|
||||
if (!success)
|
||||
delete window;
|
||||
}
|
||||
if (!success) {
|
||||
// window creation failed, we need to notify the client
|
||||
BPrivate::LinkSender reply(clientReplyPort);
|
||||
reply.StartMessage(SERVER_FALSE);
|
||||
reply.Flush();
|
||||
}
|
||||
|
||||
// We don't have to free the title, as it's owned by the ServerWindow now
|
||||
break;
|
||||
}
|
||||
|
||||
case AS_QUIT_APP:
|
||||
{
|
||||
@@ -772,14 +854,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<int32>(&bytesPerRow);
|
||||
if (link.Read<screen_id>(&screenID) == B_OK) {
|
||||
bitmap = gBitmapManager->CreateBitmap(frame, colorSpace, flags,
|
||||
bytesPerRow, screenID);
|
||||
bytesPerRow, screenID);
|
||||
}
|
||||
|
||||
STRACE(("ServerApp %s: Create Bitmap (%.1fx%.1f)\n",
|
||||
Signature(), frame.Width(), frame.Height()));
|
||||
|
||||
if (bitmap) {
|
||||
fBitmapList.AddItem(bitmap);
|
||||
if (bitmap && fBitmapList.AddItem((void*)bitmap)) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(bitmap->Token());
|
||||
fLink.Attach<int32>(bitmap->Area());
|
||||
@@ -807,10 +888,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<int32>(&id);
|
||||
|
||||
ServerBitmap *bitmap = FindBitmap(id);
|
||||
if (bitmap) {
|
||||
if (bitmap && fBitmapList.RemoveItem((void*)bitmap)) {
|
||||
STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), id));
|
||||
|
||||
fBitmapList.RemoveItem(bitmap);
|
||||
gBitmapManager->DeleteBitmap(bitmap);
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
} else
|
||||
@@ -2141,11 +2221,12 @@ ServerApp::CountBitmaps() const
|
||||
\param token ID token of the bitmap to find
|
||||
\return The bitmap having that ID or NULL if not found
|
||||
*/
|
||||
ServerBitmap *
|
||||
ServerBitmap*
|
||||
ServerApp::FindBitmap(int32 token) const
|
||||
{
|
||||
for (int32 i = 0; i < fBitmapList.CountItems(); i++) {
|
||||
ServerBitmap *bitmap = static_cast<ServerBitmap *>(fBitmapList.ItemAt(i));
|
||||
int32 count = fBitmapList.CountItems();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
ServerBitmap* bitmap = (ServerBitmap*)fBitmapList.ItemAt(i);
|
||||
if (bitmap && bitmap->Token() == token)
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
+207
-108
@@ -10,6 +10,7 @@
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AppDefs.h>
|
||||
#include <GraphicsDefs.h>
|
||||
@@ -71,8 +72,7 @@ static const uint32 kMsgWindowQuit = 'winQ';
|
||||
monitor thread.
|
||||
*/
|
||||
ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
||||
port_id clientPort, port_id looperPort, int32 handlerID,
|
||||
BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
|
||||
port_id clientPort, port_id looperPort, int32 handlerID)
|
||||
: BLocker(title && *title ? title : "Unnamed Window"),
|
||||
fTitle(title),
|
||||
fServerApp(app),
|
||||
@@ -87,27 +87,6 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
||||
fCurrentLayer(NULL)
|
||||
{
|
||||
STRACE(("ServerWindow(%s)::ServerWindow()\n", title));
|
||||
|
||||
if (fTitle == NULL)
|
||||
fTitle = strdup("Unnamed Window");
|
||||
if (fTitle == NULL)
|
||||
return;
|
||||
|
||||
// fMessagePort is the port to which the app sends messages for the server
|
||||
fMessagePort = create_port(100, fTitle);
|
||||
if (fMessagePort < B_OK)
|
||||
return;
|
||||
|
||||
fLink.SetSenderPort(fClientReplyPort);
|
||||
fLink.SetReceiverPort(fMessagePort);
|
||||
|
||||
char name[60];
|
||||
snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
|
||||
|
||||
fWinBorder = new WinBorder(frame, name, look, feel, flags,
|
||||
workspace, this, gDesktop->GetDisplayDriver());
|
||||
|
||||
STRACE(("ServerWindow %s Created\n", fTitle));
|
||||
}
|
||||
|
||||
|
||||
@@ -116,7 +95,11 @@ ServerWindow::~ServerWindow()
|
||||
{
|
||||
STRACE(("*ServerWindow (%s):~ServerWindow()\n", fTitle));
|
||||
|
||||
if (!fWinBorder->IsOffscreenWindow())
|
||||
gDesktop->RemoveWinBorder(fWinBorder);
|
||||
|
||||
delete fWinBorder;
|
||||
|
||||
free(const_cast<char *>(fTitle));
|
||||
|
||||
STRACE(("#ServerWindow(%s) will exit NOW\n", fTitle));
|
||||
@@ -124,14 +107,32 @@ ServerWindow::~ServerWindow()
|
||||
|
||||
|
||||
status_t
|
||||
ServerWindow::InitCheck()
|
||||
ServerWindow::Init(BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 workspace)
|
||||
{
|
||||
if (fTitle == NULL || fWinBorder == NULL)
|
||||
if (fTitle == NULL)
|
||||
fTitle = strdup("Unnamed Window");
|
||||
if (fTitle == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// fMessagePort is the port to which the app sends messages for the server
|
||||
fMessagePort = create_port(100, fTitle);
|
||||
if (fMessagePort < B_OK)
|
||||
return fMessagePort;
|
||||
|
||||
fLink.SetSenderPort(fClientReplyPort);
|
||||
fLink.SetReceiverPort(fMessagePort);
|
||||
|
||||
// char name[60];
|
||||
// snprintf(name, sizeof(name), "%ld: %s", fClientTeam, fTitle);
|
||||
|
||||
// We cannot call MakeWinBorder in the constructor, since it
|
||||
fWinBorder = MakeWinBorder(frame, fTitle, look, feel, flags, workspace);
|
||||
if (!fWinBorder)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
if (!fWinBorder->IsOffscreenWindow())
|
||||
gDesktop->AddWinBorder(fWinBorder);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -379,7 +380,7 @@ ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
|
||||
&& (fWinBorder->WindowFlags() & 0x00008000) != 0) {
|
||||
// this is a workspaces window!
|
||||
newLayer = new WorkspacesLayer(frame, name, token, resizeMask,
|
||||
flags, gDesktop->GetDisplayDriver());
|
||||
flags, fWinBorder->GetDisplayDriver());
|
||||
} else {
|
||||
newLayer = new Layer(frame, name, token, resizeMask,
|
||||
flags, gDesktop->GetDisplayDriver());
|
||||
@@ -394,6 +395,16 @@ ServerWindow::CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent)
|
||||
newLayer->fEventOptions = eventOptions;
|
||||
newLayer->fOwner = fWinBorder;
|
||||
|
||||
// TODO: rework the clipping stuff to remove RootLayer dependency and then
|
||||
// remove this hack:
|
||||
if (fWinBorder->IsOffscreenWindow()) {
|
||||
#ifndef NEW_CLIPPING
|
||||
newLayer->fVisible.Set(newLayer->fFrame);
|
||||
#else
|
||||
newLayer->fVisible2.Set(newLayer->fFrame);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_parent) {
|
||||
Layer *parent = fWinBorder->FindLayer(parentToken);
|
||||
if (parent == NULL)
|
||||
@@ -415,7 +426,9 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
}
|
||||
|
||||
RootLayer *myRootLayer = fWinBorder->GetRootLayer();
|
||||
myRootLayer->Lock();
|
||||
// NOTE: is NULL when fWinBorder is offscreen!
|
||||
if (myRootLayer)
|
||||
myRootLayer->Lock();
|
||||
|
||||
switch (code) {
|
||||
//--------- BView Messages -----------------
|
||||
@@ -481,9 +494,7 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
|
||||
link.Read<int32>(&token);
|
||||
|
||||
myRootLayer->Lock();
|
||||
Layer *current = fWinBorder->FindLayer(token);
|
||||
myRootLayer->Unlock();
|
||||
if (current) {
|
||||
DTRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: %s, token %ld\n", fTitle, current->Name(), token));
|
||||
} else {
|
||||
@@ -507,14 +518,8 @@ myRootLayer->Unlock();
|
||||
if (fCurrentLayer != NULL)
|
||||
break;
|
||||
|
||||
myRootLayer->Lock();
|
||||
fWinBorder->fTopLayer = CreateLayerTree(link, NULL);
|
||||
fWinBorder->fTopLayer->SetAsTopLayer(true);
|
||||
fCurrentLayer = fWinBorder->fTopLayer;
|
||||
|
||||
// connect decorator and top layer.
|
||||
fWinBorder->AddChild(fWinBorder->fTopLayer, NULL);
|
||||
myRootLayer->Unlock();
|
||||
fWinBorder->SetTopLayer(CreateLayerTree(link, NULL));
|
||||
fCurrentLayer = fWinBorder->TopLayer();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -524,11 +529,10 @@ myRootLayer->Unlock();
|
||||
|
||||
Layer* parent = NULL;
|
||||
Layer* newLayer = CreateLayerTree(link, &parent);
|
||||
myRootLayer->Lock();
|
||||
if (parent != NULL)
|
||||
parent->AddChild(newLayer, this);
|
||||
|
||||
if (!newLayer->IsHidden() && parent)
|
||||
if (myRootLayer && !newLayer->IsHidden() && parent)
|
||||
#ifndef NEW_CLIPPING
|
||||
myRootLayer->GoInvalidate(newLayer, newLayer->fFull);
|
||||
#else
|
||||
@@ -538,8 +542,6 @@ myRootLayer->Lock();
|
||||
myRootLayer->GoInvalidate(newLayer, invalidRegion);
|
||||
}
|
||||
#endif
|
||||
|
||||
myRootLayer->Unlock();
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_DELETE:
|
||||
@@ -568,11 +570,10 @@ myRootLayer->Lock();
|
||||
fCurrentLayer->RemoveSelf();
|
||||
fCurrentLayer->PruneTree();
|
||||
|
||||
if (invalidRegion) {
|
||||
if (invalidRegion && myRootLayer) {
|
||||
myRootLayer->GoInvalidate(parent, *invalidRegion);
|
||||
delete invalidRegion;
|
||||
}
|
||||
myRootLayer->Unlock();
|
||||
|
||||
#ifdef DEBUG_SERVERWINDOW
|
||||
parent->PrintTree();
|
||||
@@ -627,7 +628,8 @@ myRootLayer->Unlock();
|
||||
link.Read<uint32>(&mask);
|
||||
link.Read<uint32>(&options);
|
||||
|
||||
myRootLayer->SetEventMaskLayer(fCurrentLayer, mask, options);
|
||||
if (myRootLayer)
|
||||
myRootLayer->SetEventMaskLayer(fCurrentLayer, mask, options);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_MOVE_TO:
|
||||
@@ -713,7 +715,9 @@ myRootLayer->Unlock();
|
||||
}
|
||||
case AS_LAYER_SET_FLAGS:
|
||||
{
|
||||
link.Read<uint32>(&(fCurrentLayer->fFlags));
|
||||
uint32 flags;
|
||||
link.Read<uint32>(&flags);
|
||||
fCurrentLayer->SetFlags(flags);
|
||||
|
||||
STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
break;
|
||||
@@ -858,7 +862,8 @@ myRootLayer->Lock();
|
||||
fCurrentLayer->SetViewColor(RGBColor(c));
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
|
||||
if (myRootLayer)
|
||||
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
|
||||
#else
|
||||
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
|
||||
#endif
|
||||
@@ -941,7 +946,7 @@ myRootLayer->Unlock();
|
||||
DTRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n", Title(), fCurrentLayer->Name()));
|
||||
bool fontAliasing;
|
||||
link.Read<bool>(&fontAliasing);
|
||||
fCurrentLayer->fLayerData->SetFontAntiAliasing(!fontAliasing);
|
||||
fCurrentLayer->fLayerData->SetForceFontAliasing(fontAliasing);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -976,7 +981,7 @@ myRootLayer->Unlock();
|
||||
#ifndef NEW_CLIPPING
|
||||
fCurrentLayer->RebuildFullRegion();
|
||||
#endif
|
||||
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
#ifndef NEW_CLIPPING
|
||||
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
|
||||
#else
|
||||
@@ -998,15 +1003,16 @@ myRootLayer->Unlock();
|
||||
if (fCurrentLayer->IsHidden()) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(0L);
|
||||
fLink.Flush();
|
||||
} else {
|
||||
// TODO: Watch out for the coordinate system in AS_LAYER_GET_CLIP_REGION
|
||||
LayerData* layerData = fCurrentLayer->fLayerData;
|
||||
BRegion region;
|
||||
|
||||
// TODO: This could also be done more reliably in the Layer,
|
||||
// when the State stack is implemented there. There should be
|
||||
// DrawData::fCulmulatedClippingRegion...
|
||||
// TODO: the DrawData clipping region should be in local view coords.
|
||||
LayerData* layerData = fCurrentLayer->fLayerData;
|
||||
|
||||
do {
|
||||
if (layerData->ClippingRegion())
|
||||
@@ -1020,9 +1026,10 @@ myRootLayer->Unlock();
|
||||
|
||||
for (int32 i = 0; i < rectCount; i++)
|
||||
fLink.Attach<BRect>(region.RectAt(i));
|
||||
|
||||
fLink.Flush();
|
||||
}
|
||||
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_SET_CLIP_REGION:
|
||||
@@ -1041,16 +1048,16 @@ myRootLayer->Unlock();
|
||||
region.Include(r);
|
||||
}
|
||||
fCurrentLayer->fLayerData->SetClippingRegion(region);
|
||||
|
||||
/*
|
||||
#ifndef NEW_CLIPPING
|
||||
fCurrentLayer->RebuildFullRegion();
|
||||
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull);
|
||||
#else
|
||||
if (!(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
if (myRootLayer && !(fCurrentLayer->IsHidden()) && !fWinBorder->InUpdate())
|
||||
myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame());
|
||||
#endif
|
||||
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_INVAL_RECT:
|
||||
@@ -1061,13 +1068,17 @@ myRootLayer->Unlock();
|
||||
BRect invalRect;
|
||||
|
||||
link.Read<BRect>(&invalRect);
|
||||
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
|
||||
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
|
||||
BRegion invalidRegion(converted);
|
||||
// invalidRegion.IntersectWith(&fCurrentLayer->fVisible);
|
||||
|
||||
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
|
||||
if (myRootLayer) {
|
||||
BRect converted(fCurrentLayer->ConvertToTop(invalRect.LeftTop()),
|
||||
fCurrentLayer->ConvertToTop(invalRect.RightBottom()));
|
||||
BRegion invalidRegion(converted);
|
||||
#ifdef NEW_CLIPPING
|
||||
invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
|
||||
#endif
|
||||
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_INVAL_REGION:
|
||||
@@ -1082,30 +1093,26 @@ myRootLayer->Unlock();
|
||||
|
||||
link.Read<int32>(&noOfRects);
|
||||
|
||||
for(int i = 0; i < noOfRects; i++)
|
||||
{
|
||||
for (int i = 0; i < noOfRects; i++) {
|
||||
link.Read<BRect>(&rect);
|
||||
invalReg.Include(rect);
|
||||
}
|
||||
|
||||
myRootLayer->GoRedraw(fCurrentLayer, invalReg);
|
||||
|
||||
if (myRootLayer)
|
||||
myRootLayer->GoRedraw(fCurrentLayer, invalReg);
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_BEGIN_UPDATE:
|
||||
{
|
||||
DTRACE(("ServerWindowo %s: AS_BEGIN_UPDATE\n", Title()));
|
||||
fWinBorder->GetRootLayer()->Lock();
|
||||
fWinBorder->UpdateStart();
|
||||
fWinBorder->GetRootLayer()->Unlock();
|
||||
break;
|
||||
}
|
||||
case AS_END_UPDATE:
|
||||
{
|
||||
DTRACE(("ServerWindowo %s: AS_END_UPDATE\n", Title()));
|
||||
fWinBorder->GetRootLayer()->Lock();
|
||||
fWinBorder->UpdateEnd();
|
||||
fWinBorder->GetRootLayer()->Unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1160,7 +1167,6 @@ myRootLayer->Unlock();
|
||||
#endif
|
||||
case AS_WINDOW_TITLE:
|
||||
{
|
||||
// TODO: Implement AS_WINDOW_TITLE
|
||||
|
||||
char* newTitle;
|
||||
if (link.ReadString(&newTitle) == B_OK) {
|
||||
@@ -1169,6 +1175,10 @@ myRootLayer->Unlock();
|
||||
|
||||
free(newTitle);
|
||||
}
|
||||
char* title;
|
||||
link.ReadString(&title);
|
||||
fWinBorder->SetName(title);
|
||||
free(title);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1243,7 +1253,9 @@ myRootLayer->Unlock();
|
||||
STRACE(("ServerWindow %s: Message AS_SET_FEEL\n", Title()));
|
||||
int32 newFeel;
|
||||
link.Read<int32>(&newFeel);
|
||||
myRootLayer->GoChangeWinBorderFeel(fWinBorder, newFeel);
|
||||
|
||||
if (myRootLayer)
|
||||
myRootLayer->GoChangeWinBorderFeel(fWinBorder, newFeel);
|
||||
break;
|
||||
}
|
||||
case AS_SET_ALIGNMENT:
|
||||
@@ -1511,16 +1523,15 @@ myRootLayer->Unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
myRootLayer->Unlock();
|
||||
if (myRootLayer)
|
||||
myRootLayer->Unlock();
|
||||
}
|
||||
|
||||
// -------------------- Graphics messages ----------------------------------
|
||||
// -------------------- Graphics messages ----------------------------------
|
||||
|
||||
inline
|
||||
void
|
||||
ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
{
|
||||
fWinBorder->GetRootLayer()->Lock();
|
||||
#ifndef NEW_CLIPPING
|
||||
BRegion rreg(fCurrentLayer->fVisible);
|
||||
#else
|
||||
@@ -1530,10 +1541,12 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
if (fWinBorder->InUpdate())
|
||||
rreg.IntersectWith(&fWinBorder->RegionToBeUpdated());
|
||||
|
||||
gDesktop->GetDisplayDriver()->ConstrainClippingRegion(&rreg);
|
||||
DisplayDriver* driver = fWinBorder->GetDisplayDriver();
|
||||
|
||||
driver->ConstrainClippingRegion(&rreg);
|
||||
// rgb_color rrr = fCurrentLayer->fLayerData->viewcolor.GetColor32();
|
||||
// RGBColor c(rand()%255,rand()%255,rand()%255);
|
||||
// gDesktop->GetDisplayDriver()->FillRect(BRect(0,0,639,479), c);
|
||||
// driver->FillRect(BRect(0,0,639,479), c);
|
||||
|
||||
switch (code) {
|
||||
case AS_STROKE_LINE:
|
||||
@@ -1548,11 +1561,12 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<float>(&y2);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData) {
|
||||
|
||||
BPoint p1(x1,y1);
|
||||
BPoint p2(x2,y2);
|
||||
gDesktop->GetDisplayDriver()->StrokeLine(fCurrentLayer->ConvertToTop(p1),
|
||||
fCurrentLayer->ConvertToTop(p2),
|
||||
fCurrentLayer->fLayerData);
|
||||
driver->StrokeLine(fCurrentLayer->ConvertToTop(p1),
|
||||
fCurrentLayer->ConvertToTop(p2),
|
||||
fCurrentLayer->fLayerData);
|
||||
|
||||
// We update the pen here because many DisplayDriver calls which do not update the
|
||||
// pen position actually call StrokeLine
|
||||
@@ -1572,7 +1586,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<BRect>(&rect);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->InvertRect(fCurrentLayer->ConvertToTop(rect));
|
||||
driver->InvertRect(fCurrentLayer->ConvertToTop(rect));
|
||||
break;
|
||||
}
|
||||
case AS_STROKE_RECT:
|
||||
@@ -1587,7 +1601,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect rect(left,top,right,bottom);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->StrokeRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->StrokeRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_FILL_RECT:
|
||||
@@ -1597,7 +1611,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect rect;
|
||||
link.Read<BRect>(&rect);
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->FillRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->FillRect(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT:
|
||||
@@ -1615,7 +1629,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect dst = src.OffsetToCopy(point);
|
||||
dst = fCurrentLayer->ConvertToTop(dst);
|
||||
|
||||
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
|
||||
driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
|
||||
}
|
||||
|
||||
// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_AT_POINT sync with the client?
|
||||
@@ -1636,7 +1650,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect dst = src.OffsetToCopy(point);
|
||||
dst = fCurrentLayer->ConvertToTop(dst);
|
||||
|
||||
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
|
||||
driver->DrawBitmap(sbmp, src, dst, fCurrentLayer->fLayerData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1654,7 +1668,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
if (sbmp) {
|
||||
dstRect = fCurrentLayer->ConvertToTop(dstRect);
|
||||
|
||||
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
|
||||
driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
|
||||
}
|
||||
|
||||
// TODO: Adi -- shouldn't AS_LAYER_DRAW_BITMAP_SYNC_IN_RECT sync with the client?
|
||||
@@ -1674,7 +1688,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
if (sbmp) {
|
||||
dstRect = fCurrentLayer->ConvertToTop(dstRect);
|
||||
|
||||
fCurrentLayer->GetDisplayDriver()->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
|
||||
driver->DrawBitmap(sbmp, srcRect, dstRect, fCurrentLayer->fLayerData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1689,7 +1703,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<float>(&angle);
|
||||
link.Read<float>(&span);
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->StrokeArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
|
||||
driver->StrokeArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_FILL_ARC:
|
||||
@@ -1703,7 +1717,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<float>(&angle);
|
||||
link.Read<float>(&span);
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->FillArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
|
||||
driver->FillArc(fCurrentLayer->ConvertToTop(r),angle,span, fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_STROKE_BEZIER:
|
||||
@@ -1722,7 +1736,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (i=0; i<4; i++)
|
||||
pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->StrokeBezier(pts, fCurrentLayer->fLayerData);
|
||||
driver->StrokeBezier(pts, fCurrentLayer->fLayerData);
|
||||
}
|
||||
delete [] pts;
|
||||
break;
|
||||
@@ -1743,7 +1757,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (i=0; i<4; i++)
|
||||
pts[i]=fCurrentLayer->ConvertToTop(pts[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->FillBezier(pts, fCurrentLayer->fLayerData);
|
||||
driver->FillBezier(pts, fCurrentLayer->fLayerData);
|
||||
}
|
||||
delete [] pts;
|
||||
break;
|
||||
@@ -1755,7 +1769,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect rect;
|
||||
link.Read<BRect>(&rect);
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->StrokeEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->StrokeEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_FILL_ELLIPSE:
|
||||
@@ -1765,7 +1779,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
BRect rect;
|
||||
link.Read<BRect>(&rect);
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->FillEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->FillEllipse(fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_STROKE_ROUNDRECT:
|
||||
@@ -1779,7 +1793,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<float>(&yrad);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->StrokeRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
|
||||
driver->StrokeRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_FILL_ROUNDRECT:
|
||||
@@ -1793,7 +1807,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.Read<float>(&yrad);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->FillRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
|
||||
driver->FillRoundRect(fCurrentLayer->ConvertToTop(rect),xrad,yrad, fCurrentLayer->fLayerData);
|
||||
break;
|
||||
}
|
||||
case AS_STROKE_TRIANGLE:
|
||||
@@ -1812,7 +1826,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int i = 0;i < 3; i++)
|
||||
pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->StrokeTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->StrokeTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1832,7 +1846,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int i = 0; i < 3; i++)
|
||||
pts[i] = fCurrentLayer->ConvertToTop(pts[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->FillTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
driver->FillTriangle(pts, fCurrentLayer->ConvertToTop(rect), fCurrentLayer->fLayerData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1857,7 +1871,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int32 i = 0; i < pointcount; i++)
|
||||
pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->StrokePolygon(pointlist,pointcount,polyframe,
|
||||
driver->StrokePolygon(pointlist,pointcount,polyframe,
|
||||
fCurrentLayer->fLayerData,isclosed);
|
||||
|
||||
delete [] pointlist;
|
||||
@@ -1881,7 +1895,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int32 i = 0; i < pointcount; i++)
|
||||
pointlist[i] = fCurrentLayer->ConvertToTop(pointlist[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->FillPolygon(pointlist,pointcount,polyframe, fCurrentLayer->fLayerData);
|
||||
driver->FillPolygon(pointlist,pointcount,polyframe, fCurrentLayer->fLayerData);
|
||||
|
||||
delete [] pointlist;
|
||||
break;
|
||||
@@ -1909,7 +1923,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int32 i = 0; i < ptcount; i++)
|
||||
ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->StrokeShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
|
||||
driver->StrokeShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
|
||||
delete[] oplist;
|
||||
delete[] ptlist;
|
||||
break;
|
||||
@@ -1937,7 +1951,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
for (int32 i = 0; i < ptcount; i++)
|
||||
ptlist[i] = fCurrentLayer->ConvertToTop(ptlist[i]);
|
||||
|
||||
gDesktop->GetDisplayDriver()->FillShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
|
||||
driver->FillShape(shaperect, opcount, oplist, ptcount, ptlist, fCurrentLayer->fLayerData);
|
||||
|
||||
delete[] oplist;
|
||||
delete[] ptlist;
|
||||
@@ -1959,10 +1973,11 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
// Between the client-side conversion to BRects from clipping_rects to the overhead
|
||||
// in repeatedly calling FillRect(), this is definitely in need of optimization. At
|
||||
// least it works for now. :)
|
||||
BRegion region;
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
gDesktop->GetDisplayDriver()->FillRect(fCurrentLayer->ConvertToTop(rects[i]),
|
||||
fCurrentLayer->fLayerData);
|
||||
region.Include(fCurrentLayer->ConvertToTop(rects[i]));
|
||||
}
|
||||
driver->FillRegion(region, fCurrentLayer->fLayerData);
|
||||
|
||||
delete[] rects;
|
||||
|
||||
@@ -1996,7 +2011,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
index->pt1 = fCurrentLayer->ConvertToTop(index->pt1);
|
||||
index->pt2 = fCurrentLayer->ConvertToTop(index->pt2);
|
||||
}
|
||||
gDesktop->GetDisplayDriver()->StrokeLineArray(linecount,linedata,fCurrentLayer->fLayerData);
|
||||
driver->StrokeLineArray(linecount,linedata,fCurrentLayer->fLayerData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2014,13 +2029,22 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
link.ReadString(&string);
|
||||
|
||||
if (fCurrentLayer && fCurrentLayer->fLayerData)
|
||||
gDesktop->GetDisplayDriver()->DrawString(string, length,
|
||||
fCurrentLayer->ConvertToTop(location),
|
||||
fCurrentLayer->fLayerData);
|
||||
driver->DrawString(string, length,
|
||||
fCurrentLayer->ConvertToTop(location),
|
||||
fCurrentLayer->fLayerData);
|
||||
|
||||
free(string);
|
||||
break;
|
||||
}
|
||||
case AS_LAYER_BEGIN_PICTURE:
|
||||
CRITICAL("AS_LAYER_BEGIN_PICTURE not implemented\n");
|
||||
break;
|
||||
case AS_LAYER_APPEND_TO_PICTURE:
|
||||
CRITICAL("AS_LAYER_APPEND_TO_PICTURE not implemented\n");
|
||||
break;
|
||||
case AS_LAYER_END_PICTURE:
|
||||
CRITICAL("AS_LAYER_END_PICTURE not implemented\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ServerWindow %s received unexpected code - message offset %ld\n",
|
||||
@@ -2034,8 +2058,7 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
break;
|
||||
}
|
||||
|
||||
gDesktop->GetDisplayDriver()->ConstrainClippingRegion(NULL);
|
||||
fWinBorder->GetRootLayer()->Unlock();
|
||||
driver->ConstrainClippingRegion(NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2123,6 +2146,72 @@ ServerWindow::_MessageLooper()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
ServerWindow::_CopyBits(RootLayer* rootLayer, Layer* layer,
|
||||
BRect& src, BRect& dst,
|
||||
int32 xOffset, int32 yOffset) const
|
||||
{
|
||||
// NOTE: The correct behaviour is this:
|
||||
// * The region that is copied is the
|
||||
// src rectangle, no matter if it fits
|
||||
// into the dst rectangle. It is copied
|
||||
// by the offset dst.LeftTop() - src.LeftTop()
|
||||
// * The dst rectangle is used for invalidation:
|
||||
// Any area in the dst rectangle that could
|
||||
// not be copied from src (because either the
|
||||
// src rectangle was not big enough, or because there
|
||||
// were parts cut off by the current layer clipping),
|
||||
// are triggering BView::Draw() to be called
|
||||
// and for these parts only.
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
|
||||
// the region that is going to be copied
|
||||
BRegion copyRegion(src);
|
||||
// apply the current clipping of the layer
|
||||
|
||||
copyRegion.IntersectWith(&layer->fVisible);
|
||||
|
||||
// offset the region to the destination
|
||||
// and apply the current clipping there as well
|
||||
copyRegion.OffsetBy(xOffset, yOffset);
|
||||
copyRegion.IntersectWith(&layer->fVisible);
|
||||
|
||||
// the region at the destination that needs invalidation
|
||||
BRegion invalidRegion(dst);
|
||||
// exclude the region drawn by the copy operation
|
||||
invalidRegion.Exclude(©Region);
|
||||
// apply the current clipping as well
|
||||
invalidRegion.IntersectWith(&layer->fVisible);
|
||||
|
||||
// move the region back for the actual operation
|
||||
copyRegion.OffsetBy(-xOffset, -yOffset);
|
||||
|
||||
layer->GetDisplayDriver()->CopyRegion(©Region, xOffset, yOffset);
|
||||
|
||||
// trigger the redraw
|
||||
if (rootLayer) {
|
||||
// the following code solves a "concurrency" problem:
|
||||
// since the scrolling might happen more often
|
||||
// than redrawing, we need to keep track of the region
|
||||
// pending for redraw that might fall into the area
|
||||
// that is scrolled.
|
||||
BRegion scrolledInvalid(fWinBorder->CulmulatedUpdateRegion());
|
||||
scrolledInvalid.IntersectWith(&layer->fVisible);
|
||||
if (scrolledInvalid.Frame().IsValid()) {
|
||||
//printf("the layer has pending updates that will be scrolled\n");
|
||||
scrolledInvalid.OffsetBy(xOffset, yOffset);
|
||||
invalidRegion.Include(&scrolledInvalid);
|
||||
}
|
||||
|
||||
rootLayer->GoRedraw(fWinBorder, invalidRegion);
|
||||
}
|
||||
|
||||
#endif
|
||||
}*/
|
||||
|
||||
|
||||
void
|
||||
ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePreferred) const
|
||||
{
|
||||
@@ -2140,6 +2229,16 @@ ServerWindow::SendMessageToClient(const BMessage* msg, int32 target, bool usePre
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
// MakeWinBorder
|
||||
WinBorder*
|
||||
ServerWindow::MakeWinBorder(BRect frame, const char* name,
|
||||
uint32 look, uint32 feel, uint32 flags,
|
||||
uint32 workspace)
|
||||
{
|
||||
// The non-offscreen ServerWindow uses the DisplayDriver instance from the desktop.
|
||||
return new(nothrow) WinBorder(frame, name, look, feel, flags,
|
||||
workspace, this, gDesktop->GetDisplayDriver());
|
||||
}
|
||||
|
||||
status_t
|
||||
ServerWindow::PictureToRegion(ServerPicture *picture, BRegion ®ion,
|
||||
|
||||
@@ -55,11 +55,12 @@ class ServerWindow : public BLocker {
|
||||
public:
|
||||
ServerWindow(const char *title, ServerApp *app,
|
||||
port_id clientPort, port_id looperPort,
|
||||
int32 handlerID, BRect frame, uint32 look,
|
||||
uint32 feel, uint32 flags, uint32 workspace);
|
||||
int32 handlerID);
|
||||
virtual ~ServerWindow();
|
||||
|
||||
status_t InitCheck();
|
||||
status_t Init(BRect frame, uint32 look,
|
||||
uint32 feel, uint32 flags,
|
||||
uint32 workspace);
|
||||
bool Run();
|
||||
void Quit();
|
||||
|
||||
@@ -77,9 +78,15 @@ public:
|
||||
const color_space cspace);
|
||||
|
||||
// util methods.
|
||||
void SendMessageToClient(const BMessage* msg,
|
||||
virtual void SendMessageToClient(const BMessage* msg,
|
||||
int32 target = B_NULL_TOKEN,
|
||||
bool usePreferred = false) const;
|
||||
|
||||
virtual WinBorder* MakeWinBorder(BRect frame,
|
||||
const char* name,
|
||||
uint32 look, uint32 feel,
|
||||
uint32 flags, uint32 workspace);
|
||||
|
||||
|
||||
// TODO: Ouch, that's not exactly a nice name
|
||||
inline BMessage &ClientViewsWithInvalidCoords()
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
// Description: Methods to initialize and get the system color_map.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
|
||||
#include <SystemPalette.h>
|
||||
|
||||
const static rgb_color kSystemPalette[] = {
|
||||
@@ -155,7 +157,7 @@ color_distance(uint8 red1, uint8 green1, uint8 blue1,
|
||||
}
|
||||
|
||||
|
||||
static uint8
|
||||
static inline uint8
|
||||
FindClosestColor(const rgb_color &color, const rgb_color *palette)
|
||||
{
|
||||
uint8 closestIndex = 0;
|
||||
@@ -221,6 +223,7 @@ FillColorMap(const rgb_color *palette, color_map *map)
|
||||
void
|
||||
InitializeColorMap()
|
||||
{
|
||||
printf("InitializeColorMap()\n");
|
||||
FillColorMap(kSystemPalette, &sColorMap);
|
||||
}
|
||||
|
||||
|
||||
@@ -129,8 +129,6 @@ WinBorder::WinBorder(const BRect &frame,
|
||||
RebuildFullRegion();
|
||||
#endif
|
||||
|
||||
gDesktop->AddWinBorder(this);
|
||||
|
||||
STRACE(("WinBorder %s:\n", GetName()));
|
||||
STRACE(("\tFrame: (%.1f, %.1f, %.1f, %.1f)\n", r.left, r.top, r.right, r.bottom));
|
||||
STRACE(("\tWindow %s\n", window ? window->Title() : "NULL"));
|
||||
@@ -141,8 +139,6 @@ WinBorder::~WinBorder()
|
||||
{
|
||||
STRACE(("WinBorder(%s)::~WinBorder()\n",GetName()));
|
||||
|
||||
gDesktop->RemoveWinBorder(this);
|
||||
|
||||
delete fTopLayer;
|
||||
delete fDecorator;
|
||||
}
|
||||
@@ -274,7 +270,7 @@ WinBorder::_ResizeBy(float x, float y)
|
||||
if (x == 0.0 && y == 0.0)
|
||||
return false;
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
#ifndef NEW_CLIPPING
|
||||
if (fDecorator)
|
||||
fDecorator->ResizeBy(x, y);
|
||||
|
||||
@@ -296,6 +292,34 @@ WinBorder::_ResizeBy(float x, float y)
|
||||
return true;
|
||||
}
|
||||
|
||||
// SetName
|
||||
void
|
||||
WinBorder::SetName(const char* name)
|
||||
{
|
||||
Layer::SetName(name);
|
||||
|
||||
// rebuild the clipping for the title area
|
||||
// and redraw it.
|
||||
|
||||
// TODO: Adi, please have a look at this,
|
||||
// it doesn't work yet.
|
||||
if (fDecorator) {
|
||||
// before the change
|
||||
BRegion invalid(fDecorator->GetTabRect());
|
||||
|
||||
fDecorator->SetTitle(name);
|
||||
|
||||
// after the change
|
||||
invalid.Include(fDecorator->GetTabRect());
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
RebuildFullRegion();
|
||||
fRootLayer->GoRedraw(this, invalid);
|
||||
#else
|
||||
// TODO: ...
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateStart
|
||||
void
|
||||
@@ -375,7 +399,9 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth,
|
||||
|
||||
// On R5, Windows don't automatically resize, but since
|
||||
// BWindow::ResizeTo() even honors the limits, I would guess
|
||||
// this is a bug that we don't have to adopt
|
||||
// this is a bug that we don't have to adopt.
|
||||
// Note that most current apps will do unnecessary resizing
|
||||
// after having set the limits, but the overhead is neglible.
|
||||
|
||||
float minWidthDiff = fMinWidth - fFrame.Width();
|
||||
float minHeightDiff = fMinHeight - fFrame.Height();
|
||||
@@ -394,7 +420,6 @@ WinBorder::SetSizeLimits(float minWidth, float maxWidth,
|
||||
else if (maxHeightDiff < 0.0) // we're currently larger than maxHeight
|
||||
yDiff = maxHeightDiff;
|
||||
|
||||
// Layer::ResizeBy(xDiff, yDiff);
|
||||
ResizeBy(xDiff, yDiff);
|
||||
}
|
||||
|
||||
@@ -776,3 +801,17 @@ void WinBorder::get_user_regions(BRegion ®)
|
||||
reg.Include(&fDecRegion);
|
||||
}
|
||||
#endif
|
||||
|
||||
// SetTopLayer
|
||||
void
|
||||
WinBorder::SetTopLayer(Layer* layer)
|
||||
{
|
||||
if (layer) {
|
||||
fTopLayer = layer;
|
||||
fTopLayer->SetAsTopLayer(true);
|
||||
|
||||
// connect decorator and top layer. (?)
|
||||
AddChild(fTopLayer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,12 @@ class WinBorder : public Layer {
|
||||
virtual void ScrollBy(float x, float y)
|
||||
{ // not allowed
|
||||
}
|
||||
|
||||
virtual void SetName(const char* name);
|
||||
|
||||
virtual bool IsOffscreenWindow() const
|
||||
{ return false; }
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
virtual void RebuildFullRegion();
|
||||
#endif
|
||||
@@ -76,6 +82,8 @@ class WinBorder : public Layer {
|
||||
{ return fInUpdate; }
|
||||
inline const BRegion& RegionToBeUpdated() const
|
||||
{ return fInUpdateRegion; }
|
||||
inline const BRegion& CulmulatedUpdateRegion() const
|
||||
{ return fCumulativeRegion; }
|
||||
|
||||
void SetSizeLimits(float minWidth,
|
||||
float maxWidth,
|
||||
@@ -131,9 +139,13 @@ class WinBorder : public Layer {
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual void SetTopLayer(Layer* layer);
|
||||
inline Layer* TopLayer() const
|
||||
{ return fTopLayer; }
|
||||
|
||||
protected:
|
||||
friend class Layer;
|
||||
friend class ServerWindow;
|
||||
friend class RootLayer;
|
||||
|
||||
click_type _ActionFor(const PointerEvent& evt) const;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
// BitmapBuffer.h
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include "ServerBitmap.h"
|
||||
|
||||
#include "BitmapBuffer.h"
|
||||
|
||||
// TODO: It should be more or less guaranteed that this object
|
||||
// is not used if InitCheck() returns an error, so the checks
|
||||
// in all thos functions should probably be removed...
|
||||
|
||||
// constructor
|
||||
BitmapBuffer::BitmapBuffer(BBitmap* bitmap)
|
||||
BitmapBuffer::BitmapBuffer(ServerBitmap* bitmap)
|
||||
: fBitmap(bitmap)
|
||||
{
|
||||
}
|
||||
@@ -13,7 +17,7 @@ BitmapBuffer::BitmapBuffer(BBitmap* bitmap)
|
||||
// destructor
|
||||
BitmapBuffer::~BitmapBuffer()
|
||||
{
|
||||
delete fBitmap;
|
||||
// We don't own the ServerBitmap
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
@@ -22,7 +26,7 @@ BitmapBuffer::InitCheck() const
|
||||
{
|
||||
status_t ret = B_NO_INIT;
|
||||
if (fBitmap)
|
||||
ret = fBitmap->InitCheck();
|
||||
ret = fBitmap->IsValid() ? B_OK : B_ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -58,7 +62,7 @@ uint32
|
||||
BitmapBuffer::Width() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->Bounds().IntegerWidth() + 1;
|
||||
return fBitmap->Width();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -67,7 +71,7 @@ uint32
|
||||
BitmapBuffer::Height() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->Bounds().IntegerHeight() + 1;
|
||||
return fBitmap->Height();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
|
||||
#include "RenderingBuffer.h"
|
||||
|
||||
class BBitmap;
|
||||
class ServerBitmap;
|
||||
|
||||
class BitmapBuffer : public RenderingBuffer {
|
||||
public:
|
||||
BitmapBuffer(BBitmap* bitmap);
|
||||
BitmapBuffer(ServerBitmap* bitmap);
|
||||
virtual ~BitmapBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
@@ -21,11 +21,11 @@ class BitmapBuffer : public RenderingBuffer {
|
||||
virtual uint32 Height() const;
|
||||
|
||||
// BitmapBuffer
|
||||
const BBitmap* Bitmap() const
|
||||
const ServerBitmap* Bitmap() const
|
||||
{ return fBitmap; }
|
||||
private:
|
||||
|
||||
BBitmap* fBitmap;
|
||||
ServerBitmap* fBitmap;
|
||||
};
|
||||
|
||||
#endif // BITMAP_BUFFER_H
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright 2002-2005, Haiku, Inc. All rights reserved.
|
||||
// Distributed under the terms of the MIT License.
|
||||
//
|
||||
//
|
||||
// File Name: BitmapHWInterface.cpp
|
||||
// Authors: Michael Lotz <[email protected]>
|
||||
// DarkWyrm <[email protected]>
|
||||
// Stephan Aßmus <[email protected]>
|
||||
// Description: Accelerant based HWInterface implementation
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Cursor.h>
|
||||
|
||||
#include "Bitmap.h"
|
||||
#include "BitmapBuffer.h"
|
||||
#include "BBitmapBuffer.h"
|
||||
|
||||
#include "BitmapHWInterface.h"
|
||||
|
||||
// constructor
|
||||
BitmapHWInterface::BitmapHWInterface(ServerBitmap* bitmap)
|
||||
: HWInterface(),
|
||||
fBackBuffer(NULL),
|
||||
fFrontBuffer(new(nothrow) BitmapBuffer(bitmap))
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
BitmapHWInterface::~BitmapHWInterface()
|
||||
{
|
||||
delete fBackBuffer;
|
||||
delete fFrontBuffer;
|
||||
}
|
||||
|
||||
// Initialize
|
||||
status_t
|
||||
BitmapHWInterface::Initialize()
|
||||
{
|
||||
status_t ret = HWInterface::Initialize();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
ret = fFrontBuffer->InitCheck();
|
||||
if (ret < B_OK)
|
||||
return ret;
|
||||
|
||||
// TODO: Remove once unnecessary...
|
||||
// fall back to double buffered mode until Painter knows how
|
||||
// to draw onto non 32-bit surfaces...
|
||||
if (fFrontBuffer->ColorSpace() != B_RGB32 &&
|
||||
fFrontBuffer->ColorSpace() != B_RGBA32) {
|
||||
|
||||
BBitmap* backBitmap = new BBitmap(fFrontBuffer->Bounds(),
|
||||
B_BITMAP_NO_SERVER_LINK,
|
||||
B_RGBA32);
|
||||
fBackBuffer = new BBitmapBuffer(backBitmap);
|
||||
|
||||
ret = fBackBuffer->InitCheck();
|
||||
if (ret < B_OK) {
|
||||
delete fBackBuffer;
|
||||
fBackBuffer = NULL;
|
||||
} else {
|
||||
// import the current contents of the bitmap
|
||||
// into the back bitmap
|
||||
backBitmap->ImportBits(fFrontBuffer->Bits(),
|
||||
fFrontBuffer->BitsLength(),
|
||||
fFrontBuffer->BytesPerRow(),
|
||||
0,
|
||||
fFrontBuffer->ColorSpace());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Shutdown
|
||||
status_t
|
||||
BitmapHWInterface::Shutdown()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// SetMode
|
||||
status_t
|
||||
BitmapHWInterface::SetMode(const display_mode &mode)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// GetMode
|
||||
void
|
||||
BitmapHWInterface::GetMode(display_mode *mode)
|
||||
{
|
||||
if (mode) {
|
||||
memset(mode, 0, sizeof(display_mode));
|
||||
}
|
||||
}
|
||||
|
||||
// GetDeviceInfo
|
||||
status_t
|
||||
BitmapHWInterface::GetDeviceInfo(accelerant_device_info *info)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// GetModeList
|
||||
status_t
|
||||
BitmapHWInterface::GetModeList(display_mode** modes, uint32 *count)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// GetPixelClockLimits
|
||||
status_t
|
||||
BitmapHWInterface::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// GetPixelClockLimits
|
||||
status_t
|
||||
BitmapHWInterface::GetTimingConstraints(display_timing_constraints *dtc)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// ProposeMode
|
||||
status_t
|
||||
BitmapHWInterface::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// RetraceSemaphore
|
||||
sem_id
|
||||
BitmapHWInterface::RetraceSemaphore()
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// WaitForRetrace
|
||||
status_t
|
||||
BitmapHWInterface::WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// SetDPMSMode
|
||||
status_t
|
||||
BitmapHWInterface::SetDPMSMode(const uint32 &state)
|
||||
{
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
// DPMSMode
|
||||
uint32
|
||||
BitmapHWInterface::DPMSMode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// DPMSCapabilities
|
||||
uint32
|
||||
BitmapHWInterface::DPMSCapabilities()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FrontBuffer
|
||||
RenderingBuffer *
|
||||
BitmapHWInterface::FrontBuffer() const
|
||||
{
|
||||
return fFrontBuffer;
|
||||
}
|
||||
|
||||
// BackBuffer
|
||||
RenderingBuffer *
|
||||
BitmapHWInterface::BackBuffer() const
|
||||
{
|
||||
return fBackBuffer;
|
||||
}
|
||||
|
||||
// IsDoubleBuffered
|
||||
bool
|
||||
BitmapHWInterface::IsDoubleBuffered() const
|
||||
{
|
||||
// overwrite double buffered preference
|
||||
if (fFrontBuffer)
|
||||
return fBackBuffer != NULL;
|
||||
|
||||
return HWInterface::IsDoubleBuffered();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
// Distributed under the terms of the MIT License.
|
||||
//
|
||||
// Author: Stephan Aßmus, <[email protected]>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BITMAP_HW_INTERFACE_H
|
||||
#define BITMAP_HW_INTERFACE_H
|
||||
|
||||
#include "HWInterface.h"
|
||||
|
||||
class BitmapBuffer;
|
||||
class MallocBuffer;
|
||||
class ServerBitmap;
|
||||
class BBitmapBuffer;
|
||||
|
||||
class BitmapHWInterface : public HWInterface {
|
||||
public:
|
||||
BitmapHWInterface(ServerBitmap* bitmap);
|
||||
virtual ~BitmapHWInterface();
|
||||
|
||||
virtual status_t Initialize();
|
||||
virtual status_t Shutdown();
|
||||
|
||||
// overwrite all the meaningless functions with empty code
|
||||
virtual status_t SetMode(const display_mode &mode);
|
||||
virtual void GetMode(display_mode *mode);
|
||||
|
||||
virtual status_t GetDeviceInfo(accelerant_device_info *info);
|
||||
virtual status_t GetModeList(display_mode **mode_list,
|
||||
uint32 *count);
|
||||
virtual status_t GetPixelClockLimits(display_mode *mode,
|
||||
uint32 *low,
|
||||
uint32 *high);
|
||||
virtual status_t GetTimingConstraints(display_timing_constraints *dtc);
|
||||
virtual status_t ProposeMode(display_mode *candidate,
|
||||
const display_mode *low,
|
||||
const display_mode *high);
|
||||
|
||||
virtual sem_id RetraceSemaphore();
|
||||
virtual status_t WaitForRetrace(bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
|
||||
virtual status_t SetDPMSMode(const uint32 &state);
|
||||
virtual uint32 DPMSMode();
|
||||
virtual uint32 DPMSCapabilities();
|
||||
|
||||
// frame buffer access
|
||||
virtual RenderingBuffer* FrontBuffer() const;
|
||||
virtual RenderingBuffer* BackBuffer() const;
|
||||
virtual bool IsDoubleBuffered() const;
|
||||
|
||||
private:
|
||||
BBitmapBuffer* fBackBuffer;
|
||||
BitmapBuffer* fFrontBuffer;
|
||||
};
|
||||
|
||||
#endif // BITMAP_HW_INTERFACE_H
|
||||
@@ -19,11 +19,36 @@
|
||||
|
||||
#include "DisplayDriverPainter.h"
|
||||
|
||||
// make_rect_valid
|
||||
static inline void
|
||||
make_rect_valid(BRect& rect)
|
||||
{
|
||||
if (rect.left > rect.right) {
|
||||
float temp = rect.left;
|
||||
rect.left = rect.right;
|
||||
rect.right = temp;
|
||||
}
|
||||
if (rect.top > rect.bottom) {
|
||||
float temp = rect.top;
|
||||
rect.top = rect.bottom;
|
||||
rect.bottom = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// extend_by_stroke_width
|
||||
static inline void
|
||||
extend_by_stroke_width(BRect& rect, const DrawData* context)
|
||||
{
|
||||
// "- 1.0" because if stroke width == 1, we don't need to extend
|
||||
float inset = -ceilf(context->PenSize() / 2.0 - 1.0);
|
||||
rect.InsetBy(inset, inset);
|
||||
}
|
||||
|
||||
// constructor
|
||||
DisplayDriverPainter::DisplayDriverPainter(HWInterface* hwInterface)
|
||||
DisplayDriverPainter::DisplayDriverPainter(HWInterface* interface)
|
||||
: DisplayDriver(),
|
||||
fPainter(new Painter()),
|
||||
fGraphicsCard(hwInterface),
|
||||
fGraphicsCard(interface),
|
||||
fAvailableHWAccleration(0)
|
||||
{
|
||||
}
|
||||
@@ -70,6 +95,13 @@ DisplayDriverPainter::Update()
|
||||
}
|
||||
}
|
||||
|
||||
// SetHWInterface
|
||||
void
|
||||
DisplayDriverPainter::SetHWInterface(HWInterface* interface)
|
||||
{
|
||||
fGraphicsCard = interface;
|
||||
}
|
||||
|
||||
// ConstrainClippingRegion
|
||||
void DisplayDriverPainter::ConstrainClippingRegion(BRegion *region)
|
||||
{
|
||||
@@ -350,29 +382,26 @@ DisplayDriverPainter::CopyRegionList(BList* list, BList* pList,
|
||||
|
||||
// InvertRect
|
||||
void
|
||||
DisplayDriverPainter::InvertRect(const BRect &r)
|
||||
DisplayDriverPainter::InvertRect(BRect 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 vr(min_c(r.left, r.right),
|
||||
min_c(r.top, r.bottom),
|
||||
max_c(r.left, r.right),
|
||||
max_c(r.top, r.bottom));
|
||||
vr = fPainter->ClipRect(vr);
|
||||
if (vr.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
make_rect_valid(r);
|
||||
r = fPainter->ClipRect(r);
|
||||
if (r.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
// try hardware optimized version first
|
||||
if (fAvailableHWAccleration & HW_ACC_INVERT_REGION) {
|
||||
BRegion region(vr);
|
||||
BRegion region(r);
|
||||
region.IntersectWith(fPainter->ClippingRegion());
|
||||
fGraphicsCard->InvertRegion(region);
|
||||
} else {
|
||||
fPainter->InvertRect(vr);
|
||||
fPainter->InvertRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(vr);
|
||||
fGraphicsCard->Invalidate(r);
|
||||
}
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
@@ -390,13 +419,15 @@ DisplayDriverPainter::DrawBitmap(ServerBitmap *bitmap,
|
||||
{
|
||||
if (Lock()) {
|
||||
BRect clipped = fPainter->ClipRect(dest);
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->DrawBitmap(bitmap, source, dest);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->DrawBitmap(bitmap, source, dest);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -404,23 +435,27 @@ DisplayDriverPainter::DrawBitmap(ServerBitmap *bitmap,
|
||||
|
||||
// FillArc
|
||||
void
|
||||
DisplayDriverPainter::FillArc(const BRect &r, const float &angle,
|
||||
DisplayDriverPainter::FillArc(BRect r, const float &angle,
|
||||
const float &span, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Width() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
BRect touched = fPainter->FillArc(center, xRadius, yRadius, angle, span);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Width() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
fPainter->FillArc(center, xRadius, yRadius, angle, span);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -446,22 +481,26 @@ DisplayDriverPainter::FillBezier(BPoint *pts, const DrawData *d)
|
||||
|
||||
// FillEllipse
|
||||
void
|
||||
DisplayDriverPainter::FillEllipse(const BRect &r, const DrawData *d)
|
||||
DisplayDriverPainter::FillEllipse(BRect r, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Height() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
BRect touched = fPainter->FillEllipse(center, xRadius, yRadius);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Height() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
fPainter->FillEllipse(center, xRadius, yRadius);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -470,16 +509,20 @@ DisplayDriverPainter::FillEllipse(const BRect &r, const DrawData *d)
|
||||
// FillPolygon
|
||||
void
|
||||
DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
|
||||
const BRect &bounds, const DrawData *d)
|
||||
BRect bounds, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
make_rect_valid(bounds);
|
||||
BRect clipped = fPainter->ClipRect(bounds);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillPolygon(ptlist, numpts);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->FillPolygon(ptlist, numpts);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -487,29 +530,26 @@ DisplayDriverPainter::FillPolygon(BPoint *ptlist, int32 numpts,
|
||||
|
||||
// FillRect
|
||||
void
|
||||
DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color)
|
||||
DisplayDriverPainter::FillRect(BRect r, const RGBColor& color)
|
||||
{
|
||||
// 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 vr(min_c(r.left, r.right),
|
||||
min_c(r.top, r.bottom),
|
||||
max_c(r.left, r.right),
|
||||
max_c(r.top, r.bottom));
|
||||
vr = fPainter->ClipRect(vr);
|
||||
if (vr.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
make_rect_valid(r);
|
||||
r = fPainter->ClipRect(r);
|
||||
if (r.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
// try hardware optimized version first
|
||||
if (fAvailableHWAccleration & HW_ACC_FILL_REGION) {
|
||||
BRegion region(vr);
|
||||
BRegion region(r);
|
||||
region.IntersectWith(fPainter->ClippingRegion());
|
||||
fGraphicsCard->FillRegion(region, color);
|
||||
} else {
|
||||
fPainter->FillRect(vr, color.GetColor32());
|
||||
fPainter->FillRect(r, color.GetColor32());
|
||||
|
||||
fGraphicsCard->Invalidate(vr);
|
||||
fGraphicsCard->Invalidate(r);
|
||||
}
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
@@ -521,19 +561,16 @@ DisplayDriverPainter::FillRect(const BRect& r, const RGBColor& color)
|
||||
|
||||
// FillRect
|
||||
void
|
||||
DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
|
||||
DisplayDriverPainter::FillRect(BRect r, const DrawData *d)
|
||||
{
|
||||
// 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 vr(min_c(r.left, r.right),
|
||||
min_c(r.top, r.bottom),
|
||||
max_c(r.left, r.right),
|
||||
max_c(r.top, r.bottom));
|
||||
vr = fPainter->ClipRect(vr);
|
||||
if (vr.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
make_rect_valid(r);
|
||||
r = fPainter->ClipRect(r);
|
||||
if (r.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
bool doInSoftware = true;
|
||||
// try hardware optimized version first
|
||||
@@ -542,12 +579,12 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
|
||||
d->GetDrawingMode() == B_OP_OVER)) {
|
||||
|
||||
if (d->GetPattern() == B_SOLID_HIGH) {
|
||||
BRegion region(vr);
|
||||
BRegion region(r);
|
||||
region.IntersectWith(fPainter->ClippingRegion());
|
||||
fGraphicsCard->FillRegion(region, d->HighColor());
|
||||
doInSoftware = false;
|
||||
} else if (d->GetPattern() == B_SOLID_LOW) {
|
||||
BRegion region(vr);
|
||||
BRegion region(r);
|
||||
region.IntersectWith(fPainter->ClippingRegion());
|
||||
fGraphicsCard->FillRegion(region, d->LowColor());
|
||||
doInSoftware = false;
|
||||
@@ -556,9 +593,9 @@ DisplayDriverPainter::FillRect(const BRect &r, const DrawData *d)
|
||||
if (doInSoftware) {
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillRect(vr);
|
||||
fPainter->FillRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->Invalidate(r);
|
||||
}
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
@@ -576,57 +613,63 @@ DisplayDriverPainter::FillRegion(BRegion& r, const DrawData *d)
|
||||
// This needs to be investigated, I'm doing this because of
|
||||
// gut feeling.
|
||||
if (WriteLock()) {
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(fPainter->ClipRect(r.Frame()));
|
||||
|
||||
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 (d->GetPattern() == B_SOLID_HIGH) {
|
||||
fGraphicsCard->FillRegion(r, d->HighColor());
|
||||
doInSoftware = false;
|
||||
} else if (d->GetPattern() == B_SOLID_LOW) {
|
||||
fGraphicsCard->FillRegion(r, d->LowColor());
|
||||
doInSoftware = false;
|
||||
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 (d->GetPattern() == B_SOLID_HIGH) {
|
||||
fGraphicsCard->FillRegion(r, d->HighColor());
|
||||
doInSoftware = false;
|
||||
} else if (d->GetPattern() == B_SOLID_LOW) {
|
||||
fGraphicsCard->FillRegion(r, d->LowColor());
|
||||
doInSoftware = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doInSoftware) {
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
if (doInSoftware) {
|
||||
|
||||
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));
|
||||
fPainter->SetDrawData(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->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
|
||||
WriteUnlock();
|
||||
}
|
||||
}
|
||||
|
||||
// FillRoundRect
|
||||
void
|
||||
DisplayDriverPainter::FillRoundRect(const BRect &r,
|
||||
DisplayDriverPainter::FillRoundRect(BRect r,
|
||||
const float &xrad, const float &yrad,
|
||||
const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -649,17 +692,20 @@ printf("DisplayDriverPainter::FillShape() - what is this stuff that gets passed
|
||||
|
||||
// FillTriangle
|
||||
void
|
||||
DisplayDriverPainter::FillTriangle(BPoint *pts, const BRect &bounds,
|
||||
DisplayDriverPainter::FillTriangle(BPoint *pts, BRect bounds,
|
||||
const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->FillTriangle(pts[0], pts[1], pts[2]);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
bounds = fPainter->ClipRect(bounds);
|
||||
if (bounds.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(bounds);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->FillTriangle(pts[0], pts[1], pts[2]);
|
||||
|
||||
fGraphicsCard->Invalidate(bounds);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -667,23 +713,27 @@ DisplayDriverPainter::FillTriangle(BPoint *pts, const BRect &bounds,
|
||||
|
||||
// StrokeArc
|
||||
void
|
||||
DisplayDriverPainter::StrokeArc(const BRect &r, const float &angle,
|
||||
DisplayDriverPainter::StrokeArc(BRect r, const float &angle,
|
||||
const float &span, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Width() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
BRect touched = fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Width() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
fPainter->StrokeArc(center, xRadius, yRadius, angle, span);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -708,22 +758,28 @@ DisplayDriverPainter::StrokeBezier(BPoint *pts, const DrawData *d)
|
||||
|
||||
// StrokeEllipse
|
||||
void
|
||||
DisplayDriverPainter::StrokeEllipse(const BRect &r, const DrawData *d)
|
||||
DisplayDriverPainter::StrokeEllipse(BRect r, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Height() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
BRect touched = fPainter->StrokeEllipse(center, xRadius, yRadius);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped = r;
|
||||
extend_by_stroke_width(clipped, d);
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(r);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
|
||||
float xRadius = r.Width() / 2.0;
|
||||
float yRadius = r.Height() / 2.0;
|
||||
BPoint center(r.left + xRadius,
|
||||
r.top + yRadius);
|
||||
|
||||
fPainter->StrokeEllipse(center, xRadius, yRadius);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -737,10 +793,8 @@ void
|
||||
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, const RGBColor &color)
|
||||
{
|
||||
if (Lock()) {
|
||||
BRect touched(min_c(start.x, end.x),
|
||||
min_c(start.y, end.y),
|
||||
max_c(start.x, end.x),
|
||||
max_c(start.y, end.y));
|
||||
BRect touched(start, end);
|
||||
make_rect_valid(touched);
|
||||
touched = fPainter->ClipRect(touched);
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
@@ -762,17 +816,18 @@ void
|
||||
DisplayDriverPainter::StrokeLine(const BPoint &start, const BPoint &end, DrawData* context)
|
||||
{
|
||||
if (Lock()) {
|
||||
BRect touched(min_c(start.x, end.x),
|
||||
min_c(start.y, end.y),
|
||||
max_c(start.x, end.x),
|
||||
max_c(start.y, end.y));
|
||||
BRect touched(start, end);
|
||||
make_rect_valid(touched);
|
||||
extend_by_stroke_width(touched, context);
|
||||
touched = fPainter->ClipRect(touched);
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
touched = fPainter->StrokeLine(start, end, context);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
if (touched.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
touched = fPainter->StrokeLine(start, end, context);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -788,24 +843,41 @@ DisplayDriverPainter::StrokeLineArray(const int32 &numlines,
|
||||
return;
|
||||
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
DrawData context;
|
||||
context.SetDrawingMode(B_OP_COPY);
|
||||
const LineArrayData *data;
|
||||
|
||||
data = (const LineArrayData *)&(linedata[0]);
|
||||
context.SetHighColor(data->color);
|
||||
BRect touched = fPainter->StrokeLine(data->pt1, data->pt2, &context);
|
||||
|
||||
// figure out bounding box for line array
|
||||
const LineArrayData *data = (const LineArrayData *)&(linedata[0]);
|
||||
BRect touched(min_c(data->pt1.x, data->pt2.x),
|
||||
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++) {
|
||||
data = (const LineArrayData *)&(linedata[i]);
|
||||
context.SetHighColor(data->color);
|
||||
touched = touched | fPainter->StrokeLine(data->pt1, data->pt2, &context);
|
||||
BRect box(min_c(data->pt1.x, data->pt2.x),
|
||||
min_c(data->pt1.y, data->pt2.y),
|
||||
max_c(data->pt1.x, data->pt2.x),
|
||||
max_c(data->pt1.y, data->pt2.y));
|
||||
touched = touched | box;
|
||||
}
|
||||
extend_by_stroke_width(touched, d);
|
||||
touched = fPainter->ClipRect(touched);
|
||||
if (touched.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(touched);
|
||||
|
||||
DrawData 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++) {
|
||||
data = (const LineArrayData *)&(linedata[i]);
|
||||
context.SetHighColor(data->color);
|
||||
fPainter->StrokeLine(data->pt1, data->pt2, &context);
|
||||
}
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -829,18 +901,22 @@ DisplayDriverPainter::StrokePoint(const BPoint& pt, DrawData *context)
|
||||
|
||||
// StrokePolygon
|
||||
void
|
||||
DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts,
|
||||
const BRect &bounds, const DrawData *d,
|
||||
DisplayDriverPainter::StrokePolygon(BPoint* ptlist, int32 numpts,
|
||||
BRect bounds, const DrawData* d,
|
||||
bool closed)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->StrokePolygon(ptlist, numpts, closed);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
extend_by_stroke_width(bounds, d);
|
||||
bounds = fPainter->ClipRect(bounds);
|
||||
if (bounds.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(bounds);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->StrokePolygon(ptlist, numpts, closed);
|
||||
|
||||
fGraphicsCard->Invalidate(bounds);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -850,29 +926,27 @@ DisplayDriverPainter::StrokePolygon(BPoint *ptlist, int32 numpts,
|
||||
//
|
||||
// this function is used to draw a one pixel wide rect
|
||||
void
|
||||
DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
||||
DisplayDriverPainter::StrokeRect(BRect r, const RGBColor &color)
|
||||
{
|
||||
if (Lock()) {
|
||||
// support invalid rects
|
||||
BRect vr(min_c(r.left, r.right),
|
||||
min_c(r.top, r.bottom),
|
||||
max_c(r.left, r.right),
|
||||
max_c(r.top, r.bottom));
|
||||
make_rect_valid(r);
|
||||
BRect clipped = fPainter->ClipRect(r);
|
||||
if (clipped.IsValid()) {
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
|
||||
fPainter->StrokeRect(vr, color.GetColor32());
|
||||
|
||||
/* fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.top,
|
||||
vr.right, vr.top)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.top + 1,
|
||||
vr.left, vr.bottom - 1)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.right, vr.top + 1,
|
||||
vr.right, vr.bottom - 1)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(vr.left, vr.bottom,
|
||||
vr.right, vr.bottom)));*/
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(vr));
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->StrokeRect(r, color.GetColor32());
|
||||
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top,
|
||||
r.right, r.top)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.top + 1,
|
||||
r.left, r.bottom - 1)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.right, r.top + 1,
|
||||
r.right, r.bottom - 1)));
|
||||
fGraphicsCard->Invalidate(fPainter->ClipRect(BRect(r.left, r.bottom,
|
||||
r.right, r.bottom)));
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -880,24 +954,24 @@ DisplayDriverPainter::StrokeRect(const BRect &r, const RGBColor &color)
|
||||
|
||||
// StrokeRect
|
||||
void
|
||||
DisplayDriverPainter::StrokeRect(const BRect &r, const DrawData *d)
|
||||
DisplayDriverPainter::StrokeRect(BRect r, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
// support invalid rects
|
||||
BRect vr(min_c(r.left, r.right),
|
||||
min_c(r.top, r.bottom),
|
||||
max_c(r.left, r.right),
|
||||
max_c(r.top, r.bottom));
|
||||
float extend = -ceilf(d->PenSize() / 2.0);
|
||||
vr.InsetBy(extend, extend);
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(vr);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->StrokeRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
make_rect_valid(r);
|
||||
BRect clipped(r);
|
||||
extend_by_stroke_width(clipped, d);
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->StrokeRect(r);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -908,37 +982,48 @@ void
|
||||
DisplayDriverPainter::StrokeRegion(BRegion& r, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(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));
|
||||
BRect clipped(r.Frame());
|
||||
extend_by_stroke_width(clipped, d);
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(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();
|
||||
}
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
// StrokeRoundRect
|
||||
void
|
||||
DisplayDriverPainter::StrokeRoundRect(const BRect &r, const float &xrad,
|
||||
DisplayDriverPainter::StrokeRoundRect(BRect r, const float &xrad,
|
||||
const float &yrad, const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->StrokeRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
// 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->SetDrawData(d);
|
||||
BRect touched = fPainter->StrokeRoundRect(r, xrad, yrad);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
@@ -964,18 +1049,23 @@ DisplayDriverPainter::StrokeTriangle(BPoint *pts, const BRect &bounds,
|
||||
const DrawData *d)
|
||||
{
|
||||
if (Lock()) {
|
||||
fGraphicsCard->HideSoftwareCursor();
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
BRect touched = fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
|
||||
|
||||
fGraphicsCard->Invalidate(touched);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
BRect clipped(bounds);
|
||||
extend_by_stroke_width(clipped, d);
|
||||
clipped = fPainter->ClipRect(clipped);
|
||||
if (clipped.IsValid()) {
|
||||
fGraphicsCard->HideSoftwareCursor(clipped);
|
||||
|
||||
fPainter->SetDrawData(d);
|
||||
fPainter->StrokeTriangle(pts[0], pts[1], pts[2]);
|
||||
|
||||
fGraphicsCard->Invalidate(clipped);
|
||||
fGraphicsCard->ShowSoftwareCursor();
|
||||
}
|
||||
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// DrawString
|
||||
void
|
||||
DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
@@ -985,18 +1075,16 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
static DrawData d;
|
||||
d.SetHighColor(color);
|
||||
|
||||
// TODO: Why is escapement_delta a part of the state stack?
|
||||
if (delta)
|
||||
d.SetEscapementDelta(*delta);
|
||||
|
||||
DrawString(string, length, pt, &d);
|
||||
}
|
||||
|
||||
*/
|
||||
// DrawString
|
||||
void
|
||||
DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
const BPoint &pt, DrawData *d)
|
||||
DisplayDriverPainter::DrawString(const char* string, int32 length,
|
||||
const BPoint& pt, DrawData* d,
|
||||
escapement_delta* delta)
|
||||
{
|
||||
// TODO: use delta
|
||||
if (Lock()) {
|
||||
fPainter->SetDrawData(d);
|
||||
//bigtime_t now = system_time();
|
||||
@@ -1007,7 +1095,8 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
// in case we don't have one.
|
||||
BRect b = fPainter->BoundingBox(string, length, pt);
|
||||
// stop here if we're supposed to render outside of the clipping
|
||||
if (fPainter->ClippingRegion()->Frame().Intersects(b)) {
|
||||
b = fPainter->ClipRect(b);
|
||||
if (b.IsValid()) {
|
||||
//printf("bounding box '%s': %lld µs\n", string, system_time() - now);
|
||||
fGraphicsCard->HideSoftwareCursor(b);
|
||||
|
||||
@@ -1024,9 +1113,11 @@ DisplayDriverPainter::DrawString(const char *string, const int32 &length,
|
||||
|
||||
// StringWidth
|
||||
float
|
||||
DisplayDriverPainter::StringWidth(const char *string, int32 length,
|
||||
const DrawData *d)
|
||||
DisplayDriverPainter::StringWidth(const char* string, int32 length,
|
||||
const DrawData* d,
|
||||
escapement_delta* delta)
|
||||
{
|
||||
// TODO: use delta
|
||||
float width = 0.0;
|
||||
if (Lock()) {
|
||||
fPainter->SetDrawData(d);
|
||||
@@ -1038,9 +1129,11 @@ DisplayDriverPainter::StringWidth(const char *string, int32 length,
|
||||
|
||||
// StringWidth
|
||||
float
|
||||
DisplayDriverPainter::StringWidth(const char *string, int32 length,
|
||||
const ServerFont &font)
|
||||
DisplayDriverPainter::StringWidth(const char* string, int32 length,
|
||||
const ServerFont& font,
|
||||
escapement_delta* delta)
|
||||
{
|
||||
// TODO: use delta
|
||||
static DrawData d;
|
||||
d.SetFont(font);
|
||||
return StringWidth(string, length, &d);
|
||||
|
||||
@@ -16,12 +16,11 @@
|
||||
|
||||
#include "DisplayDriver.h"
|
||||
|
||||
class HWInterface;
|
||||
class Painter;
|
||||
|
||||
class DisplayDriverPainter : public DisplayDriver {
|
||||
public:
|
||||
DisplayDriverPainter(HWInterface* hwInterface);
|
||||
DisplayDriverPainter(HWInterface* interface = NULL);
|
||||
virtual ~DisplayDriverPainter();
|
||||
|
||||
// when implementing, be sure to call the inherited version
|
||||
@@ -30,6 +29,8 @@ public:
|
||||
|
||||
virtual void Update();
|
||||
|
||||
virtual void SetHWInterface(HWInterface* interface);
|
||||
|
||||
// clipping for all drawing functions, passing a NULL region
|
||||
// will remove any clipping (drawing allowed everywhere)
|
||||
virtual void ConstrainClippingRegion(BRegion* region);
|
||||
@@ -44,14 +45,14 @@ public:
|
||||
int32 rCount,
|
||||
BRegion* clipReg);
|
||||
|
||||
virtual void InvertRect( const BRect &r);
|
||||
virtual void InvertRect( BRect r);
|
||||
|
||||
virtual void DrawBitmap( ServerBitmap *bitmap,
|
||||
const BRect &source,
|
||||
const BRect &dest,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillArc( const BRect &r,
|
||||
virtual void FillArc( BRect r,
|
||||
const float &angle,
|
||||
const float &span,
|
||||
const DrawData *d);
|
||||
@@ -59,24 +60,24 @@ public:
|
||||
virtual void FillBezier( BPoint *pts,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillEllipse( const BRect &r,
|
||||
virtual void FillEllipse( BRect r,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillPolygon( BPoint *ptlist,
|
||||
int32 numpts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillRect( const BRect &r,
|
||||
virtual void FillRect( BRect r,
|
||||
const RGBColor &color);
|
||||
|
||||
virtual void FillRect( const BRect &r,
|
||||
virtual void FillRect( BRect r,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillRegion( BRegion &r,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillRoundRect( const BRect &r,
|
||||
virtual void FillRoundRect( BRect r,
|
||||
const float &xrad,
|
||||
const float &yrad,
|
||||
const DrawData *d);
|
||||
@@ -89,10 +90,10 @@ public:
|
||||
const DrawData *d);
|
||||
|
||||
virtual void FillTriangle( BPoint *pts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void StrokeArc( const BRect &r,
|
||||
virtual void StrokeArc( BRect r,
|
||||
const float &angle,
|
||||
const float &span,
|
||||
const DrawData *d);
|
||||
@@ -100,7 +101,7 @@ public:
|
||||
virtual void StrokeBezier( BPoint *pts,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void StrokeEllipse( const BRect &r,
|
||||
virtual void StrokeEllipse( BRect r,
|
||||
const DrawData *d);
|
||||
|
||||
// this version used by Decorator
|
||||
@@ -125,21 +126,21 @@ public:
|
||||
|
||||
virtual void StrokePolygon( BPoint *ptlist,
|
||||
int32 numpts,
|
||||
const BRect &bounds,
|
||||
BRect bounds,
|
||||
const DrawData *d,
|
||||
bool is_closed=true);
|
||||
|
||||
// this version used by Decorator
|
||||
virtual void StrokeRect( const BRect &r,
|
||||
virtual void StrokeRect( BRect r,
|
||||
const RGBColor &color);
|
||||
|
||||
virtual void StrokeRect( const BRect &r,
|
||||
virtual void StrokeRect( BRect r,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void StrokeRegion( BRegion &r,
|
||||
const DrawData *d);
|
||||
|
||||
virtual void StrokeRoundRect(const BRect &r,
|
||||
virtual void StrokeRoundRect(BRect r,
|
||||
const float &xrad,
|
||||
const float &yrad,
|
||||
const DrawData *d);
|
||||
@@ -158,28 +159,31 @@ public:
|
||||
// Font-related calls
|
||||
|
||||
// DrawData is NOT const because this call updates the pen position in the passed DrawData
|
||||
virtual void DrawString( const char *string,
|
||||
const int32 &length,
|
||||
const BPoint &pt,
|
||||
DrawData *d);
|
||||
virtual void DrawString( const char* string,
|
||||
int32 length,
|
||||
const BPoint& pt,
|
||||
DrawData* d,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
virtual void DrawString( const char *string,
|
||||
/* virtual void DrawString( const char *string,
|
||||
const int32 &length,
|
||||
const BPoint &pt,
|
||||
const RGBColor &color,
|
||||
escapement_delta *delta=NULL);
|
||||
escapement_delta *delta=NULL);*/
|
||||
|
||||
virtual float StringWidth( const char *string,
|
||||
virtual float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const DrawData *d);
|
||||
const DrawData* d,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
virtual float StringWidth( const char *string,
|
||||
virtual float StringWidth( const char* string,
|
||||
int32 length,
|
||||
const ServerFont &font);
|
||||
const ServerFont& font,
|
||||
escapement_delta* delta = NULL);
|
||||
|
||||
virtual float StringHeight( const char *string,
|
||||
virtual float StringHeight( const char* string,
|
||||
int32 length,
|
||||
const DrawData *d);
|
||||
const DrawData* d);
|
||||
|
||||
virtual bool Lock();
|
||||
virtual void Unlock();
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __HAIKU__
|
||||
#include <Screen.h>
|
||||
#endif
|
||||
|
||||
#include "RenderingBuffer.h"
|
||||
#include "ServerCursor.h"
|
||||
#include "SystemPalette.h"
|
||||
#include "UpdateQueue.h"
|
||||
|
||||
#include "HWInterface.h"
|
||||
@@ -176,7 +173,7 @@ HWInterface::CopyBackToFront(const BRect& frame)
|
||||
|
||||
// we need to mess with the area, but it is const
|
||||
BRect area(frame);
|
||||
BRect bufferClip(0.0, 0.0, backBuffer->Width() - 1, backBuffer->Height() - 1);
|
||||
BRect bufferClip(backBuffer->Bounds());
|
||||
|
||||
if (area.IsValid() && area.Intersects(bufferClip)) {
|
||||
|
||||
@@ -213,6 +210,8 @@ HWInterface::HideSoftwareCursor(const BRect& area)
|
||||
fCursorAreaBackup->right,
|
||||
fCursorAreaBackup->bottom);
|
||||
if (area.Intersects(backupArea)) {
|
||||
//printf("HideSoftwareCursor(BRect(%.1, %.1, %.1, %.1))\n", area.left, area.top, area.right, area.bottom);
|
||||
//backupArea.PrintToStream();
|
||||
_RestoreCursorArea(backupArea);
|
||||
fSoftwareCursorHidden = true;
|
||||
}
|
||||
@@ -224,6 +223,7 @@ void
|
||||
HWInterface::HideSoftwareCursor()
|
||||
{
|
||||
if (fCursorAreaBackup && !fSoftwareCursorHidden) {
|
||||
//printf("HideSoftwareCursor()\n");
|
||||
_RestoreCursorArea(BRect(fCursorAreaBackup->left,
|
||||
fCursorAreaBackup->top,
|
||||
fCursorAreaBackup->right,
|
||||
@@ -237,6 +237,7 @@ void
|
||||
HWInterface::ShowSoftwareCursor()
|
||||
{
|
||||
if (fCursorAreaBackup && fSoftwareCursorHidden) {
|
||||
//printf("ShowSoftwareCursor()\n");
|
||||
_DrawCursor(_CursorFrame());
|
||||
fSoftwareCursorHidden = false;
|
||||
}
|
||||
@@ -258,8 +259,7 @@ HWInterface::_DrawCursor(BRect area) const
|
||||
BRect cf = _CursorFrame();
|
||||
|
||||
// make sure we don't copy out of bounds
|
||||
BRect bufferClip(0.0, 0.0, backBuffer->Width() - 1, backBuffer->Height() - 1);
|
||||
area = bufferClip & area;
|
||||
area = backBuffer->Bounds() & area;
|
||||
|
||||
if (cf.IsValid() && area.Intersects(cf)) {
|
||||
// clip to common area
|
||||
@@ -545,35 +545,26 @@ HWInterface::_CopyToFront(uint8* src, uint32 srcBPR,
|
||||
break;
|
||||
}
|
||||
case B_CMAP8: {
|
||||
// TODO: make this work on Haiku, the problem is only
|
||||
// the rgb_color->index mapping, there is an implementation
|
||||
// in Bitmap.cpp, maybe it needs to be moved to a public
|
||||
// place...
|
||||
#ifndef __HAIKU__
|
||||
const color_map *colorMap = SystemColorMap();
|
||||
// offset to left top pixel in dest buffer
|
||||
dst += y * dstBPR + x;
|
||||
int32 left = x;
|
||||
uint16 index;
|
||||
// copy
|
||||
// TODO: using BScreen will not be an option in the
|
||||
// final implementation, will it? The BBitmap implementation
|
||||
// has a class that handles this, something so useful
|
||||
// should be moved to a more public place.
|
||||
// TODO: assumes BGR order again
|
||||
BScreen screen;
|
||||
for (; y <= bottom; y++) {
|
||||
uint8* srcHandle = src;
|
||||
uint8* dstHandle = dst;
|
||||
for (x = left; x <= right; x++) {
|
||||
*dstHandle = screen.IndexForColor(srcHandle[2],
|
||||
srcHandle[1],
|
||||
srcHandle[0]);
|
||||
index = ((srcHandle[2] & 0xf8) << 7) | ((srcHandle[1] & 0xf8) << 2) | (srcHandle[1] >> 3);
|
||||
*dstHandle = colorMap->index_map[index];
|
||||
dstHandle ++;
|
||||
srcHandle += 4;
|
||||
}
|
||||
dst += dstBPR;
|
||||
src += srcBPR;
|
||||
}
|
||||
#endif // __HAIKU__
|
||||
|
||||
break;
|
||||
}
|
||||
case B_GRAY8: {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
//
|
||||
// Copyright 2005, Stephan Aßmus <[email protected]>
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright 2005, Haiku, Inc. All rights reserved.
|
||||
// Distributed under the terms of the MIT License.
|
||||
//
|
||||
// Contains an abstract base class HWInterface that provides the
|
||||
// basic functionality for frame buffer acces in the DisplayDriverPainter
|
||||
// implementation.
|
||||
// Author: Stephan Aßmus, <[email protected]>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef HW_INTERFACE_H
|
||||
#define HW_INTERFACE_H
|
||||
|
||||
@@ -175,15 +175,18 @@ Painter::DetachFromBuffer()
|
||||
void
|
||||
Painter::SetDrawData(const DrawData* data)
|
||||
{
|
||||
// for now...
|
||||
// NOTE: The custom clipping in "data" is ignored, because it has already been
|
||||
// taken into account elsewhere
|
||||
|
||||
// TODO: optimize "context switch" for speed...
|
||||
// but for now...
|
||||
SetPenSize(data->PenSize());
|
||||
SetPenLocation(data->PenLocation());
|
||||
SetFont(data->Font());
|
||||
// fTextRenderer->SetAntialiasing(data->FontAntiAliasing());
|
||||
fTextRenderer->SetAntialiasing(!(data->Font().Flags() & B_DISABLE_ANTIALIASING));
|
||||
// if (data->clipReg) {
|
||||
// ConstrainClipping(*data->clipReg);
|
||||
// }
|
||||
fTextRenderer->SetAntialiasing(!(data->ForceFontAliasing() || data->Font().Flags() & B_DISABLE_ANTIALIASING));
|
||||
|
||||
fSubpixelPrecise = data->SubPixelPrecise();
|
||||
|
||||
// any of these conditions means we need to use a different drawing
|
||||
// mode instance
|
||||
bool updateDrawingMode = !(data->GetPattern() == fPatternHandler->GetPattern()) ||
|
||||
@@ -1482,6 +1485,12 @@ Painter::_StrokePath(VertexSource& path) const
|
||||
// stroke.line_cap(agg::butt_cap);
|
||||
stroke.width(fPenSize);
|
||||
|
||||
// special case line width = 1 with square caps
|
||||
// this has a couple of advantages and it looks
|
||||
// like this is also the R5 behaviour.
|
||||
if (fPenSize == 1.0)
|
||||
stroke.line_cap(agg::square_cap);
|
||||
|
||||
fRasterizer->reset();
|
||||
fRasterizer->add_path(stroke);
|
||||
agg::render_scanlines(*fRasterizer, *fScanline, *fRenderer);
|
||||
|
||||
@@ -83,11 +83,6 @@ class Painter {
|
||||
void SetPenLocation(const BPoint& location);
|
||||
void SetFont(const ServerFont& font);
|
||||
|
||||
// BView API compatibility (for easier testing)
|
||||
void Sync() {}
|
||||
inline void MovePenTo(const BPoint& location)
|
||||
{ SetPenLocation(location); }
|
||||
|
||||
// painting functions
|
||||
|
||||
// lines
|
||||
@@ -98,7 +93,7 @@ class Painter {
|
||||
BRect StrokeLine( BPoint b,
|
||||
DrawData* context);
|
||||
|
||||
// return true if the line was either vertical or horizontal
|
||||
// returns true if the line was either vertical or horizontal
|
||||
// draws a solid one pixel wide line of color c, no blending
|
||||
bool StraightLine( BPoint a,
|
||||
BPoint b,
|
||||
@@ -288,8 +283,7 @@ class Painter {
|
||||
|
||||
agg::line_profile_aa fLineProfile;
|
||||
|
||||
// for internal coordinate rounding/transformation,
|
||||
// does not concern rendering
|
||||
// for internal coordinate rounding/transformation
|
||||
bool fSubpixelPrecise;
|
||||
|
||||
float fPenSize;
|
||||
@@ -306,8 +300,7 @@ class Painter {
|
||||
ServerFont fFont;
|
||||
// a class handling rendering and caching of glyphs
|
||||
// it is setup to load from a specific Freetype supported
|
||||
// font file, it uses the FontManager to locate a file
|
||||
// by Family and Style
|
||||
// font file which it gets from ServerFont
|
||||
AGGTextRenderer* fTextRenderer;
|
||||
};
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// ViewBitmapBuffer.h
|
||||
|
||||
#include <Bitmap.h>
|
||||
|
||||
#include "ViewBitmapBuffer.h"
|
||||
|
||||
// constructor
|
||||
ViewBitmapBuffer::ViewBitmapBuffer(BBitmap* bitmap)
|
||||
: fBitmap(bitmap)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
ViewBitmapBuffer::~ViewBitmapBuffer()
|
||||
{
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
ViewBitmapBuffer::InitCheck() const
|
||||
{
|
||||
status_t ret = B_NO_INIT;
|
||||
if (fBitmap)
|
||||
ret = fBitmap->InitCheck();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ColorSpace
|
||||
color_space
|
||||
ViewBitmapBuffer::ColorSpace() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->ColorSpace();
|
||||
return B_NO_COLOR_SPACE;
|
||||
}
|
||||
|
||||
// Bits
|
||||
void*
|
||||
ViewBitmapBuffer::Bits() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->Bits();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// BytesPerRow
|
||||
uint32
|
||||
ViewBitmapBuffer::BytesPerRow() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->BytesPerRow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Width
|
||||
uint32
|
||||
ViewBitmapBuffer::Width() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->Bounds().IntegerWidth() + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Height
|
||||
uint32
|
||||
ViewBitmapBuffer::Height() const
|
||||
{
|
||||
if (InitCheck() >= B_OK)
|
||||
return fBitmap->Bounds().IntegerHeight() + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// ViewBitmapBuffer.h
|
||||
|
||||
#ifndef VIEW_BITMAP_BUFFER_H
|
||||
#define VIEW_BITMAP_BUFFER_H
|
||||
|
||||
#include "RenderingBuffer.h"
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class ViewBitmapBuffer : public RenderingBuffer {
|
||||
public:
|
||||
ViewBitmapBuffer(BBitmap* bitmap);
|
||||
virtual ~ViewBitmapBuffer();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual void* Bits() const;
|
||||
virtual uint32 BytesPerRow() const;
|
||||
virtual uint32 Width() const;
|
||||
virtual uint32 Height() const;
|
||||
|
||||
// ViewBitmapBuffer
|
||||
const BBitmap* Bitmap() const
|
||||
{ return fBitmap; }
|
||||
private:
|
||||
|
||||
BBitmap* fBitmap;
|
||||
};
|
||||
|
||||
#endif // VIEW_BITMAP_BUFFER_H
|
||||
@@ -299,8 +299,8 @@ STRACE("MSG_UPDATE\n");
|
||||
}*/
|
||||
BRect frame = fUpdateRegion.Frame();
|
||||
if (frame.IsValid()) {
|
||||
// fView->Invalidate(frame);
|
||||
fView->Invalidate();
|
||||
fView->Invalidate(frame);
|
||||
// fView->Invalidate();
|
||||
}
|
||||
fUpdateRegion.MakeEmpty();
|
||||
fUpdateLock.Unlock();
|
||||
|
||||
Reference in New Issue
Block a user