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