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 46 ServerLink::ServerLink() 47 { 48 } 49 50 51 ServerLink::~ServerLink() 52 { 53 } 54 55 56 void 57 ServerLink::SetTo(port_id sender, port_id receiver) 58 { 59 fSender->SetPort(sender); 60 fReceiver->SetPort(receiver); 61 } 62 63 64 status_t 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 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 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 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 134 ServerLink::ReadGradient(BGradient** _gradient) 135 { 136 GTRACE(("ServerLink::ReadGradient\n")); 137 return fReceiver->ReadGradient(_gradient); 138 } 139 140 141 status_t 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 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