1/*
2 * Copyright 2001-2009, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Pahtz <pahtz@yahoo.com.au>
7 *		Axel D��rfler, axeld@pinc-software.de
8 */
9
10
11/*!	Class for low-overhead port-based messaging */
12
13
14#include <ServerLink.h>
15
16#include <stdlib.h>
17#include <string.h>
18#include <new>
19
20#include <Gradient.h>
21#include <GradientLinear.h>
22#include <GradientRadial.h>
23#include <GradientRadialFocus.h>
24#include <GradientDiamond.h>
25#include <GradientConic.h>
26#include <Region.h>
27#include <Shape.h>
28
29#include <ServerProtocol.h>
30
31
32//#define TRACE_SERVER_LINK_GRADIENTS
33#ifdef TRACE_SERVER_LINK_GRADIENTS
34#	include <OS.h>
35#	define GTRACE(x) debug_printf x
36#else
37#	define GTRACE(x) ;
38#endif
39
40
41namespace BPrivate {
42
43
44ServerLink::ServerLink()
45{
46}
47
48
49ServerLink::~ServerLink()
50{
51}
52
53
54void
55ServerLink::SetTo(port_id sender, port_id receiver)
56{
57	fSender->SetPort(sender);
58	fReceiver->SetPort(receiver);
59}
60
61
62status_t
63ServerLink::ReadRegion(BRegion* region)
64{
65	fReceiver->Read(&region->fCount, sizeof(int32));
66	if (region->fCount > 0) {
67		fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
68		if (!region->_SetSize(region->fCount))
69			return B_NO_MEMORY;
70		return fReceiver->Read(region->fData,
71			region->fCount * sizeof(clipping_rect));
72	}
73
74	return fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
75}
76
77
78status_t
79ServerLink::AttachRegion(const BRegion& region)
80{
81	fSender->Attach(&region.fCount, sizeof(int32));
82	if (region.fCount > 0) {
83		fSender->Attach(&region.fBounds, sizeof(clipping_rect));
84		return fSender->Attach(region.fData,
85			region.fCount * sizeof(clipping_rect));
86	}
87
88	return fSender->Attach(&region.fBounds, sizeof(clipping_rect));
89}
90
91
92status_t
93ServerLink::ReadShape(BShape* shape)
94{
95	int32 opCount, ptCount;
96	fReceiver->Read(&opCount, sizeof(int32));
97	fReceiver->Read(&ptCount, sizeof(int32));
98
99	uint32 opList[opCount];
100	if (opCount > 0)
101		fReceiver->Read(opList, opCount * sizeof(uint32));
102
103	BPoint ptList[ptCount];
104	if (ptCount > 0)
105		fReceiver->Read(ptList, ptCount * sizeof(BPoint));
106
107	shape->SetData(opCount, ptCount, opList, ptList);
108	return B_OK;
109}
110
111
112status_t
113ServerLink::AttachShape(BShape& shape)
114{
115	int32 opCount, ptCount;
116	uint32* opList;
117	BPoint* ptList;
118
119	shape.GetData(&opCount, &ptCount, &opList, &ptList);
120
121	fSender->Attach(&opCount, sizeof(int32));
122	fSender->Attach(&ptCount, sizeof(int32));
123	if (opCount > 0)
124		fSender->Attach(opList, opCount * sizeof(uint32));
125	if (ptCount > 0)
126		fSender->Attach(ptList, ptCount * sizeof(BPoint));
127	return B_OK;
128}
129
130
131status_t
132ServerLink::ReadGradient(BGradient** _gradient)
133{
134	GTRACE(("ServerLink::ReadGradient\n"));
135	return fReceiver->ReadGradient(_gradient);
136}
137
138
139status_t
140ServerLink::AttachGradient(const BGradient& gradient)
141{
142	GTRACE(("ServerLink::AttachGradient\n"));
143	BGradient::Type gradientType = gradient.GetType();
144	int32 stopCount = gradient.CountColorStops();
145	GTRACE(("ServerLink::AttachGradient> color stop count == %d\n",
146		(int)stopCount));
147	fSender->Attach(&gradientType, sizeof(BGradient::Type));
148	fSender->Attach(&stopCount, sizeof(int32));
149	if (stopCount > 0) {
150		for (int i = 0; i < stopCount; i++) {
151			fSender->Attach(gradient.ColorStopAtFast(i),
152				sizeof(BGradient::ColorStop));
153		}
154	}
155
156	switch (gradientType) {
157		case BGradient::TYPE_LINEAR:
158		{
159			GTRACE(("ServerLink::AttachGradient> type == TYPE_LINEAR\n"));
160			const BGradientLinear* linear = (BGradientLinear*)&gradient;
161			fSender->Attach(linear->Start());
162			fSender->Attach(linear->End());
163			break;
164		}
165		case BGradient::TYPE_RADIAL:
166		{
167			GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL\n"));
168			const BGradientRadial* radial = (BGradientRadial*)&gradient;
169			BPoint center = radial->Center();
170			float radius = radial->Radius();
171			fSender->Attach(&center, sizeof(BPoint));
172			fSender->Attach(&radius, sizeof(float));
173			break;
174		}
175		case BGradient::TYPE_RADIAL_FOCUS:
176		{
177			GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL_FOCUS\n"));
178			const BGradientRadialFocus* radialFocus
179				= (BGradientRadialFocus*)&gradient;
180			BPoint center = radialFocus->Center();
181			BPoint focal = radialFocus->Focal();
182			float radius = radialFocus->Radius();
183			fSender->Attach(&center, sizeof(BPoint));
184			fSender->Attach(&focal, sizeof(BPoint));
185			fSender->Attach(&radius, sizeof(float));
186			break;
187		}
188		case BGradient::TYPE_DIAMOND:
189		{
190			GTRACE(("ServerLink::AttachGradient> type == TYPE_DIAMOND\n"));
191			const BGradientDiamond* diamond = (BGradientDiamond*)&gradient;
192			BPoint center = diamond->Center();
193			fSender->Attach(&center, sizeof(BPoint));
194			break;
195		}
196		case BGradient::TYPE_CONIC:
197		{
198			GTRACE(("ServerLink::AttachGradient> type == TYPE_CONIC\n"));
199			const BGradientConic* conic = (BGradientConic*)&gradient;
200			BPoint center = conic->Center();
201			float angle = conic->Angle();
202			fSender->Attach(&center, sizeof(BPoint));
203			fSender->Attach(&angle, sizeof(float));
204			break;
205		}
206		case BGradient::TYPE_NONE:
207		{
208			GTRACE(("ServerLink::AttachGradient> type == TYPE_NONE\n"));
209			break;
210		}
211	}
212	return B_OK;
213}
214
215
216status_t
217ServerLink::FlushWithReply(int32& code)
218{
219	status_t status = Flush(B_INFINITE_TIMEOUT, true);
220	if (status < B_OK)
221		return status;
222
223	return GetNextMessage(code);
224}
225
226
227}	// namespace BPrivate
228