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(®ion->fCount, sizeof(int32));
68 if (region->fCount > 0) {
69 fReceiver->Read(®ion->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(®ion->fBounds, sizeof(clipping_rect));
77 }
78
79
80 status_t
AttachRegion(const BRegion & region)81 ServerLink::AttachRegion(const BRegion& region)
82 {
83 fSender->Attach(®ion.fCount, sizeof(int32));
84 if (region.fCount > 0) {
85 fSender->Attach(®ion.fBounds, sizeof(clipping_rect));
86 return fSender->Attach(region.fData,
87 region.fCount * sizeof(clipping_rect));
88 }
89
90 return fSender->Attach(®ion.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(¢er, 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(¢er, 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(¢er, 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(¢er, 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