blob: 2cea44d1e28d8e234438df29525739ccf181a4da [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
Pierre Ossman0ff26552016-02-05 10:26:56 +01002 * Copyright 2009-2019 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
Pierre Ossman0d3ce872018-06-18 15:59:00 +020034 class ClientParams;
Pierre Ossman96728352018-06-20 11:35:05 +020035 class PixelFormat;
Steve Kondik1f5d4b12017-07-08 02:00:49 -070036 struct ScreenSet;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000037
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000038 class SMsgWriter {
39 public:
Pierre Ossman0d3ce872018-06-18 15:59:00 +020040 SMsgWriter(ClientParams* client, rdr::OutStream* os);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000041 virtual ~SMsgWriter();
42
43 // writeServerInit() must only be called at the appropriate time in the
44 // protocol initialisation.
Pierre Ossman96728352018-06-20 11:35:05 +020045 void writeServerInit(rdr::U16 width, rdr::U16 height,
46 const PixelFormat& pf, const char* name);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000047
48 // Methods to write normal protocol messages
49
50 // writeSetColourMapEntries() writes a setColourMapEntries message, using
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010051 // the given colour entries.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010052 void writeSetColourMapEntries(int firstColour, int nColours,
Pierre Ossmanb6b4dc62014-01-20 15:05:21 +010053 const rdr::U16 red[],
54 const rdr::U16 green[],
55 const rdr::U16 blue[]);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000056
Pierre Ossman0ff26552016-02-05 10:26:56 +010057 // writeBell() does the obvious thing.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010058 void writeBell();
Pierre Ossman0ff26552016-02-05 10:26:56 +010059
Pierre Ossman66f1db52019-05-02 12:32:03 +020060 void writeServerCutText(const char* str);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000061
Pierre Ossman0ff26552016-02-05 10:26:56 +010062 void writeClipboardCaps(rdr::U32 caps, const rdr::U32* lengths);
63 void writeClipboardRequest(rdr::U32 flags);
64 void writeClipboardPeek(rdr::U32 flags);
65 void writeClipboardNotify(rdr::U32 flags);
66 void writeClipboardProvide(rdr::U32 flags, const size_t* lengths,
67 const rdr::U8* const* data);
68
Pierre Ossmanc754cce2011-11-14 15:44:11 +000069 // writeFence() sends a new fence request or response to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010070 void writeFence(rdr::U32 flags, unsigned len, const char data[]);
Pierre Ossmanc754cce2011-11-14 15:44:11 +000071
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000072 // writeEndOfContinuousUpdates() indicates that we have left continuous
73 // updates mode.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010074 void writeEndOfContinuousUpdates();
Pierre Ossmanc898d9a2011-11-14 16:22:23 +000075
Pierre Ossman2daba9b2018-10-29 10:03:37 +010076 // writeDesktopSize() won't actually write immediately, but will
Pierre Ossman7638e9c2014-01-16 13:12:40 +010077 // write the relevant pseudo-rectangle as part of the next update.
Pierre Ossman2daba9b2018-10-29 10:03:37 +010078 void writeDesktopSize(rdr::U16 reason, rdr::U16 result=0);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000079
Pierre Ossman7b8bc432018-10-29 10:03:37 +010080 void writeSetDesktopName();
Peter Åstrandc39e0782009-01-15 12:21:42 +000081
Pierre Ossman126e5642014-02-13 14:40:25 +010082 // Like setDesktopSize, we can't just write out a cursor message
83 // immediately.
Pierre Ossman2daba9b2018-10-29 10:03:37 +010084 void writeCursor();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000085
Pierre Ossmanb45a84f2016-12-12 16:59:15 +010086 // Same for LED state message
Pierre Ossman7b8bc432018-10-29 10:03:37 +010087 void writeLEDState();
Pierre Ossmanb45a84f2016-12-12 16:59:15 +010088
Pierre Ossman5ae28212017-05-16 14:30:38 +020089 // And QEMU keyboard event handshake
Pierre Ossman7b8bc432018-10-29 10:03:37 +010090 void writeQEMUKeyEvent();
Pierre Ossman5ae28212017-05-16 14:30:38 +020091
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000092 // needFakeUpdate() returns true when an immediate update is needed in
Pierre Ossmane9962f72009-04-23 12:31:42 +000093 // order to flush out pseudo-rectangles to the client.
Pierre Ossman7638e9c2014-01-16 13:12:40 +010094 bool needFakeUpdate();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000095
Pierre Ossmane9962f72009-04-23 12:31:42 +000096 // needNoDataUpdate() returns true when an update without any
97 // framebuffer changes need to be sent (using writeNoDataUpdate()).
98 // Commonly this is an update that modifies the size of the framebuffer
99 // or the screen layout.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100100 bool needNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +0000101
102 // writeNoDataUpdate() write a framebuffer update containing only
103 // pseudo-rectangles.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100104 void writeNoDataUpdate();
Pierre Ossmane9962f72009-04-23 12:31:42 +0000105
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100106 // writeFramebufferUpdateStart() initiates an update which you can fill
107 // in using writeCopyRect() and encoders. Finishing the update by calling
108 // writeFramebufferUpdateEnd().
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100109 void writeFramebufferUpdateStart(int nRects);
110 void writeFramebufferUpdateEnd();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000111
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100112 // There is no explicit encoder for CopyRect rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100113 void writeCopyRect(const Rect& r, int srcX, int srcY);
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000114
Pierre Ossmanfdba3fe2014-01-31 13:12:18 +0100115 // Encoders should call these to mark the start and stop of individual
116 // rects.
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100117 void startRect(const Rect& r, int enc);
118 void endRect();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000119
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000120 protected:
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100121 void startMsg(int type);
122 void endMsg();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000123
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100124 void writePseudoRects();
125 void writeNoDataRects();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000126
Pierre Ossmanc0b1aa02014-01-16 13:39:05 +0100127 void writeSetDesktopSizeRect(int width, int height);
128 void writeExtendedDesktopSizeRect(rdr::U16 reason, rdr::U16 result,
129 int fb_width, int fb_height,
130 const ScreenSet& layout);
131 void writeSetDesktopNameRect(const char *name);
Pierre Ossman126e5642014-02-13 14:40:25 +0100132 void writeSetCursorRect(int width, int height,
133 int hotspotX, int hotspotY,
134 const void* data, const void* mask);
135 void writeSetXCursorRect(int width, int height,
136 int hotspotX, int hotspotY,
Pierre Ossman126e5642014-02-13 14:40:25 +0100137 const void* data, const void* mask);
Pierre Ossman8053c8e2017-02-21 12:59:04 +0100138 void writeSetCursorWithAlphaRect(int width, int height,
139 int hotspotX, int hotspotY,
140 const rdr::U8* data);
Pierre Ossman4a6266f2018-11-05 16:28:18 +0100141 void writeSetVMwareCursorRect(int width, int height,
142 int hotspotX, int hotspotY,
143 const rdr::U8* data);
Pierre Ossmanb45a84f2016-12-12 16:59:15 +0100144 void writeLEDStateRect(rdr::U8 state);
Pierre Ossman5ae28212017-05-16 14:30:38 +0200145 void writeQEMUKeyEventRect();
Pierre Ossmanc0b1aa02014-01-16 13:39:05 +0100146
Pierre Ossman0d3ce872018-06-18 15:59:00 +0200147 ClientParams* client;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000148 rdr::OutStream* os;
149
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100150 int nRectsInUpdate;
151 int nRectsInHeader;
152
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100153 bool needSetDesktopName;
Pierre Ossman2daba9b2018-10-29 10:03:37 +0100154 bool needCursor;
Pierre Ossmanb45a84f2016-12-12 16:59:15 +0100155 bool needLEDState;
Pierre Ossman5ae28212017-05-16 14:30:38 +0200156 bool needQEMUKeyEvent;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100157
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100158 typedef struct {
159 rdr::U16 reason, result;
Pierre Ossman7638e9c2014-01-16 13:12:40 +0100160 } ExtendedDesktopSizeMsg;
161
162 std::list<ExtendedDesktopSizeMsg> extendedDesktopSizeMsgs;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000163 };
164}
165#endif