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 #ifndef REMOTE_MESSAGE_H 9 #define REMOTE_MESSAGE_H 10 11 #ifndef CLIENT_COMPILE 12 # include "PatternHandler.h" 13 # include <ViewPrivate.h> 14 #endif 15 16 #include "StreamingRingBuffer.h" 17 18 #include <AffineTransform.h> 19 #include <GraphicsDefs.h> 20 #include <Region.h> 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 class BBitmap; 27 class BFont; 28 class BGradient; 29 class BView; 30 class DrawState; 31 class Pattern; 32 class RemotePainter; 33 class ServerBitmap; 34 class ServerCursor; 35 class ServerFont; 36 struct ViewLineArrayInfo; 37 38 enum { 39 RP_INIT_CONNECTION = 1, 40 RP_UPDATE_DISPLAY_MODE, 41 RP_CLOSE_CONNECTION, 42 RP_GET_SYSTEM_PALETTE, 43 RP_GET_SYSTEM_PALETTE_RESULT, 44 45 RP_CREATE_STATE = 20, 46 RP_DELETE_STATE, 47 RP_ENABLE_SYNC_DRAWING, 48 RP_DISABLE_SYNC_DRAWING, 49 RP_INVALIDATE_RECT, 50 RP_INVALIDATE_REGION, 51 52 RP_SET_OFFSETS = 40, 53 RP_SET_HIGH_COLOR, 54 RP_SET_LOW_COLOR, 55 RP_SET_PEN_SIZE, 56 RP_SET_STROKE_MODE, 57 RP_SET_BLENDING_MODE, 58 RP_SET_PATTERN, 59 RP_SET_DRAWING_MODE, 60 RP_SET_FONT, 61 RP_SET_TRANSFORM, 62 63 RP_CONSTRAIN_CLIPPING_REGION = 60, 64 RP_COPY_RECT_NO_CLIPPING, 65 RP_INVERT_RECT, 66 RP_DRAW_BITMAP, 67 RP_DRAW_BITMAP_RECTS, 68 69 RP_STROKE_ARC = 80, 70 RP_STROKE_BEZIER, 71 RP_STROKE_ELLIPSE, 72 RP_STROKE_POLYGON, 73 RP_STROKE_RECT, 74 RP_STROKE_ROUND_RECT, 75 RP_STROKE_SHAPE, 76 RP_STROKE_TRIANGLE, 77 RP_STROKE_LINE, 78 RP_STROKE_LINE_ARRAY, 79 80 RP_FILL_ARC = 100, 81 RP_FILL_BEZIER, 82 RP_FILL_ELLIPSE, 83 RP_FILL_POLYGON, 84 RP_FILL_RECT, 85 RP_FILL_ROUND_RECT, 86 RP_FILL_SHAPE, 87 RP_FILL_TRIANGLE, 88 RP_FILL_REGION, 89 90 RP_FILL_ARC_GRADIENT = 120, 91 RP_FILL_BEZIER_GRADIENT, 92 RP_FILL_ELLIPSE_GRADIENT, 93 RP_FILL_POLYGON_GRADIENT, 94 RP_FILL_RECT_GRADIENT, 95 RP_FILL_ROUND_RECT_GRADIENT, 96 RP_FILL_SHAPE_GRADIENT, 97 RP_FILL_TRIANGLE_GRADIENT, 98 RP_FILL_REGION_GRADIENT, 99 100 RP_STROKE_POINT_COLOR = 140, 101 RP_STROKE_LINE_1PX_COLOR, 102 RP_STROKE_RECT_1PX_COLOR, 103 104 RP_FILL_RECT_COLOR = 160, 105 RP_FILL_REGION_COLOR_NO_CLIPPING, 106 107 RP_DRAW_STRING = 180, 108 RP_DRAW_STRING_WITH_OFFSETS, 109 RP_DRAW_STRING_RESULT, 110 RP_STRING_WIDTH, 111 RP_STRING_WIDTH_RESULT, 112 RP_READ_BITMAP, 113 RP_READ_BITMAP_RESULT, 114 115 RP_SET_CURSOR = 200, 116 RP_SET_CURSOR_VISIBLE, 117 RP_MOVE_CURSOR_TO, 118 119 RP_MOUSE_MOVED = 220, 120 RP_MOUSE_DOWN, 121 RP_MOUSE_UP, 122 RP_MOUSE_WHEEL_CHANGED, 123 124 RP_KEY_DOWN = 240, 125 RP_KEY_UP, 126 RP_UNMAPPED_KEY_DOWN, 127 RP_UNMAPPED_KEY_UP, 128 RP_MODIFIERS_CHANGED 129 }; 130 131 132 class RemoteMessage { 133 public: 134 RemoteMessage(StreamingRingBuffer* source, 135 StreamingRingBuffer *target); 136 ~RemoteMessage(); 137 138 void Start(uint16 code); 139 status_t Flush(); 140 void Cancel(); 141 142 status_t NextMessage(uint16& code); 143 uint16 Code() { return fCode; } 144 uint32 DataLeft() { return fDataLeft; } 145 146 template<typename T> 147 void Add(const T& value); 148 149 void AddString(const char* string, size_t length); 150 void AddRegion(const BRegion& region); 151 void AddGradient(const BGradient& gradient); 152 void AddTransform(const BAffineTransform& transform); 153 154 #ifndef CLIENT_COMPILE 155 void AddBitmap(const ServerBitmap& bitmap, 156 bool minimal = false); 157 void AddFont(const ServerFont& font); 158 void AddPattern(const Pattern& pattern); 159 void AddDrawState(const DrawState& drawState); 160 void AddArrayLine(const ViewLineArrayInfo& line); 161 void AddCursor(const ServerCursor& cursor); 162 #else 163 void AddBitmap(const BBitmap& bitmap); 164 #endif 165 166 template<typename T> 167 void AddList(const T* array, int32 count); 168 169 template<typename T> 170 status_t Read(T& value); 171 172 status_t ReadRegion(BRegion& region); 173 status_t ReadFontState(BFont& font); 174 // sets font state 175 status_t ReadViewState(BView& view, ::pattern& pattern); 176 // sets viewstate and returns pattern 177 178 status_t ReadString(char** _string, size_t& length); 179 status_t ReadBitmap(BBitmap** _bitmap, 180 bool minimal = false, 181 color_space colorSpace = B_RGB32, 182 uint32 flags = 0); 183 status_t ReadGradient(BGradient** _gradient); 184 status_t ReadTransform(BAffineTransform& transform); 185 status_t ReadArrayLine(BPoint& startPoint, 186 BPoint& endPoint, rgb_color& color); 187 188 template<typename T> 189 status_t ReadList(T* array, int32 count); 190 191 private: 192 bool _MakeSpace(size_t size); 193 194 StreamingRingBuffer* fSource; 195 StreamingRingBuffer* fTarget; 196 197 uint8* fBuffer; 198 size_t fAvailable; 199 size_t fWriteIndex; 200 uint32 fDataLeft; 201 uint16 fCode; 202 }; 203 204 205 inline 206 RemoteMessage::RemoteMessage(StreamingRingBuffer* source, 207 StreamingRingBuffer* target) 208 : 209 fSource(source), 210 fTarget(target), 211 fBuffer(NULL), 212 fAvailable(0), 213 fWriteIndex(0), 214 fDataLeft(0) 215 { 216 } 217 218 219 inline 220 RemoteMessage::~RemoteMessage() 221 { 222 if (fWriteIndex > 0) 223 Flush(); 224 free(fBuffer); 225 } 226 227 228 inline void 229 RemoteMessage::Start(uint16 code) 230 { 231 if (fWriteIndex > 0) 232 Flush(); 233 234 Add(code); 235 236 uint32 sizeDummy = 0; 237 Add(sizeDummy); 238 } 239 240 241 inline status_t 242 RemoteMessage::Flush() 243 { 244 if (fWriteIndex == 0 || fTarget == NULL) 245 return B_NO_INIT; 246 247 uint32 length = fWriteIndex; 248 fAvailable += fWriteIndex; 249 fWriteIndex = 0; 250 251 memcpy(fBuffer + sizeof(uint16), &length, sizeof(uint32)); 252 return fTarget->Write(fBuffer, length); 253 } 254 255 256 template<typename T> 257 inline void 258 RemoteMessage::Add(const T& value) 259 { 260 if (!_MakeSpace(sizeof(T))) 261 return; 262 263 memcpy(fBuffer + fWriteIndex, &value, sizeof(T)); 264 fWriteIndex += sizeof(T); 265 fAvailable -= sizeof(T); 266 } 267 268 269 inline void 270 RemoteMessage::AddString(const char* string, size_t length) 271 { 272 Add((uint32)length); 273 if (length > fAvailable && !_MakeSpace(length)) 274 return; 275 276 memcpy(fBuffer + fWriteIndex, string, length); 277 fWriteIndex += length; 278 fAvailable -= length; 279 } 280 281 282 inline void 283 RemoteMessage::AddRegion(const BRegion& region) 284 { 285 int32 rectCount = region.CountRects(); 286 Add(rectCount); 287 288 for (int32 i = 0; i < rectCount; i++) 289 Add(region.RectAt(i)); 290 } 291 292 293 template<typename T> 294 inline void 295 RemoteMessage::AddList(const T* array, int32 count) 296 { 297 for (int32 i = 0; i < count; i++) 298 Add(array[i]); 299 } 300 301 302 template<typename T> 303 inline status_t 304 RemoteMessage::Read(T& value) 305 { 306 if (fDataLeft < sizeof(T)) 307 return B_ERROR; 308 309 if (fSource == NULL) 310 return B_NO_INIT; 311 312 int32 readSize = fSource->Read(&value, sizeof(T)); 313 if (readSize < 0) 314 return readSize; 315 316 if (readSize != sizeof(T)) 317 return B_ERROR; 318 319 fDataLeft -= sizeof(T); 320 return B_OK; 321 } 322 323 324 inline status_t 325 RemoteMessage::ReadRegion(BRegion& region) 326 { 327 region.MakeEmpty(); 328 329 int32 rectCount; 330 Read(rectCount); 331 332 for (int32 i = 0; i < rectCount; i++) { 333 BRect rect; 334 status_t result = Read(rect); 335 if (result != B_OK) 336 return result; 337 338 region.Include(rect); 339 } 340 341 return B_OK; 342 } 343 344 345 template<typename T> 346 inline status_t 347 RemoteMessage::ReadList(T* array, int32 count) 348 { 349 for (int32 i = 0; i < count; i++) { 350 status_t result = Read(array[i]); 351 if (result != B_OK) 352 return result; 353 } 354 355 return B_OK; 356 } 357 358 359 inline bool 360 RemoteMessage::_MakeSpace(size_t size) 361 { 362 if (fAvailable >= size) 363 return true; 364 365 size_t extraSize = size + 20; 366 uint8 *newBuffer = (uint8*)realloc(fBuffer, fWriteIndex + extraSize); 367 if (newBuffer == NULL) 368 return false; 369 370 fAvailable = extraSize; 371 fBuffer = newBuffer; 372 return true; 373 } 374 375 #endif // REMOTE_MESSAGE_H 376