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