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);
Code()143 uint16 Code() { return fCode; }
DataLeft()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
RemoteMessage(StreamingRingBuffer * source,StreamingRingBuffer * target)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
~RemoteMessage()220 RemoteMessage::~RemoteMessage()
221 {
222 if (fWriteIndex > 0)
223 Flush();
224 free(fBuffer);
225 }
226
227
228 inline void
Start(uint16 code)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
Flush()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
Add(const T & value)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
AddString(const char * string,size_t length)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
AddRegion(const BRegion & region)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
AddList(const T * array,int32 count)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
Read(T & value)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
ReadRegion(BRegion & region)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
ReadList(T * array,int32 count)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
_MakeSpace(size_t size)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