xref: /haiku/src/servers/app/drawing/interface/remote/RemoteMessage.h (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
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