blob: ed8ad0ef54e3ebd47c79f36998bc63a8f9efab08 [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>
28
29namespace rdr { class OutStream; }
30
31namespace rfb {
32
33 class PixelFormat;
34 class ConnParams;
35 class ImageGetter;
36 class ColourMap;
37 class Region;
38 class UpdateInfo;
39
40 class WriteSetCursorCallback {
41 public:
42 virtual void writeSetCursorCallback() = 0;
43 };
44
45 class SMsgWriter {
46 public:
47 virtual ~SMsgWriter();
48
49 // writeServerInit() must only be called at the appropriate time in the
50 // protocol initialisation.
51 virtual void writeServerInit()=0;
52
53 // Methods to write normal protocol messages
54
55 // writeSetColourMapEntries() writes a setColourMapEntries message, using
56 // the given ColourMap object to lookup the RGB values of the given range
57 // of colours.
58 virtual void writeSetColourMapEntries(int firstColour, int nColours,
59 ColourMap* cm);
60
61 // writeBell() and writeServerCutText() do the obvious thing.
62 virtual void writeBell();
63 virtual void writeServerCutText(const char* str, int len);
64
65 // setupCurrentEncoder() should be called before each framebuffer update,
66 // prior to calling getNumRects() or writeFramebufferUpdateStart().
67 void setupCurrentEncoder();
68
69 // getNumRects() computes the number of sub-rectangles that will compose a
70 // given rectangle, for current encoder.
71 int getNumRects(const Rect &r);
72
73 // writeSetDesktopSize() on a V3 writer won't actually write immediately,
74 // but will write the relevant pseudo-rectangle as part of the next update.
75 virtual bool writeSetDesktopSize()=0;
76
77 // Like setDesktopSize, we can't just write out a setCursor message
78 // immediately on a V3 writer. Instead of calling writeSetCursor()
79 // directly, you must call cursorChange(), and then invoke writeSetCursor()
80 // in response to the writeSetCursorCallback() callback. For a V3 writer
81 // this will happen when the next update is sent.
82 virtual void cursorChange(WriteSetCursorCallback* cb)=0;
83 virtual void writeSetCursor(int width, int height, const Point& hotspot,
84 void* data, void* mask)=0;
85 virtual void writeSetXCursor(int width, int height, int hotspotX,
86 int hotspotY, void* data, void* mask)=0;
87
88 // needFakeUpdate() returns true when an immediate update is needed in
89 // order to flush out setDesktopSize or setCursor pseudo-rectangles to the
90 // client.
91 virtual bool needFakeUpdate();
92
93 // writeFramebufferUpdate() writes a framebuffer update using the given
94 // UpdateInfo and ImageGetter. On a V3 writer this may have
95 // pseudo-rectangles for setDesktopSize and setCursor added to it, and so
96 // may invoke writeSetCursorCallback().
97 virtual void writeFramebufferUpdate(const UpdateInfo& ui, ImageGetter* ig,
98 Region* updatedRegion);
99
100 // writeRects() accepts an UpdateInfo (changed & copied regions) and an
101 // ImageGetter to fetch pixels from. It then calls writeCopyRect() and
102 // writeRect() as appropriate. writeFramebufferUpdateStart() must be used
103 // before the first writeRects() call and writeFrameBufferUpdateEnd() after
104 // the last one. It returns the actual region sent to the client, which
105 // may be smaller than the update passed in.
106 virtual void writeRects(const UpdateInfo& update, ImageGetter* ig,
107 Region* updatedRegion);
108
109 // To construct a framebuffer update you can call
110 // writeFramebufferUpdateStart(), followed by a number of writeCopyRect()s
111 // and writeRect()s, finishing with writeFramebufferUpdateEnd(). If you
112 // know the exact number of rectangles ahead of time you can specify it to
113 // writeFramebufferUpdateStart() which can be more efficient.
114 virtual void writeFramebufferUpdateStart(int nRects)=0;
115 virtual void writeFramebufferUpdateStart()=0;
116 virtual void writeFramebufferUpdateEnd()=0;
117
118 // writeRect() tries to write the given rectangle. If it is unable to
119 // write the whole rectangle it returns false and sets actual to the actual
120 // rectangle which was updated.
121 virtual bool writeRect(const Rect& r, ImageGetter* ig, Rect* actual);
122 virtual bool writeRect(const Rect& r, unsigned int encoding,
123 ImageGetter* ig, Rect* actual);
124
125 virtual void writeCopyRect(const Rect& r, int srcX, int srcY);
126
127 virtual void startRect(const Rect& r, unsigned int enc)=0;
128 virtual void endRect()=0;
129
130 ConnParams* getConnParams() { return cp; }
131 rdr::OutStream* getOutStream() { return os; }
132 rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
133 int bpp();
134
135 int getUpdatesSent() { return updatesSent; }
136 int getRectsSent(int encoding) { return rectsSent[encoding]; }
137 int getBytesSent(int encoding) { return bytesSent[encoding]; }
138 int getRawBytesEquivalent() { return rawBytesEquivalent; }
139
140 int imageBufIdealSize;
141
142 protected:
143 SMsgWriter(ConnParams* cp, rdr::OutStream* os);
144
145 virtual void startMsg(int type)=0;
146 virtual void endMsg()=0;
147
148 ConnParams* cp;
149 rdr::OutStream* os;
150
151 Encoder* encoders[encodingMax+1];
152 int lenBeforeRect;
153 unsigned int currentEncoding;
154 int updatesSent;
155 int bytesSent[encodingMax+1];
156 int rectsSent[encodingMax+1];
157 int rawBytesEquivalent;
158
159 rdr::U8* imageBuf;
160 int imageBufSize;
161 };
162}
163#endif