blob: c3ee45771ba09a697007287abc4eca6bc7c8df22 [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
37 class WriteSetCursorCallback {
38 public:
39 virtual void writeSetCursorCallback() = 0;
40 };
41
42 class SMsgWriter {
43 public:
Pierre Ossman7638e9c2014-01-16 13:12:40 +010044 SMsgWriter(ConnParams* cp, rdr::OutStream* os);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000045 virtual ~SMsgWriter();
46
47 // writeServerInit() must only be called at the appropriate time in the
48 // protocol initialisation.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010049 void writeServerInit();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000050
51 // Methods to write normal protocol messages
52
53 // writeSetColourMapEntries() writes a setColourMapEntries message, using
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010054 // the given colour entries.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010055 void writeSetColourMapEntries(int firstColour, int nColours,
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010056 const rdr::U16 red[],
57 const rdr::U16 green[],
58 const rdr::U16 blue[]);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000059
60 // writeBell() and writeServerCutText() do the obvious thing.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010061 void writeBell();
62 void writeServerCutText(const char* str, int len);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000063
Pierre Ossmanc754cce2011-11-14 15:44:11 +000064 // writeFence() sends a new fence request or response to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010065 void writeFence(rdr::U32 flags, unsigned len, const char data[]);
Pierre Ossmanc754cce2011-11-14 15:44:11 +000066
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000067 // writeEndOfContinuousUpdates() indicates that we have left continuous
68 // updates mode.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010069 void writeEndOfContinuousUpdates();
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000070
Pierre Ossman7638e9c2014-01-16 13:12:40 +010071 // writeSetDesktopSize() won't actually write immediately, but will
72 // write the relevant pseudo-rectangle as part of the next update.
73 bool writeSetDesktopSize();
Pierre Ossman04e62db2009-03-23 16:57:07 +000074 // Same thing for the extended version. The first version queues up a
75 // generic update of the current server state, but the second queues a
76 // specific message.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010077 bool writeExtendedDesktopSize();
78 bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result,
79 int fb_width, int fb_height,
80 const ScreenSet& layout);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000081
Pierre Ossman7638e9c2014-01-16 13:12:40 +010082 bool writeSetDesktopName();
Peter Åstrandc39e0782009-01-15 12:21:42 +000083
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000084 // Like setDesktopSize, we can't just write out a setCursor message
Pierre Ossman7638e9c2014-01-16 13:12:40 +010085 // immediately. Instead of calling writeSetCursor() directly,
86 // you must call cursorChange(), and then invoke writeSetCursor()
87 // in response to the writeSetCursorCallback() callback. This will
88 // happen when the next update is sent.
89 void cursorChange(WriteSetCursorCallback* cb);
90 void writeSetCursor(int width, int height, const Point& hotspot,
91 void* data, void* mask);
92 void writeSetXCursor(int width, int height, int hotspotX, int hotspotY,
93 void* data, void* mask);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000094
95 // needFakeUpdate() returns true when an immediate update is needed in
Pierre Ossmane9962f72009-04-23 12:31:42 +000096 // order to flush out pseudo-rectangles to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010097 bool needFakeUpdate();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000098
Pierre Ossmane9962f72009-04-23 12:31:42 +000099 // needNoDataUpdate() returns true when an update without any
100 // framebuffer changes need to be sent (using writeNoDataUpdate()).
101 // Commonly this is an update that modifies the size of the framebuffer
102 // or the screen layout.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100103 bool needNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +0000104
105 // writeNoDataUpdate() write a framebuffer update containing only
106 // pseudo-rectangles.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100107 void writeNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +0000108
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100109 // writeFramebufferUpdateStart() initiates an update which you can fill
110 // in using writeCopyRect() and encoders. Finishing the update by calling
111 // writeFramebufferUpdateEnd().
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100112 void writeFramebufferUpdateStart(int nRects);
113 void writeFramebufferUpdateEnd();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000114
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100115 // There is no explicit encoder for CopyRect rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100116 void writeCopyRect(const Rect& r, int srcX, int srcY);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000117
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100118 // Encoders should call these to mark the start and stop of individual
119 // rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100120 void startRect(const Rect& r, int enc);
121 void endRect();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000122
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000123 rdr::U8* getImageBuf(int required, int requested=0, int* nPixels=0);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000124
125 int getUpdatesSent() { return updatesSent; }
126 int getRectsSent(int encoding) { return rectsSent[encoding]; }
127 int getBytesSent(int encoding) { return bytesSent[encoding]; }
DRC887c5fd2011-08-19 03:13:47 +0000128 rdr::U64 getRawBytesEquivalent() { return rawBytesEquivalent; }
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000129
130 int imageBufIdealSize;
131
132 protected:
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100133 void startMsg(int type);
134 void endMsg();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000135
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100136 void writePseudoRects();
137 void writeNoDataRects();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000138
Pierre Ossmanc0b1aa02014-01-16 13:39:05 +0100139 void writeSetDesktopSizeRect(int width, int height);
140 void writeExtendedDesktopSizeRect(rdr::U16 reason, rdr::U16 result,
141 int fb_width, int fb_height,
142 const ScreenSet& layout);
143 void writeSetDesktopNameRect(const char *name);
144
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000145 ConnParams* cp;
146 rdr::OutStream* os;
147
Peter Åstrand98fe98c2010-02-10 07:43:02 +0000148 int currentEncoding;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100149
150 int nRectsInUpdate;
151 int nRectsInHeader;
152
153 WriteSetCursorCallback* wsccb;
154
155 bool needSetDesktopSize;
156 bool needExtendedDesktopSize;
157 bool needSetDesktopName;
158 bool needLastRect;
159
160 int lenBeforeRect;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000161 int updatesSent;
162 int bytesSent[encodingMax+1];
163 int rectsSent[encodingMax+1];
DRC887c5fd2011-08-19 03:13:47 +0000164 rdr::U64 rawBytesEquivalent;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000165
166 rdr::U8* imageBuf;
167 int imageBufSize;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100168
169 typedef struct {
170 rdr::U16 reason, result;
171 int fb_width, fb_height;
172 ScreenSet layout;
173 } ExtendedDesktopSizeMsg;
174
175 std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000176 };
177}
178#endif