blob: 490d556c7128ec4029fbaac697e3b8a5c0bf637d [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18//
19// SMsgWriter - class for writing RFB messages on the server side.
20//
21
22#ifndef __RFB_SMSGWRITER_H__
23#define __RFB_SMSGWRITER_H__
24
25#include <rdr/types.h>
26#include <rfb/encodings.h>
27#include <rfb/Encoder.h>
Constantin Kaplinsky46ba45a2007-08-31 21:31:34 +000028#include <rfb/PixelBuffer.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000029
30namespace rdr { class OutStream; }
31
32namespace rfb {
33
34 class PixelFormat;
35 class ConnParams;
36 class ImageGetter;
37 class ColourMap;
38 class Region;
39 class UpdateInfo;
Constantin Kaplinsky46ba45a2007-08-31 21:31:34 +000040 class JpegEncoder;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000041
42 class WriteSetCursorCallback {
43 public:
44 virtual void writeSetCursorCallback() = 0;
45 };
46
47 class SMsgWriter {
48 public:
49 virtual ~SMsgWriter();
50
51 // writeServerInit() must only be called at the appropriate time in the
52 // protocol initialisation.
53 virtual void writeServerInit()=0;
54
55 // Methods to write normal protocol messages
56
57 // writeSetColourMapEntries() writes a setColourMapEntries message, using
58 // the given ColourMap object to lookup the RGB values of the given range
59 // of colours.
60 virtual void writeSetColourMapEntries(int firstColour, int nColours,
61 ColourMap* cm);
62
63 // writeBell() and writeServerCutText() do the obvious thing.
64 virtual void writeBell();
65 virtual void writeServerCutText(const char* str, int len);
66
67 // setupCurrentEncoder() should be called before each framebuffer update,
68 // prior to calling getNumRects() or writeFramebufferUpdateStart().
69 void setupCurrentEncoder();
70
71 // getNumRects() computes the number of sub-rectangles that will compose a
72 // given rectangle, for current encoder.
73 int getNumRects(const Rect &r);
74
75 // writeSetDesktopSize() on a V3 writer won't actually write immediately,
76 // but will write the relevant pseudo-rectangle as part of the next update.
77 virtual bool writeSetDesktopSize()=0;
78
79 // Like setDesktopSize, we can't just write out a setCursor message
80 // immediately on a V3 writer. Instead of calling writeSetCursor()
81 // directly, you must call cursorChange(), and then invoke writeSetCursor()
82 // in response to the writeSetCursorCallback() callback. For a V3 writer
83 // this will happen when the next update is sent.
84 virtual void cursorChange(WriteSetCursorCallback* cb)=0;
85 virtual void writeSetCursor(int width, int height, const Point& hotspot,
86 void* data, void* mask)=0;
87 virtual void writeSetXCursor(int width, int height, int hotspotX,
88 int hotspotY, void* data, void* mask)=0;
89
90 // needFakeUpdate() returns true when an immediate update is needed in
91 // order to flush out setDesktopSize or setCursor pseudo-rectangles to the
92 // client.
93 virtual bool needFakeUpdate();
94
95 // writeFramebufferUpdate() writes a framebuffer update using the given
96 // UpdateInfo and ImageGetter. On a V3 writer this may have
97 // pseudo-rectangles for setDesktopSize and setCursor added to it, and so
98 // may invoke writeSetCursorCallback().
Constantin Kaplinskyfe6b5692007-08-31 15:44:12 +000099 //
Constantin Kaplinskyfe0db842007-08-31 21:14:45 +0000100 // FIXME: This function is not used because it incorrectly computes
Constantin Kaplinskyfe6b5692007-08-31 15:44:12 +0000101 // the number of rectangles if the Tight encoder is used.
102 /*
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000103 virtual void writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig,
104 Region* updatedRegion);
Constantin Kaplinskyfe6b5692007-08-31 15:44:12 +0000105 */
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000106
107 // writeRects() accepts an UpdateInfo (changed & copied regions) and an
108 // ImageGetter to fetch pixels from. It then calls writeCopyRect() and
109 // writeRect() as appropriate. writeFramebufferUpdateStart() must be used
110 // before the first writeRects() call and writeFrameBufferUpdateEnd() after
111 // the last one. It returns the actual region sent to the client, which
112 // may be smaller than the update passed in.
113 virtual void writeRects(const UpdateInfo& update, ImageGetter* ig,
114 Region* updatedRegion);
115
116 // To construct a framebuffer update you can call
117 // writeFramebufferUpdateStart(), followed by a number of writeCopyRect()s
118 // and writeRect()s, finishing with writeFramebufferUpdateEnd(). If you
119 // know the exact number of rectangles ahead of time you can specify it to
120 // writeFramebufferUpdateStart() which can be more efficient.
121 virtual void writeFramebufferUpdateStart(int nRects)=0;
122 virtual void writeFramebufferUpdateStart()=0;
123 virtual void writeFramebufferUpdateEnd()=0;
124
125 // writeRect() tries to write the given rectangle. If it is unable to
126 // write the whole rectangle it returns false and sets actual to the actual
127 // rectangle which was updated.
128 virtual bool writeRect(const Rect& r, ImageGetter* ig, Rect* actual);
129 virtual bool writeRect(const Rect& r, unsigned int encoding,
130 ImageGetter* ig, Rect* actual);
131
132 virtual void writeCopyRect(const Rect& r, int srcX, int srcY);
133
Constantin Kaplinsky46ba45a2007-08-31 21:31:34 +0000134 virtual void writeVideoRect(PixelBuffer *pb, const Rect& r);
135
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000136 virtual void startRect(const Rect& r, unsigned int enc)=0;
137 virtual void endRect()=0;
138
139 ConnParams* getConnParams() { return cp; }
140 rdr::OutStream* getOutStream() { return os; }
141 rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
142 int bpp();
143
144 int getUpdatesSent() { return updatesSent; }
145 int getRectsSent(int encoding) { return rectsSent[encoding]; }
146 int getBytesSent(int encoding) { return bytesSent[encoding]; }
147 int getRawBytesEquivalent() { return rawBytesEquivalent; }
148
149 int imageBufIdealSize;
150
151 protected:
152 SMsgWriter(ConnParams* cp, rdr::OutStream* os);
153
154 virtual void startMsg(int type)=0;
155 virtual void endMsg()=0;
156
157 ConnParams* cp;
158 rdr::OutStream* os;
159
160 Encoder* encoders[encodingMax+1];
Constantin Kaplinsky46ba45a2007-08-31 21:31:34 +0000161 JpegEncoder* jpegEncoder;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000162 int lenBeforeRect;
163 unsigned int currentEncoding;
164 int updatesSent;
165 int bytesSent[encodingMax+1];
166 int rectsSent[encodingMax+1];
167 int rawBytesEquivalent;
Constantin Kaplinsky46ba45a2007-08-31 21:31:34 +0000168 // FIXME: Gather statistics for JpegEncoder as well.
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000169
170 rdr::U8* imageBuf;
171 int imageBufSize;
172 };
173}
174#endif