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 25class BBitmap; 26class BFont; 27class BGradient; 28class BView; 29class DrawState; 30class Pattern; 31class RemotePainter; 32class ServerBitmap; 33class ServerCursor; 34class ServerFont; 35class ViewLineArrayInfo; 36 37enum { 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 128class RemoteMessage { 129public: 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 185private: 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 199inline 200RemoteMessage::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 213inline 214RemoteMessage::~RemoteMessage() 215{ 216 if (fWriteIndex > 0) 217 Flush(); 218 free(fBuffer); 219} 220 221 222inline void 223RemoteMessage::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 235inline status_t 236RemoteMessage::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 250template<typename T> 251inline void 252RemoteMessage::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 263inline void 264RemoteMessage::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 276inline void 277RemoteMessage::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 287template<typename T> 288inline void 289RemoteMessage::AddList(const T* array, int32 count) 290{ 291 for (int32 i = 0; i < count; i++) 292 Add(array[i]); 293} 294 295 296template<typename T> 297inline status_t 298RemoteMessage::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 315inline status_t 316RemoteMessage::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 336template<typename T> 337inline status_t 338RemoteMessage::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 350inline bool 351RemoteMessage::_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