diff --git a/headers/private/servers/app/Decorator.h b/headers/private/servers/app/Decorator.h index bd044ad487..d9ebe71e4e 100644 --- a/headers/private/servers/app/Decorator.h +++ b/headers/private/servers/app/Decorator.h @@ -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); diff --git a/headers/private/servers/app/DisplayDriver.h b/headers/private/servers/app/DisplayDriver.h index 9e29d90eb3..acf3e15457 100644 --- a/headers/private/servers/app/DisplayDriver.h +++ b/headers/private/servers/app/DisplayDriver.h @@ -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, diff --git a/headers/private/servers/app/LayerData.h b/headers/private/servers/app/LayerData.h index 2924896c35..64e36dbb39 100644 --- a/headers/private/servers/app/LayerData.h +++ b/headers/private/servers/app/LayerData.h @@ -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); diff --git a/headers/private/servers/app/RenderingBuffer.h b/headers/private/servers/app/RenderingBuffer.h index 0ef31400b4..c1c706fe4f 100644 --- a/headers/private/servers/app/RenderingBuffer.h +++ b/headers/private/servers/app/RenderingBuffer.h @@ -4,6 +4,7 @@ #define RENDERING_BUFFER_H #include +#include 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 diff --git a/headers/private/servers/app/ServerConfig.h b/headers/private/servers/app/ServerConfig.h index f3e8113b59..8ef9cd9628 100644 --- a/headers/private/servers/app/ServerConfig.h +++ b/headers/private/servers/app/ServerConfig.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" diff --git a/src/servers/app/BGet++.cpp b/src/servers/app/BGet++.cpp index 1d7f22cf2c..077bcf8d26 100644 --- a/src/servers/app/BGet++.cpp +++ b/src/servers/app/BGet++.cpp @@ -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)); diff --git a/src/servers/app/DefaultDecorator.cpp b/src/servers/app/DefaultDecorator.cpp index 79f23642ed..e65425aa94 100644 --- a/src/servers/app/DefaultDecorator.cpp +++ b/src/servers/app/DefaultDecorator.cpp @@ -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); diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 1881636c2a..9219f7a175 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -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; diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 7bbd4fc197..65f8e0a0d0 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -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 diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 7e51fb6694..bf80802c6c 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -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 diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 20a1b1298d..e93cebcaaf 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -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); diff --git a/src/servers/app/LayerData.cpp b/src/servers/app/LayerData.cpp index 0fafc8c845..0a3d1c0887 100644 --- a/src/servers/app/LayerData.cpp +++ b/src/servers/app/LayerData.cpp @@ -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*)&fAlphaSrcMode); link.Read((int8*)&fAlphaFncMode); link.Read(&fScale); - link.Read(&fFontAntiAliasing); - - // TODO: ahm... which way arround? - fFontAntiAliasing = !fFontAntiAliasing; + link.Read(&fFontAliasing); fHighColor = highColor; fLowColor = lowColor; @@ -505,7 +533,7 @@ LayerData::WriteToLink(BPrivate::LinkSender& link) const link.Attach((uint8)fAlphaSrcMode); link.Attach((uint8)fAlphaFncMode); link.Attach(fScale); - link.Attach(!fFontAntiAliasing); + link.Attach(fFontAliasing); int32 clippingRectCount = fClippingRegion ? fClippingRegion->CountRects() : 0; link.Attach(clippingRectCount); diff --git a/src/servers/app/OffscreenServerWindow.cpp b/src/servers/app/OffscreenServerWindow.cpp new file mode 100644 index 0000000000..4abc54f7d3 --- /dev/null +++ b/src/servers/app/OffscreenServerWindow.cpp @@ -0,0 +1,49 @@ +/* + * Copyright 2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#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); +} diff --git a/src/servers/app/OffscreenServerWindow.h b/src/servers/app/OffscreenServerWindow.h new file mode 100644 index 0000000000..c5f1ffa92a --- /dev/null +++ b/src/servers/app/OffscreenServerWindow.h @@ -0,0 +1,37 @@ +/* + * Copyright 2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ +#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 diff --git a/src/servers/app/OffscreenWinBorder.cpp b/src/servers/app/OffscreenWinBorder.cpp new file mode 100644 index 0000000000..4ba730ca20 --- /dev/null +++ b/src/servers/app/OffscreenWinBorder.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Author: Stephan Aßmus + */ + +#include + +#include +#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 +} + diff --git a/src/servers/app/OffscreenWinBorder.h b/src/servers/app/OffscreenWinBorder.h new file mode 100644 index 0000000000..a5e3e0cbf8 --- /dev/null +++ b/src/servers/app/OffscreenWinBorder.h @@ -0,0 +1,38 @@ +/* + * Copyright 2005, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT license. + * + * Author: Stephan Aßmus + */ + +#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 diff --git a/src/servers/app/PicturePlayer.cpp b/src/servers/app/PicturePlayer.cpp index a384728497..46e1720b61 100644 --- a/src/servers/app/PicturePlayer.cpp +++ b/src/servers/app/PicturePlayer.cpp @@ -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; } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 10161907bc..524da811dd 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -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(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(&bitmapToken); + receiver.Read(&frame); + receiver.Read(&look); + receiver.Read(&feel); + receiver.Read(&flags); + receiver.Read(&workspaces); + receiver.Read(&token); + receiver.Read(&clientReplyPort); + receiver.Read(&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(&bytesPerRow); if (link.Read(&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(bitmap->Token()); fLink.Attach(bitmap->Area()); @@ -807,10 +888,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&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(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; } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 2ab1948904..8755e6ce93 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -10,6 +10,7 @@ * Axel Dörfler, axeld@pinc-software.de */ +#include #include #include @@ -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(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(&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(&mask); link.Read(&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(&(fCurrentLayer->fFlags)); + uint32 flags; + link.Read(&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(&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(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(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(&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(&noOfRects); - for(int i = 0; i < noOfRects; i++) - { + for (int i = 0; i < noOfRects; i++) { link.Read(&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(&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(&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(&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(&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(&angle); link.Read(&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(&angle); link.Read(&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(&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(&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(&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(&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, diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index e1673f2c6a..b0b3d0609e 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -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() diff --git a/src/servers/app/SystemPalette.cpp b/src/servers/app/SystemPalette.cpp index 366e34b21d..93893f0909 100644 --- a/src/servers/app/SystemPalette.cpp +++ b/src/servers/app/SystemPalette.cpp @@ -25,6 +25,8 @@ // Description: Methods to initialize and get the system color_map. // //------------------------------------------------------------------------------ +#include + #include 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); } diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index 9d3567090e..6b45de5bef 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -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); + } +} + diff --git a/src/servers/app/WinBorder.h b/src/servers/app/WinBorder.h index 3c44a908f6..7fa1963042 100644 --- a/src/servers/app/WinBorder.h +++ b/src/servers/app/WinBorder.h @@ -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; diff --git a/src/servers/app/drawing/BitmapBuffer.cpp b/src/servers/app/drawing/BitmapBuffer.cpp index 25e3103419..994e3a51e1 100644 --- a/src/servers/app/drawing/BitmapBuffer.cpp +++ b/src/servers/app/drawing/BitmapBuffer.cpp @@ -1,11 +1,15 @@ // BitmapBuffer.h -#include +#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; } diff --git a/src/servers/app/drawing/BitmapBuffer.h b/src/servers/app/drawing/BitmapBuffer.h index a90af10bbd..007700ab2b 100644 --- a/src/servers/app/drawing/BitmapBuffer.h +++ b/src/servers/app/drawing/BitmapBuffer.h @@ -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 diff --git a/src/servers/app/drawing/BitmapHWInterface.cpp b/src/servers/app/drawing/BitmapHWInterface.cpp new file mode 100644 index 0000000000..5ba6969460 --- /dev/null +++ b/src/servers/app/drawing/BitmapHWInterface.cpp @@ -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 +// DarkWyrm +// Stephan Aßmus +// Description: Accelerant based HWInterface implementation +// +//------------------------------------------------------------------------------ + +#include +#include +#include + +#include + +#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(); +} + + diff --git a/src/servers/app/drawing/BitmapHWInterface.h b/src/servers/app/drawing/BitmapHWInterface.h new file mode 100644 index 0000000000..3ae4702d0a --- /dev/null +++ b/src/servers/app/drawing/BitmapHWInterface.h @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// Copyright 2005, Haiku, Inc. All rights reserved. +// Distributed under the terms of the MIT License. +// +// Author: Stephan Aßmus, +//------------------------------------------------------------------------------ + +#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 diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index 7c1a33c90b..79137d2074 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -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); diff --git a/src/servers/app/drawing/DisplayDriverPainter.h b/src/servers/app/drawing/DisplayDriverPainter.h index e544b57496..ffad9dea7b 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.h +++ b/src/servers/app/drawing/DisplayDriverPainter.h @@ -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(); diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 1ace4b713c..f99fe4eaa2 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -3,12 +3,9 @@ #include #include -#ifndef __HAIKU__ - #include -#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: { diff --git a/src/servers/app/drawing/HWInterface.h b/src/servers/app/drawing/HWInterface.h index df0bdf276f..8e9bb7057f 100644 --- a/src/servers/app/drawing/HWInterface.h +++ b/src/servers/app/drawing/HWInterface.h @@ -1,10 +1,9 @@ -// -// Copyright 2005, Stephan Aßmus +//------------------------------------------------------------------------------ +// 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, +//------------------------------------------------------------------------------ #ifndef HW_INTERFACE_H #define HW_INTERFACE_H diff --git a/src/servers/app/drawing/Painter/Painter.cpp b/src/servers/app/drawing/Painter/Painter.cpp index 8566bec944..5dcf780d89 100644 --- a/src/servers/app/drawing/Painter/Painter.cpp +++ b/src/servers/app/drawing/Painter/Painter.cpp @@ -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); diff --git a/headers/private/servers/app/Painter.h b/src/servers/app/drawing/Painter/Painter.h similarity index 95% rename from headers/private/servers/app/Painter.h rename to src/servers/app/drawing/Painter/Painter.h index 3a7ecf1c57..cd0c74951c 100644 --- a/headers/private/servers/app/Painter.h +++ b/src/servers/app/drawing/Painter/Painter.h @@ -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; }; diff --git a/src/servers/app/drawing/ViewBitmapBuffer.cpp b/src/servers/app/drawing/ViewBitmapBuffer.cpp deleted file mode 100644 index ac7872ed5a..0000000000 --- a/src/servers/app/drawing/ViewBitmapBuffer.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// ViewBitmapBuffer.h - -#include - -#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; -} - diff --git a/src/servers/app/drawing/ViewBitmapBuffer.h b/src/servers/app/drawing/ViewBitmapBuffer.h deleted file mode 100644 index a46c817098..0000000000 --- a/src/servers/app/drawing/ViewBitmapBuffer.h +++ /dev/null @@ -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 diff --git a/src/servers/app/drawing/ViewHWInterface.cpp b/src/servers/app/drawing/ViewHWInterface.cpp index 0dfcda3a4a..a317418f12 100644 --- a/src/servers/app/drawing/ViewHWInterface.cpp +++ b/src/servers/app/drawing/ViewHWInterface.cpp @@ -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();