vncserver.hh revision 10839:10cac0f0f419
12SN/A/* 21762SN/A * Copyright (c) 2010, 2015 ARM Limited 32SN/A * All rights reserved 42SN/A * 52SN/A * The license below extends only to copyright in the software and shall 62SN/A * not be construed as granting a license to any other intellectual 72SN/A * property including but not limited to intellectual property relating 82SN/A * to a hardware implementation of the functionality of the software 92SN/A * licensed hereunder. You may use the software subject to the license 102SN/A * terms below provided that you ensure that this notice is replicated 112SN/A * unmodified and in its entirety in all distributions of the software, 122SN/A * modified or unmodified, in source code or in binary form. 132SN/A * 142SN/A * Redistribution and use in source and binary forms, with or without 152SN/A * modification, are permitted provided that the following conditions are 162SN/A * met: redistributions of source code must retain the above copyright 172SN/A * notice, this list of conditions and the following disclaimer; 182SN/A * redistributions in binary form must reproduce the above copyright 192SN/A * notice, this list of conditions and the following disclaimer in the 202SN/A * documentation and/or other materials provided with the distribution; 212SN/A * neither the name of the copyright holders nor the names of its 222SN/A * contributors may be used to endorse or promote products derived from 232SN/A * this software without specific prior written permission. 242SN/A * 252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282665Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316216Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326216Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346216Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35100SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367584SAli.Saidi@arm.com * 376214Snate@binkert.org * Authors: Ali Saidi 38100SN/A * William Wang 392SN/A */ 402020SN/A 412SN/A/** @file 422SN/A * Declaration of a VNC server 4350SN/A */ 442SN/A 452020SN/A#ifndef __BASE_VNC_VNC_SERVER_HH__ 462SN/A#define __BASE_VNC_VNC_SERVER_HH__ 4750SN/A 482SN/A#include <iostream> 4950SN/A 5050SN/A#include "base/vnc/vncinput.hh" 5150SN/A#include "base/bitmap.hh" 5250SN/A#include "base/circlebuf.hh" 5350SN/A#include "base/pollevent.hh" 5450SN/A#include "base/socket.hh" 5550SN/A#include "params/VncServer.hh" 5650SN/A#include "sim/sim_object.hh" 5750SN/A 5850SN/A/** @file 5950SN/A * Declaration of a VNC server 6050SN/A */ 612SN/A 622SN/Aclass VncServer : public VncInput 632SN/A{ 6450SN/A public: 6550SN/A 662020SN/A /** 672SN/A * \defgroup VncConstants A set of constants and structs from the VNC spec 6850SN/A * @{ 692SN/A */ 702SN/A /** Authentication modes */ 7150SN/A const static uint32_t AuthInvalid = 0; 7250SN/A const static uint32_t AuthNone = 1; 732020SN/A 7450SN/A /** Error conditions */ 752020SN/A const static uint32_t VncOK = 0; 7650SN/A 7750SN/A /** Server -> Client message IDs */ 787584SAli.Saidi@arm.com enum ServerMessages { 797584SAli.Saidi@arm.com ServerFrameBufferUpdate = 0, 807584SAli.Saidi@arm.com ServerSetColorMapEntries = 1, 817584SAli.Saidi@arm.com ServerBell = 2, 827584SAli.Saidi@arm.com ServerCutText = 3 837584SAli.Saidi@arm.com }; 847584SAli.Saidi@arm.com 857584SAli.Saidi@arm.com /** Encoding types */ 867584SAli.Saidi@arm.com enum EncodingTypes { 877584SAli.Saidi@arm.com EncodingRaw = 0, 887584SAli.Saidi@arm.com EncodingCopyRect = 1, 897584SAli.Saidi@arm.com EncodingHextile = 5, 907584SAli.Saidi@arm.com EncodingDesktopSize = -223 917584SAli.Saidi@arm.com }; 927584SAli.Saidi@arm.com 937584SAli.Saidi@arm.com /** keyboard/mouse support */ 947584SAli.Saidi@arm.com enum MouseEvents { 957584SAli.Saidi@arm.com MouseLeftButton = 0x1, 967584SAli.Saidi@arm.com MouseRightButton = 0x2, 977584SAli.Saidi@arm.com MouseMiddleButton = 0x4 987584SAli.Saidi@arm.com }; 992SN/A 1002020SN/A const char* vncVersion() const 10150SN/A { 102100SN/A return "RFB 003.008\n"; 1032SN/A } 10450SN/A 1052SN/A enum ConnectionState { 10650SN/A WaitForProtocolVersion, 10750SN/A WaitForSecurityResponse, 10850SN/A WaitForClientInit, 10950SN/A InitializationPhase, 11050SN/A NormalPhase 11150SN/A }; 11250SN/A 11350SN/A struct ServerInitMsg { 11450SN/A uint16_t fbWidth; 115100SN/A uint16_t fbHeight; 1162020SN/A PixelFormat px; 1171642SN/A uint32_t namelen; 1181642SN/A char name[2]; // just to put M5 in here 1191642SN/A } M5_ATTR_PACKED; 1201642SN/A 1211642SN/A struct FrameBufferUpdate { 1221642SN/A uint8_t type; 1231642SN/A uint8_t padding; 1241642SN/A uint16_t num_rects; 1251642SN/A } M5_ATTR_PACKED; 1261642SN/A 1271642SN/A struct FrameBufferRect { 1281642SN/A uint16_t x; 1291642SN/A uint16_t y; 1301642SN/A uint16_t width; 1311642SN/A uint16_t height; 1321642SN/A int32_t encoding; 1331642SN/A } M5_ATTR_PACKED; 1341642SN/A 1352020SN/A struct ServerCutText { 136100SN/A uint8_t type; 137100SN/A uint8_t padding[3]; 138100SN/A uint32_t length; 139100SN/A } M5_ATTR_PACKED; 140100SN/A 141100SN/A /** @} */ 142100SN/A 143100SN/A protected: 144100SN/A /** ListenEvent to accept a vnc client connection */ 145100SN/A class ListenEvent: public PollEvent 146100SN/A { 147100SN/A protected: 148100SN/A VncServer *vncserver; 149100SN/A 150100SN/A public: 151100SN/A ListenEvent(VncServer *vs, int fd, int e); 1522020SN/A void process(int revent); 153100SN/A }; 154100SN/A 1552020SN/A friend class ListenEvent; 156100SN/A ListenEvent *listenEvent; 157100SN/A 158100SN/A /** DataEvent to read data from vnc */ 1592020SN/A class DataEvent: public PollEvent 160100SN/A { 161100SN/A protected: 1622020SN/A VncServer *vncserver; 1631642SN/A 1641642SN/A public: 1651642SN/A DataEvent(VncServer *vs, int fd, int e); 1662020SN/A void process(int revent); 1671642SN/A }; 1681642SN/A 1692020SN/A friend class DataEvent; 170100SN/A DataEvent *dataEvent; 171100SN/A 17250SN/A int number; 17350SN/A int dataFd; // data stream file describer 1742020SN/A 17550SN/A ListenSocket listener; 176100SN/A 177100SN/A void listen(int port); 178100SN/A void accept(); 1792020SN/A void data(); 18050SN/A void detach(); 18150SN/A 18250SN/A public: 18350SN/A typedef VncServerParams Params; 1842020SN/A VncServer(const Params *p); 18550SN/A ~VncServer(); 1862020SN/A 18750SN/A // RFB 18850SN/A protected: 18950SN/A 19050SN/A /** The rfb prototol state the connection is in */ 1912020SN/A ConnectionState curState; 19250SN/A 1932020SN/A /** An update needs to be sent to the client. Without doing this the 19450SN/A * client will constantly request data that is pointless */ 1952SN/A bool sendUpdate; 1969091Sandreas.hansson@arm.com 19752SN/A /** The one and only pixel format we support */ 1989091Sandreas.hansson@arm.com PixelFormat pixelFormat; 19952SN/A 20052SN/A /** If the vnc client supports receiving raw data. It always should */ 20152SN/A bool supportsRawEnc; 20252SN/A 20352SN/A /** If the vnc client supports the desktop resize command */ 20452SN/A bool supportsResizeEnc; 2052021SN/A 20652SN/A protected: 2072021SN/A /** 20852SN/A * vnc client Interface 20952SN/A */ 21052SN/A 21152SN/A /** Send an error message to the client 21252SN/A * @param error_msg text to send describing the error 2132418SN/A */ 21452SN/A void sendError(const char* error_msg); 2152418SN/A 21652SN/A /** Read some data from the client 21752SN/A * @param buf the data to read 21852SN/A * @param len the amount of data to read 2192SN/A * @return length read 2202020SN/A */ 22150SN/A size_t read(uint8_t *buf, size_t len); 2225570Snate@binkert.org 2235570Snate@binkert.org /** Read len -1 bytes from the client into the buffer provided + 1 2245570Snate@binkert.org * assert that we read enough bytes. This function exists to handle 2252SN/A * reading all of the protocol structs above when we've already read 2262SN/A * the first byte which describes which one we're reading 2272SN/A * @param buf the address of the buffer to add one to and read data into 2282020SN/A * @param len the amount of data + 1 to read 22950SN/A * @return length read 23050SN/A */ 23150SN/A size_t read1(uint8_t *buf, size_t len); 2322SN/A 2332SN/A 2342020SN/A /** Templated version of the read function above to 23550SN/A * read simple data to the client 23650SN/A * @param val data to recv from the client 23750SN/A */ 2382SN/A template <typename T> size_t read(T* val); 2392SN/A 2402020SN/A 2412SN/A /** Write a buffer to the client. 2422SN/A * @param buf buffer to send 2432SN/A * @param len length of the buffer 2442SN/A * @return number of bytes sent 245105SN/A */ 2462SN/A size_t write(const uint8_t *buf, size_t len); 2472SN/A 2482SN/A /** Templated version of the write function above to 2492SN/A * write simple data to the client 2502SN/A * @param val data to send to the client 2512SN/A */ 2522SN/A template <typename T> size_t write(T* val); 2532SN/A 2546216Snate@binkert.org /** Send a string to the client 255 * @param str string to transmit 256 */ 257 size_t write(const char* str); 258 259 /** Check the client's protocol verion for compatibility and send 260 * the security types we support 261 */ 262 void checkProtocolVersion(); 263 264 /** Check that the security exchange was successful 265 */ 266 void checkSecurity(); 267 268 /** Send client our idea about what the frame buffer looks like */ 269 void sendServerInit(); 270 271 /** Send an error message to the client when something goes wrong 272 * @param error_msg error to send 273 */ 274 void sendError(std::string error_msg); 275 276 /** Send a updated frame buffer to the client. 277 * @todo this doesn't do anything smart and just sends the entire image 278 */ 279 void sendFrameBufferUpdate(); 280 281 /** Receive pixel foramt message from client and process it. */ 282 void setPixelFormat(); 283 284 /** Receive encodings message from client and process it. */ 285 void setEncodings(); 286 287 /** Receive message from client asking for updated frame buffer */ 288 void requestFbUpdate(); 289 290 /** Receive message from client providing new keyboard input */ 291 void recvKeyboardInput(); 292 293 /** Recv message from client providing new mouse movement or button click */ 294 void recvPointerInput(); 295 296 /** Receive message from client that there is text in it's paste buffer. 297 * This is a no-op at the moment, but perhaps we would want to be able to 298 * paste it at some point. 299 */ 300 void recvCutText(); 301 302 /** Tell the client that the frame buffer resized. This happens when the 303 * simulated system changes video modes (E.g. X11 starts). 304 */ 305 void sendFrameBufferResized(); 306 307 static const PixelConverter pixelConverter; 308 309 public: 310 void setDirty() M5_ATTR_OVERRIDE; 311 void frameBufferResized() M5_ATTR_OVERRIDE; 312}; 313 314#endif 315