Patch by Artur Wyszynski with some changes by myself:

* Resolved TODO: The type of the gradient is no longer encoded twice in the
  app_server link protocoll.
* Moved instantiation of the BGradient into the LinkReceiver::ReadGradient()
  method.
* Check success for (at least) ReadGradient() in ServerWindow.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28150 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-10-15 19:47:00 +00:00
parent 2259002bdb
commit 431dc47dde
7 changed files with 134 additions and 232 deletions

View File

@ -13,9 +13,10 @@
#include <OS.h>
class BGradient;
class BString;
class BRegion;
class BGradient;
namespace BPrivate {
@ -38,7 +39,7 @@ class LinkReceiver {
status_t ReadString(BString& string, size_t* _length = NULL);
status_t ReadString(char* buffer, size_t bufferSize);
status_t ReadRegion(BRegion* region);
status_t ReadGradient(BGradient *gradient);
status_t ReadGradient(BGradient** gradient);
template <class Type> status_t Read(Type *data)
{ return Read(data, sizeof(Type)); }

View File

@ -66,7 +66,7 @@ class ServerLink {
status_t ReadString(char** _string, size_t* _length = NULL);
status_t ReadRegion(BRegion *region);
status_t ReadShape(BShape *shape);
status_t ReadGradient(BGradient *gradient);
status_t ReadGradient(BGradient **gradient);
template <class Type> status_t Read(Type *data);
// convenience methods

View File

@ -1,11 +1,12 @@
/*
* Copyright 2001-2007, Haiku.
* Copyright 2001-2008, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Pahtz <pahtz@yahoo.com.au>
* Axel Dörfler
* Stephan Aßmus <superstippi@gmx.de>
* Artur Wyszynski <harakash@gmail.com>
*/
/** Class for low-overhead port-based messaging */
@ -469,79 +470,120 @@ LinkReceiver::ReadRegion(BRegion* region)
}
static BGradient*
gradient_for_type(gradient_type type)
{
switch (type) {
case B_GRADIENT_LINEAR:
return new (std::nothrow) BGradientLinear();
case B_GRADIENT_RADIAL:
return new (std::nothrow) BGradientRadial();
case B_GRADIENT_RADIAL_FOCUS:
return new (std::nothrow) BGradientRadialFocus();
case B_GRADIENT_DIAMOND:
return new (std::nothrow) BGradientDiamond();
case B_GRADIENT_CONIC:
return new (std::nothrow) BGradientConic();
case B_GRADIENT_NONE:
return new (std::nothrow) BGradient();
}
return NULL;
}
status_t
LinkReceiver::ReadGradient(BGradient *gradient)
LinkReceiver::ReadGradient(BGradient** _gradient)
{
GTRACE(("LinkReceiver::ReadGradient\n"));
gradient_type gradientType;
int32 colorsCount;
Read(&gradientType, sizeof(gradient_type));
Read(&colorsCount, sizeof(int32));
status_t ret;
if ((ret = Read(&gradientType, sizeof(gradient_type))) != B_OK)
return ret;
if ((ret = Read(&colorsCount, sizeof(int32))) != B_OK)
return ret;
BGradient* gradient = gradient_for_type(gradientType);
if (!gradient)
return B_NO_MEMORY;
*_gradient = gradient;
if (colorsCount > 0) {
color_step step;
for (int i = 0; i < colorsCount; i++) {
Read(&step, sizeof(color_step));
gradient->AddColor(step, i);
if ((ret = Read(&step, sizeof(color_step))) != B_OK)
return ret;
if (!gradient->AddColor(step, i))
return B_NO_MEMORY;
}
}
switch(gradientType) {
case B_GRADIENT_LINEAR: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_LINEAR\n"));
BGradientLinear* linear = (BGradientLinear*) gradient;
BGradientLinear* linear = (BGradientLinear*)gradient;
BPoint start;
BPoint end;
Read(&start, sizeof(BPoint));
Read(&end, sizeof(BPoint));
if ((ret = Read(&start, sizeof(BPoint))) != B_OK)
return ret;
if ((ret = Read(&end, sizeof(BPoint))) != B_OK)
return ret;
linear->SetStart(start);
linear->SetEnd(end);
break;
return B_OK;
}
case B_GRADIENT_RADIAL: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_RADIAL\n"));
BGradientRadial* radial = (BGradientRadial*) gradient;
BGradientRadial* radial = (BGradientRadial*)gradient;
BPoint center;
float radius;
Read(&center, sizeof(BPoint));
Read(&radius, sizeof(float));
if ((ret = Read(&center, sizeof(BPoint))) != B_OK)
return ret;
if ((ret = Read(&radius, sizeof(float))) != B_OK)
return ret;
radial->SetCenter(center);
radial->SetRadius(radius);
break;
return B_OK;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
(BGradientRadialFocus*)gradient;
BPoint center;
BPoint focal;
float radius;
Read(&center, sizeof(BPoint));
Read(&focal, sizeof(BPoint));
Read(&radius, sizeof(float));
if ((ret = Read(&center, sizeof(BPoint))) != B_OK)
return ret;
if ((ret = Read(&focal, sizeof(BPoint))) != B_OK)
return ret;
if ((ret = Read(&radius, sizeof(float))) != B_OK)
return ret;
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
radialFocus->SetRadius(radius);
break;
return B_OK;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_DIAMOND\n"));
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BGradientDiamond* diamond = (BGradientDiamond*)gradient;
BPoint center;
Read(&center, sizeof(BPoint));
if ((ret = Read(&center, sizeof(BPoint))) != B_OK)
return ret;
diamond->SetCenter(center);
break;
return B_OK;
}
case B_GRADIENT_CONIC: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_CONIC\n"));
BGradientConic* conic = (BGradientConic*) gradient;
BGradientConic* conic = (BGradientConic*)gradient;
BPoint center;
float angle;
Read(&center, sizeof(BPoint));
Read(&angle, sizeof(float));
if ((ret = Read(&center, sizeof(BPoint))) != B_OK)
return ret;
if ((ret = Read(&angle, sizeof(float))) != B_OK)
return ret;
conic->SetCenter(center);
conic->SetAngle(angle);
break;
return B_OK;
}
case B_GRADIENT_NONE: {
GTRACE(("LinkReceiver::ReadGradient> type == B_GRADIENT_NONE\n"));
@ -549,7 +591,7 @@ LinkReceiver::ReadGradient(BGradient *gradient)
}
}
return B_OK;
return B_ERROR;
}
} // namespace BPrivate

View File

@ -115,87 +115,10 @@ ServerLink::AttachShape(BShape &shape)
status_t
ServerLink::ReadGradient(BGradient *gradient)
ServerLink::ReadGradient(BGradient **gradient)
{
GTRACE(("ServerLink::ReadGradient\n"));
fReceiver->ReadGradient(gradient);
/* gradient_type gradientType;
int32 colorsCount;
fReceiver->Read(&gradientType, sizeof(gradient_type));
fReceiver->Read(&colorsCount, sizeof(int32));
if (colorsCount > 0) {
color_step step;
for (int i = 0; i < colorsCount; i++) {
fReceiver->Read(&step, sizeof(color_step));
gradient->AddColor(step, i);
}
}
switch(gradientType) {
case B_GRADIENT_LINEAR: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_LINEAR\n"));
BGradientLinear* linear = (BGradientLinear*) gradient;
BPoint start;
BPoint end;
fReceiver->Read(&start, sizeof(BPoint));
fReceiver->Read(&end, sizeof(BPoint));
linear->SetStart(start);
linear->SetEnd(end);
break;
}
case B_GRADIENT_RADIAL: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_RADIAL\n"));
BGradientRadial* radial = (BGradientRadial*) gradient;
BPoint center;
float radius;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&radius, sizeof(float));
radial->SetCenter(center);
radial->SetRadius(radius);
break;
}
case B_GRADIENT_RADIAL_FOCUS: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_RADIAL_FOCUS\n"));
BGradientRadialFocus* radialFocus =
(BGradientRadialFocus*) gradient;
BPoint center;
BPoint focal;
float radius;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&focal, sizeof(BPoint));
fReceiver->Read(&radius, sizeof(float));
radialFocus->SetCenter(center);
radialFocus->SetFocal(focal);
radialFocus->SetRadius(radius);
break;
}
case B_GRADIENT_DIAMOND: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_DIAMOND\n"));
BGradientDiamond* diamond = (BGradientDiamond*) gradient;
BPoint center;
fReceiver->Read(&center, sizeof(BPoint));
diamond->SetCenter(center);
break;
}
case B_GRADIENT_CONIC: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_CONIC\n"));
BGradientConic* conic = (BGradientConic*) gradient;
BPoint center;
float angle;
fReceiver->Read(&center, sizeof(BPoint));
fReceiver->Read(&angle, sizeof(float));
conic->SetCenter(center);
conic->SetAngle(angle);
break;
}
case B_GRADIENT_NONE: {
GTRACE(("ServerLink::ReadGradient> type == B_GRADIENT_NONE\n"));
break;
}
}
*/
return B_OK;
return fReceiver->ReadGradient(gradient);
}

View File

@ -2629,7 +2629,6 @@ BView::FillEllipse(BRect rect, const BGradient& gradient)
fOwner->fLink->StartMessage(AS_FILL_ELLIPSE_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -2714,7 +2713,6 @@ BView::FillArc(BRect rect, float startAngle, float arcAngle,
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<float>(startAngle);
fOwner->fLink->Attach<float>(arcAngle);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -2772,7 +2770,6 @@ BView::FillBezier(BPoint *controlPoints, const BGradient& gradient)
fOwner->fLink->Attach<BPoint>(controlPoints[1]);
fOwner->fLink->Attach<BPoint>(controlPoints[2]);
fOwner->fLink->Attach<BPoint>(controlPoints[3]);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -2874,7 +2871,6 @@ BView::FillPolygon(const BPolygon *polygon, const BGradient& gradient)
fOwner->fLink->Attach<int32>(polygon->fCount);
fOwner->fLink->Attach(polygon->fPoints,
polygon->fCount * sizeof(BPoint));
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -2987,7 +2983,6 @@ BView::FillRect(BRect rect, const BGradient& gradient)
fOwner->fLink->StartMessage(AS_FILL_RECT_GRADIENT);
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -3046,7 +3041,6 @@ BView::FillRoundRect(BRect rect, float xRadius, float yRadius,
fOwner->fLink->Attach<BRect>(rect);
fOwner->fLink->Attach<float>(xRadius);
fOwner->fLink->Attach<float>(yRadius);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -3080,7 +3074,6 @@ BView::FillRegion(BRegion *region, const BGradient& gradient)
fOwner->fLink->StartMessage(AS_FILL_REGION_GRADIENT);
fOwner->fLink->AttachRegion(*region);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -3259,7 +3252,6 @@ BView::FillTriangle(BPoint pt1, BPoint pt2, BPoint pt3,
fOwner->fLink->Attach<BPoint>(pt2);
fOwner->fLink->Attach<BPoint>(pt3);
fOwner->fLink->Attach<BRect>(bounds);
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();
@ -3359,7 +3351,6 @@ BView::FillShape(BShape *shape, const BGradient& gradient)
fOwner->fLink->Attach<int32>(sd->ptCount);
fOwner->fLink->Attach(sd->opList, sd->opCount * sizeof(int32));
fOwner->fLink->Attach(sd->ptList, sd->ptCount * sizeof(BPoint));
fOwner->fLink->Attach<gradient_type>(gradient.Type());
fOwner->fLink->AttachGradient(gradient);
_FlushIfNotInTransaction();

View File

@ -8,6 +8,7 @@
* Stephan Aßmus <superstippi@gmx.de>
* Stefano Ceccherini (burton666@libero.it)
* Axel Dörfler, axeld@pinc-software.de
* Artur Wyszynski <harakash@gmail.com>
*/
/*!
@ -2139,15 +2140,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BRect rect;
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRectGradient(rect, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRectGradient(rect, *gradient);
break;
}
case AS_VIEW_DRAW_BITMAP:
@ -2198,15 +2196,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BRect>(&r);
link.Read<float>(&angle);
link.Read<float>(&span);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&r);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillArcGradient(r, angle, span, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&r);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillArcGradient(r, angle, span, *gradient);
break;
}
case AS_STROKE_BEZIER:
@ -2232,14 +2227,11 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BPoint>(&(pts[i]));
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
}
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillBezierGradient(pts, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillBezierGradient(pts, *gradient);
break;
}
case AS_STROKE_ELLIPSE:
@ -2260,15 +2252,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BRect rect;
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillEllipseGradient(rect, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillEllipseGradient(rect, *gradient);
break;
}
case AS_STROKE_ROUNDRECT:
@ -2295,15 +2284,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
link.Read<BRect>(&rect);
link.Read<float>(&xrad);
link.Read<float>(&yrad);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRoundRectGradient(rect, xrad, yrad, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRoundRectGradient(rect, xrad, yrad, *gradient);
break;
}
case AS_STROKE_TRIANGLE:
@ -2336,15 +2322,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
fCurrentView->ConvertToScreenForDrawing(&pts[i]);
}
link.Read<BRect>(&rect);
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillTriangleGradient(pts, rect, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&rect);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillTriangleGradient(pts, rect, *gradient);
break;
}
case AS_STROKE_POLYGON:
@ -2385,19 +2368,16 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BPoint* pointList = new(nothrow) BPoint[pointCount];
if (link.Read(pointList, pointCount * sizeof(BPoint)) >= B_OK) {
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
for (int32 i = 0; i < pointCount; i++)
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillPolygonGradient(pointList, pointCount,
polyFrame, *gradient, isClosed && pointCount > 2);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
for (int32 i = 0; i < pointCount; i++)
fCurrentView->ConvertToScreenForDrawing(&pointList[i]);
fCurrentView->ConvertToScreenForDrawing(&polyFrame);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillPolygonGradient(pointList, pointCount,
polyFrame, *gradient, isClosed && pointCount > 2);
}
delete[] pointList;
break;
@ -2460,15 +2440,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
ptList[i] += penLocation;
fCurrentView->ConvertToScreenForDrawing(&ptList[i]);
}
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillShapeGradient(shapeFrame, opCount, opList,
ptCount, ptList, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillShapeGradient(shapeFrame, opCount, opList,
ptCount, ptList, *gradient);
}
delete[] opList;
@ -2495,15 +2472,12 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li
BRegion region;
if (link.ReadRegion(&region) < B_OK)
break;
gradient_type gradientType;
link.Read<gradient_type>(&gradientType);
BGradient* gradient = _GetNewGradientForType(gradientType);
if (gradient) {
link.ReadGradient(gradient);
fCurrentView->ConvertToScreenForDrawing(&region);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRegionGradient(region, *gradient);
}
BGradient* gradient;
if (link.ReadGradient(&gradient) != B_OK)
break;
fCurrentView->ConvertToScreenForDrawing(&region);
fCurrentView->ConvertToScreenForDrawing(gradient);
drawingEngine->FillRegionGradient(region, *gradient);
break;
}
case AS_STROKE_LINEARRAY:
@ -3491,30 +3465,3 @@ ServerWindow::PictureToRegion(ServerPicture *picture, BRegion &region,
region.MakeEmpty();
return B_ERROR;
}
BGradient*
ServerWindow::_GetNewGradientForType(gradient_type type)
{
switch (type) {
case B_GRADIENT_LINEAR: {
return new (std::nothrow) BGradientLinear();
}
case B_GRADIENT_RADIAL: {
return new (std::nothrow) BGradientRadial();
}
case B_GRADIENT_RADIAL_FOCUS: {
return new (std::nothrow) BGradientRadialFocus();
}
case B_GRADIENT_DIAMOND: {
return new (std::nothrow) BGradientDiamond();
}
case B_GRADIENT_CONIC: {
return new (std::nothrow) BGradientConic();
}
case B_GRADIENT_NONE: {
return new (std::nothrow) BGradient();
}
}
return NULL;
}

View File

@ -130,8 +130,6 @@ private:
void _UpdateCurrentDrawingRegion();
bool _MessageNeedsAllWindowsLocked(uint32 code) const;
BGradient* _GetNewGradientForType(gradient_type type);
// TODO: Move me elsewhere
status_t PictureToRegion(ServerPicture *picture,