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