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