blob: e9fc5a47394263587ffbab832fc4fe79aca975f4 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossman7638e9c2014-01-16 13:12:40 +01002 * Copyright 2009-2014 Pierre Ossman for Cendio AB
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00003 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This software is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this software; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19//
20// SMsgWriter - class for writing RFB messages on the server side.
21//
22
23#ifndef __RFB_SMSGWRITER_H__
24#define __RFB_SMSGWRITER_H__
25
26#include <rdr/types.h>
27#include <rfb/encodings.h>
Pierre Ossman04e62db2009-03-23 16:57:07 +000028#include <rfb/ScreenSet.h>
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000029
30namespace rdr { class OutStream; }
31
32namespace rfb {
33
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000034 class ConnParams;
Pierre Ossman7638e9c2014-01-16 13:12:40 +010035 class ScreenSet;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000036
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000037 class SMsgWriter {
38 public:
Pierre Ossman7638e9c2014-01-16 13:12:40 +010039 SMsgWriter(ConnParams* cp, rdr::OutStream* os);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000040 virtual ~SMsgWriter();
41
42 // writeServerInit() must only be called at the appropriate time in the
43 // protocol initialisation.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010044 void writeServerInit();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000045
46 // Methods to write normal protocol messages
47
48 // writeSetColourMapEntries() writes a setColourMapEntries message, using
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010049 // the given colour entries.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010050 void writeSetColourMapEntries(int firstColour, int nColours,
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010051 const rdr::U16 red[],
52 const rdr::U16 green[],
53 const rdr::U16 blue[]);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000054
55 // writeBell() and writeServerCutText() do the obvious thing.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010056 void writeBell();
57 void writeServerCutText(const char* str, int len);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000058
Pierre Ossmanc754cce2011-11-14 15:44:11 +000059 // writeFence() sends a new fence request or response to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010060 void writeFence(rdr::U32 flags, unsigned len, const char data[]);
Pierre Ossmanc754cce2011-11-14 15:44:11 +000061
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000062 // writeEndOfContinuousUpdates() indicates that we have left continuous
63 // updates mode.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010064 void writeEndOfContinuousUpdates();
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000065
Pierre Ossman7638e9c2014-01-16 13:12:40 +010066 // writeSetDesktopSize() won't actually write immediately, but will
67 // write the relevant pseudo-rectangle as part of the next update.
68 bool writeSetDesktopSize();
Pierre Ossman04e62db2009-03-23 16:57:07 +000069 // Same thing for the extended version. The first version queues up a
70 // generic update of the current server state, but the second queues a
71 // specific message.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010072 bool writeExtendedDesktopSize();
73 bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
74 int fb_width, int fb_height,
75 const ScreenSet& layout);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000076
Pierre Ossman7638e9c2014-01-16 13:12:40 +010077 bool writeSetDesktopName();
Peter Åstrandc39e0782009-01-15 12:21:42 +000078
Pierre Ossman126e5642014-02-13 14:40:25 +010079 // Like setDesktopSize, we can't just write out a cursor message
80 // immediately.
81 bool writeSetCursor();
82 bool writeSetXCursor();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000083
84 // needFakeUpdate() returns true when an immediate update is needed in
Pierre Ossmane9962f72009-04-23 12:31:42 +000085 // order to flush out pseudo-rectangles to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010086 bool needFakeUpdate();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000087
Pierre Ossmane9962f72009-04-23 12:31:42 +000088 // needNoDataUpdate() returns true when an update without any
89 // framebuffer changes need to be sent (using writeNoDataUpdate()).
90 // Commonly this is an update that modifies the size of the framebuffer
91 // or the screen layout.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010092 bool needNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +000093
94 // writeNoDataUpdate() write a framebuffer update containing only
95 // pseudo-rectangles.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010096 void writeNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +000097
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +010098 // writeFramebufferUpdateStart() initiates an update which you can fill
99 // in using writeCopyRect() and encoders. Finishing the update by calling
100 // writeFramebufferUpdateEnd().
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100101 void writeFramebufferUpdateStart(int nRects);
102 void writeFramebufferUpdateEnd();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000103
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100104 // There is no explicit encoder for CopyRect rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100105 void writeCopyRect(const Rect& r, int srcX, int srcY);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000106
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100107 // Encoders should call these to mark the start and stop of individual
108 // rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100109 void startRect(const Rect& r, int enc);
110 void endRect();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000111
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000112 rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000113
114 int getUpdatesSent() { return updatesSent; }
115 int getRectsSent(int encoding) { return rectsSent[encoding]; }
116 int getBytesSent(int encoding) { return bytesSent[encoding]; }
DRC887c5fd2011-08-19 03:13:47 +0000117 rdr::U64 getRawBytesEquivalent() { return rawBytesEquivalent; }
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000118
119 int imageBufIdealSize;
120
121 protected:
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100122 void startMsg(int type);
123 void endMsg();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000124
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100125 void writePseudoRects();
126 void writeNoDataRects();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000127
Pierre Ossmanc0b1aa02014-01-16 13:39:05 +0100128 void writeSetDesktopSizeRect(int width, int height);
129 void writeExtendedDesktopSizeRect(rdr::U16 reason, rdr::U16 result,
130 int fb_width, int fb_height,
131 const ScreenSet& layout);
132 void writeSetDesktopNameRect(const char *name);
Pierre Ossman126e5642014-02-13 14:40:25 +0100133 void writeSetCursorRect(int width, int height,
134 int hotspotX, int hotspotY,
135 const void* data, const void* mask);
136 void writeSetXCursorRect(int width, int height,
137 int hotspotX, int hotspotY,
138 const rdr::U8 pix0[], const rdr::U8 pix1[],
139 const void* data, const void* mask);
Pierre Ossmanc0b1aa02014-01-16 13:39:05 +0100140
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000141 ConnParams* cp;
142 rdr::OutStream* os;
143
Peter Åstrand98fe98c2010-02-10 07:43:02 +0000144 int currentEncoding;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100145
146 int nRectsInUpdate;
147 int nRectsInHeader;
148
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100149 bool needSetDesktopSize;
150 bool needExtendedDesktopSize;
151 bool needSetDesktopName;
152 bool needLastRect;
Pierre Ossman126e5642014-02-13 14:40:25 +0100153 bool needSetCursor;
154 bool needSetXCursor;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100155
156 int lenBeforeRect;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000157 int updatesSent;
158 int bytesSent[encodingMax+1];
159 int rectsSent[encodingMax+1];
DRC887c5fd2011-08-19 03:13:47 +0000160 rdr::U64 rawBytesEquivalent;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000161
162 rdr::U8* imageBuf;
163 int imageBufSize;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100164
165 typedef struct {
166 rdr::U16 reason, result;
167 int fb_width, fb_height;
168 ScreenSet layout;
169 } ExtendedDesktopSizeMsg;
170
171 std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000172 };
173}
174#endif