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