1 /* 2 * Copyright 2009, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 */ 8 9 #include "RemoteMessage.h" 10 11 #ifndef CLIENT_COMPILE 12 #include "DrawState.h" 13 #include "ServerBitmap.h" 14 #include "ServerCursor.h" 15 #endif 16 17 #include <Bitmap.h> 18 #include <Font.h> 19 #include <View.h> 20 21 #include <Gradient.h> 22 #include <GradientLinear.h> 23 #include <GradientRadial.h> 24 #include <GradientRadialFocus.h> 25 #include <GradientDiamond.h> 26 #include <GradientConic.h> 27 28 #include <new> 29 30 31 status_t 32 RemoteMessage::NextMessage(uint16& code) 33 { 34 if (fDataLeft > 0) { 35 // discard remainder of message 36 int32 readSize = fSource->Read(NULL, fDataLeft); 37 if (readSize < 0) 38 return readSize; 39 } 40 41 static const uint32 kHeaderSize = sizeof(uint16) + sizeof(uint32); 42 43 fDataLeft = kHeaderSize; 44 Read(code); 45 uint32 dataLeft; 46 status_t result = Read(dataLeft); 47 if (result != B_OK) 48 return result; 49 50 if (dataLeft < kHeaderSize) 51 return B_ERROR; 52 53 fDataLeft = dataLeft - kHeaderSize; 54 fCode = code; 55 return B_OK; 56 } 57 58 59 void 60 RemoteMessage::Cancel() 61 { 62 fAvailable += fWriteIndex; 63 fWriteIndex = 0; 64 } 65 66 67 #ifndef CLIENT_COMPILE 68 void 69 RemoteMessage::AddBitmap(const ServerBitmap& bitmap, bool minimal) 70 { 71 Add(bitmap.Width()); 72 Add(bitmap.Height()); 73 Add(bitmap.BytesPerRow()); 74 75 if (!minimal) { 76 Add(bitmap.ColorSpace()); 77 Add(bitmap.Flags()); 78 } 79 80 uint32 bitsLength = bitmap.BitsLength(); 81 Add(bitsLength); 82 83 if (!_MakeSpace(bitsLength)) 84 return; 85 86 memcpy(fBuffer + fWriteIndex, bitmap.Bits(), bitsLength); 87 fWriteIndex += bitsLength; 88 fAvailable -= bitsLength; 89 } 90 91 92 void 93 RemoteMessage::AddFont(const ServerFont& font) 94 { 95 Add(font.Direction()); 96 Add((uint8)font.Encoding()); 97 Add(font.Flags()); 98 Add((uint8)font.Spacing()); 99 Add(font.Shear()); 100 Add(font.Rotation()); 101 Add(font.FalseBoldWidth()); 102 Add(font.Size()); 103 Add(font.Face()); 104 Add(font.GetFamilyAndStyle()); 105 } 106 107 108 void 109 RemoteMessage::AddDrawState(const DrawState& drawState) 110 { 111 Add(drawState.PenSize()); 112 Add(drawState.SubPixelPrecise()); 113 Add(drawState.GetDrawingMode()); 114 Add(drawState.AlphaSrcMode()); 115 Add(drawState.AlphaFncMode()); 116 AddPattern(drawState.GetPattern()); 117 Add(drawState.LineCapMode()); 118 Add(drawState.LineJoinMode()); 119 Add(drawState.MiterLimit()); 120 Add(drawState.HighColor()); 121 Add(drawState.LowColor()); 122 } 123 124 125 void 126 RemoteMessage::AddArrayLine(const ViewLineArrayInfo& line) 127 { 128 Add(line.startPoint); 129 Add(line.endPoint); 130 Add(line.color); 131 } 132 133 134 void 135 RemoteMessage::AddCursor(const ServerCursor& cursor) 136 { 137 Add(cursor.GetHotSpot()); 138 AddBitmap(cursor); 139 } 140 141 142 void 143 RemoteMessage::AddPattern(const Pattern& pattern) 144 { 145 Add(pattern.GetPattern()); 146 } 147 148 #else // !CLIENT_COMPILE 149 150 void 151 RemoteMessage::AddBitmap(const BBitmap& bitmap) 152 { 153 BRect bounds = bitmap.Bounds(); 154 Add(bounds.IntegerWidth() + 1); 155 Add(bounds.IntegerHeight() + 1); 156 Add(bitmap.BytesPerRow()); 157 Add(bitmap.ColorSpace()); 158 Add(bitmap.Flags()); 159 160 uint32 bitsLength = bitmap.BitsLength(); 161 Add(bitsLength); 162 163 if (!_MakeSpace(bitsLength)) 164 return; 165 166 memcpy(fBuffer + fWriteIndex, bitmap.Bits(), bitsLength); 167 fWriteIndex += bitsLength; 168 fAvailable -= bitsLength; 169 } 170 #endif // !CLIENT_COMPILE 171 172 173 void 174 RemoteMessage::AddGradient(const BGradient& gradient) 175 { 176 Add(gradient.GetType()); 177 178 switch (gradient.GetType()) { 179 case BGradient::TYPE_NONE: 180 break; 181 182 case BGradient::TYPE_LINEAR: 183 { 184 const BGradientLinear* linear 185 = dynamic_cast<const BGradientLinear *>(&gradient); 186 if (linear == NULL) 187 return; 188 189 Add(linear->Start()); 190 Add(linear->End()); 191 break; 192 } 193 194 case BGradient::TYPE_RADIAL: 195 { 196 const BGradientRadial* radial 197 = dynamic_cast<const BGradientRadial *>(&gradient); 198 if (radial == NULL) 199 return; 200 201 Add(radial->Center()); 202 Add(radial->Radius()); 203 break; 204 } 205 206 case BGradient::TYPE_RADIAL_FOCUS: 207 { 208 const BGradientRadialFocus* radialFocus 209 = dynamic_cast<const BGradientRadialFocus *>(&gradient); 210 if (radialFocus == NULL) 211 return; 212 213 Add(radialFocus->Center()); 214 Add(radialFocus->Focal()); 215 Add(radialFocus->Radius()); 216 break; 217 } 218 219 case BGradient::TYPE_DIAMOND: 220 { 221 const BGradientDiamond* diamond 222 = dynamic_cast<const BGradientDiamond *>(&gradient); 223 if (diamond == NULL) 224 return; 225 226 Add(diamond->Center()); 227 break; 228 } 229 230 case BGradient::TYPE_CONIC: 231 { 232 const BGradientConic* conic 233 = dynamic_cast<const BGradientConic *>(&gradient); 234 if (conic == NULL) 235 return; 236 237 Add(conic->Center()); 238 Add(conic->Angle()); 239 break; 240 } 241 } 242 243 int32 stopCount = gradient.CountColorStops(); 244 Add(stopCount); 245 246 for (int32 i = 0; i < stopCount; i++) { 247 BGradient::ColorStop* stop = gradient.ColorStopAt(i); 248 if (stop == NULL) 249 return; 250 251 Add(stop->color); 252 Add(stop->offset); 253 } 254 } 255 256 257 status_t 258 RemoteMessage::ReadString(char** _string, size_t& _length) 259 { 260 uint32 length; 261 status_t result = Read(length); 262 if (result != B_OK) 263 return result; 264 265 if (length > fDataLeft) 266 return B_ERROR; 267 268 char *string = (char *)malloc(length + 1); 269 if (string == NULL) 270 return B_NO_MEMORY; 271 272 int32 readSize = fSource->Read(string, length); 273 if (readSize < 0) { 274 free(string); 275 return readSize; 276 } 277 278 if ((uint32)readSize != length) { 279 free(string); 280 return B_ERROR; 281 } 282 283 fDataLeft -= readSize; 284 285 string[length] = 0; 286 *_string = string; 287 _length = length; 288 return B_OK; 289 } 290 291 292 status_t 293 RemoteMessage::ReadBitmap(BBitmap** _bitmap, bool minimal, 294 color_space colorSpace, uint32 flags) 295 { 296 uint32 bitsLength; 297 int32 width, height, bytesPerRow; 298 299 Read(width); 300 Read(height); 301 Read(bytesPerRow); 302 303 if (!minimal) { 304 Read(colorSpace); 305 Read(flags); 306 } 307 308 Read(bitsLength); 309 310 if (bitsLength > fDataLeft) 311 return B_ERROR; 312 313 #ifndef CLIENT_COMPILE 314 flags = B_BITMAP_NO_SERVER_LINK; 315 #endif 316 317 BBitmap *bitmap = new(std::nothrow) BBitmap( 318 BRect(0, 0, width - 1, height - 1), flags, colorSpace, bytesPerRow); 319 if (bitmap == NULL) 320 return B_NO_MEMORY; 321 322 status_t result = bitmap->InitCheck(); 323 if (result != B_OK) { 324 delete bitmap; 325 return result; 326 } 327 328 if (bitmap->BitsLength() < (int32)bitsLength) { 329 delete bitmap; 330 return B_ERROR; 331 } 332 333 int32 readSize = fSource->Read(bitmap->Bits(), bitsLength); 334 if ((uint32)readSize != bitsLength) { 335 delete bitmap; 336 return readSize < 0 ? readSize : B_ERROR; 337 } 338 339 fDataLeft -= readSize; 340 *_bitmap = bitmap; 341 return B_OK; 342 } 343 344 345 status_t 346 RemoteMessage::ReadFontState(BFont& font) 347 { 348 uint8 encoding, spacing; 349 uint16 face; 350 uint32 flags, familyAndStyle; 351 font_direction direction; 352 float falseBoldWidth, rotation, shear, size; 353 354 Read(direction); 355 Read(encoding); 356 Read(flags); 357 Read(spacing); 358 Read(shear); 359 Read(rotation); 360 Read(falseBoldWidth); 361 Read(size); 362 Read(face); 363 status_t result = Read(familyAndStyle); 364 if (result != B_OK) 365 return result; 366 367 font.SetFamilyAndStyle(familyAndStyle); 368 font.SetEncoding(encoding); 369 font.SetFlags(flags); 370 font.SetSpacing(spacing); 371 font.SetShear(shear); 372 font.SetRotation(rotation); 373 font.SetFalseBoldWidth(falseBoldWidth); 374 font.SetSize(size); 375 font.SetFace(face); 376 return B_OK; 377 } 378 379 380 status_t 381 RemoteMessage::ReadViewState(BView& view, ::pattern& pattern) 382 { 383 bool subPixelPrecise; 384 float penSize, miterLimit; 385 drawing_mode drawingMode; 386 source_alpha sourceAlpha; 387 alpha_function alphaFunction; 388 cap_mode capMode; 389 join_mode joinMode; 390 rgb_color highColor, lowColor; 391 392 Read(penSize); 393 Read(subPixelPrecise); 394 Read(drawingMode); 395 Read(sourceAlpha); 396 Read(alphaFunction); 397 Read(pattern); 398 Read(capMode); 399 Read(joinMode); 400 Read(miterLimit); 401 Read(highColor); 402 status_t result = Read(lowColor); 403 if (result != B_OK) 404 return result; 405 406 uint32 flags = view.Flags() & ~B_SUBPIXEL_PRECISE; 407 view.SetFlags(flags | (subPixelPrecise ? B_SUBPIXEL_PRECISE : 0)); 408 view.SetPenSize(penSize); 409 view.SetDrawingMode(drawingMode); 410 view.SetBlendingMode(sourceAlpha, alphaFunction); 411 view.SetLineMode(capMode, joinMode, miterLimit); 412 view.SetHighColor(highColor); 413 view.SetLowColor(lowColor); 414 return B_OK; 415 } 416 417 418 status_t 419 RemoteMessage::ReadGradient(BGradient** _gradient) 420 { 421 BGradient::Type type; 422 Read(type); 423 424 BGradient *gradient = NULL; 425 switch (type) { 426 case BGradient::TYPE_NONE: 427 break; 428 429 case BGradient::TYPE_LINEAR: 430 { 431 BPoint start, end; 432 433 Read(start); 434 Read(end); 435 436 gradient = new(std::nothrow) BGradientLinear(start, end); 437 break; 438 } 439 440 case BGradient::TYPE_RADIAL: 441 { 442 BPoint center; 443 float radius; 444 445 Read(center); 446 Read(radius); 447 448 gradient = new(std::nothrow) BGradientRadial(center, radius); 449 break; 450 } 451 452 case BGradient::TYPE_RADIAL_FOCUS: 453 { 454 BPoint center, focal; 455 float radius; 456 457 Read(center); 458 Read(focal); 459 Read(radius); 460 461 gradient = new(std::nothrow) BGradientRadialFocus(center, radius, 462 focal); 463 break; 464 } 465 466 case BGradient::TYPE_DIAMOND: 467 { 468 BPoint center; 469 470 Read(center); 471 472 gradient = new(std::nothrow) BGradientDiamond(center); 473 break; 474 } 475 476 case BGradient::TYPE_CONIC: 477 { 478 BPoint center; 479 float angle; 480 481 Read(center); 482 Read(angle); 483 484 gradient = new(std::nothrow) BGradientConic(center, angle); 485 break; 486 } 487 } 488 489 if (gradient == NULL) 490 return B_NO_MEMORY; 491 492 int32 stopCount; 493 status_t result = Read(stopCount); 494 if (result != B_OK) { 495 delete gradient; 496 return result; 497 } 498 499 for (int32 i = 0; i < stopCount; i++) { 500 rgb_color color; 501 float offset; 502 503 Read(color); 504 result = Read(offset); 505 if (result != B_OK) 506 return result; 507 508 gradient->AddColor(color, offset); 509 } 510 511 *_gradient = gradient; 512 return B_OK; 513 } 514 515 516 status_t 517 RemoteMessage::ReadArrayLine(BPoint& startPoint, BPoint& endPoint, 518 rgb_color& color) 519 { 520 Read(startPoint); 521 Read(endPoint); 522 return Read(color); 523 } 524