xref: /haiku/src/kits/app/ServerLink.cpp (revision 2b0aa4245bc5e6b0a38dbb0fb31ccb56794d13ff)
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 #include <ShapePrivate.h>
29 #include <StackOrHeapArray.h>
30 
31 #include <ServerProtocol.h>
32 
33 
34 //#define TRACE_SERVER_LINK_GRADIENTS
35 #ifdef TRACE_SERVER_LINK_GRADIENTS
36 #	include <OS.h>
37 #	define GTRACE(x) debug_printf x
38 #else
39 #	define GTRACE(x) ;
40 #endif
41 
42 
43 namespace BPrivate {
44 
45 
ServerLink()46 ServerLink::ServerLink()
47 {
48 }
49 
50 
~ServerLink()51 ServerLink::~ServerLink()
52 {
53 }
54 
55 
56 void
SetTo(port_id sender,port_id receiver)57 ServerLink::SetTo(port_id sender, port_id receiver)
58 {
59 	fSender->SetPort(sender);
60 	fReceiver->SetPort(receiver);
61 }
62 
63 
64 status_t
ReadRegion(BRegion * region)65 ServerLink::ReadRegion(BRegion* region)
66 {
67 	fReceiver->Read(&region->fCount, sizeof(int32));
68 	if (region->fCount > 0) {
69 		fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
70 		if (!region->_SetSize(region->fCount))
71 			return B_NO_MEMORY;
72 		return fReceiver->Read(region->fData,
73 			region->fCount * sizeof(clipping_rect));
74 	}
75 
76 	return fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
77 }
78 
79 
80 status_t
AttachRegion(const BRegion & region)81 ServerLink::AttachRegion(const BRegion& region)
82 {
83 	fSender->Attach(&region.fCount, sizeof(int32));
84 	if (region.fCount > 0) {
85 		fSender->Attach(&region.fBounds, sizeof(clipping_rect));
86 		return fSender->Attach(region.fData,
87 			region.fCount * sizeof(clipping_rect));
88 	}
89 
90 	return fSender->Attach(&region.fBounds, sizeof(clipping_rect));
91 }
92 
93 
94 status_t
ReadShape(BShape * shape)95 ServerLink::ReadShape(BShape* shape)
96 {
97 	int32 opCount, ptCount;
98 	fReceiver->Read(&opCount, sizeof(int32));
99 	fReceiver->Read(&ptCount, sizeof(int32));
100 
101 	BStackOrHeapArray<uint32, 64> opList(opCount);
102 	if (opCount > 0)
103 		fReceiver->Read(opList, opCount * sizeof(uint32));
104 
105 	BStackOrHeapArray<BPoint, 64> ptList(ptCount);
106 	if (ptCount > 0)
107 		fReceiver->Read(ptList, ptCount * sizeof(BPoint));
108 
109 	BShape::Private(*shape).SetData(opCount, ptCount, opList, ptList);
110 	return B_OK;
111 }
112 
113 
114 status_t
AttachShape(BShape & shape)115 ServerLink::AttachShape(BShape& shape)
116 {
117 	int32 opCount, ptCount;
118 	uint32* opList;
119 	BPoint* ptList;
120 
121 	BShape::Private(shape).GetData(&opCount, &ptCount, &opList, &ptList);
122 
123 	fSender->Attach(&opCount, sizeof(int32));
124 	fSender->Attach(&ptCount, sizeof(int32));
125 	if (opCount > 0)
126 		fSender->Attach(opList, opCount * sizeof(uint32));
127 	if (ptCount > 0)
128 		fSender->Attach(ptList, ptCount * sizeof(BPoint));
129 	return B_OK;
130 }
131 
132 
133 status_t
ReadGradient(BGradient ** _gradient)134 ServerLink::ReadGradient(BGradient** _gradient)
135 {
136 	GTRACE(("ServerLink::ReadGradient\n"));
137 	return fReceiver->ReadGradient(_gradient);
138 }
139 
140 
141 status_t
AttachGradient(const BGradient & gradient)142 ServerLink::AttachGradient(const BGradient& gradient)
143 {
144 	GTRACE(("ServerLink::AttachGradient\n"));
145 	BGradient::Type gradientType = gradient.GetType();
146 	int32 stopCount = gradient.CountColorStops();
147 	GTRACE(("ServerLink::AttachGradient> color stop count == %d\n",
148 		(int)stopCount));
149 	fSender->Attach(&gradientType, sizeof(BGradient::Type));
150 	fSender->Attach(&stopCount, sizeof(int32));
151 	if (stopCount > 0) {
152 		for (int i = 0; i < stopCount; i++) {
153 			fSender->Attach(gradient.ColorStopAtFast(i),
154 				sizeof(BGradient::ColorStop));
155 		}
156 	}
157 
158 	switch (gradientType) {
159 		case BGradient::TYPE_LINEAR:
160 		{
161 			GTRACE(("ServerLink::AttachGradient> type == TYPE_LINEAR\n"));
162 			const BGradientLinear* linear = (BGradientLinear*)&gradient;
163 			fSender->Attach(linear->Start());
164 			fSender->Attach(linear->End());
165 			break;
166 		}
167 		case BGradient::TYPE_RADIAL:
168 		{
169 			GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL\n"));
170 			const BGradientRadial* radial = (BGradientRadial*)&gradient;
171 			BPoint center = radial->Center();
172 			float radius = radial->Radius();
173 			fSender->Attach(&center, sizeof(BPoint));
174 			fSender->Attach(&radius, sizeof(float));
175 			break;
176 		}
177 		case BGradient::TYPE_RADIAL_FOCUS:
178 		{
179 			GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL_FOCUS\n"));
180 			const BGradientRadialFocus* radialFocus
181 				= (BGradientRadialFocus*)&gradient;
182 			BPoint center = radialFocus->Center();
183 			BPoint focal = radialFocus->Focal();
184 			float radius = radialFocus->Radius();
185 			fSender->Attach(&center, sizeof(BPoint));
186 			fSender->Attach(&focal, sizeof(BPoint));
187 			fSender->Attach(&radius, sizeof(float));
188 			break;
189 		}
190 		case BGradient::TYPE_DIAMOND:
191 		{
192 			GTRACE(("ServerLink::AttachGradient> type == TYPE_DIAMOND\n"));
193 			const BGradientDiamond* diamond = (BGradientDiamond*)&gradient;
194 			BPoint center = diamond->Center();
195 			fSender->Attach(&center, sizeof(BPoint));
196 			break;
197 		}
198 		case BGradient::TYPE_CONIC:
199 		{
200 			GTRACE(("ServerLink::AttachGradient> type == TYPE_CONIC\n"));
201 			const BGradientConic* conic = (BGradientConic*)&gradient;
202 			BPoint center = conic->Center();
203 			float angle = conic->Angle();
204 			fSender->Attach(&center, sizeof(BPoint));
205 			fSender->Attach(&angle, sizeof(float));
206 			break;
207 		}
208 		case BGradient::TYPE_NONE:
209 		{
210 			GTRACE(("ServerLink::AttachGradient> type == TYPE_NONE\n"));
211 			break;
212 		}
213 	}
214 	return B_OK;
215 }
216 
217 
218 status_t
FlushWithReply(int32 & code)219 ServerLink::FlushWithReply(int32& code)
220 {
221 	status_t status = Flush(B_INFINITE_TIMEOUT, true);
222 	if (status < B_OK)
223 		return status;
224 
225 	return GetNextMessage(code);
226 }
227 
228 
229 }	// namespace BPrivate
230