2 * Copyright (c) 2010 ARM Limited
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 * Declaration of a VNC server
45 #ifndef __DEV_VNC_SERVER_HH__
46 #define __DEV_VNC_SERVER_HH__
50 #include "base/vnc/convert.hh"
51 #include "base/bitmap.hh"
52 #include "base/circlebuf.hh"
53 #include "base/pollevent.hh"
54 #include "base/socket.hh"
55 #include "cpu/intr_control.hh"
56 #include "params/VncServer.hh"
57 #include "sim/sim_object.hh"
61 * A device that expects to receive input from the vnc server should derrive
62 * (through mulitple inheritence if necessary from VncKeyboard or VncMouse
63 * and call setKeyboard() or setMouse() respectively on the vnc server.
69 * Called when the vnc server receives a key press event from the
71 * @param key the key passed is an x11 keysym
72 * @param down is the key now down or up?
74 virtual void keyPress(uint32_t key, bool down) = 0;
81 * called whenever the mouse moves or it's button state changes
82 * buttons is a simple mask with each button (0-8) corresponding to
83 * a bit position in the byte with 1 being down and 0 being up
84 * @param x the x position of the mouse
85 * @param y the y position of the mouse
86 * @param buttos the button state as described above
88 virtual void mouseAt(uint16_t x, uint16_t y, uint8_t buttons) = 0;
91 class VncServer : public SimObject
96 * \defgroup VncConstants A set of constants and structs from the VNC spec
99 /** Authentication modes */
100 const static uint32_t AuthInvalid = 0;
101 const static uint32_t AuthNone = 1;
103 /** Error conditions */
104 const static uint32_t VncOK = 0;
106 /** Client -> Server message IDs */
107 enum ClientMessages {
108 ClientSetPixelFormat = 0,
109 ClientSetEncodings = 2,
110 ClientFrameBufferUpdate = 3,
112 ClientPointerEvent = 5,
116 /** Server -> Client message IDs */
117 enum ServerMessages {
118 ServerFrameBufferUpdate = 0,
119 ServerSetColorMapEntries = 1,
124 /** Encoding types */
127 EncodingCopyRect = 1,
129 EncodingDesktopSize = -223
132 /** keyboard/mouse support */
134 MouseLeftButton = 0x1,
135 MouseRightButton = 0x2,
136 MouseMiddleButton = 0x4
139 const char* vncVersion() const
141 return "RFB 003.008\n";
144 enum ConnectionState {
145 WaitForProtocolVersion,
146 WaitForSecurityResponse,
166 struct ServerInitMsg {
171 char name[2]; // just to put M5 in here
174 struct PixelFormatMessage {
180 struct PixelEncodingsMessage {
183 uint16_t num_encodings;
186 struct FrameBufferUpdateReq {
195 struct KeyEventMessage {
202 struct PointerEventMessage {
209 struct ClientCutTextMessage {
215 struct FrameBufferUpdate {
221 struct FrameBufferRect {
229 struct ServerCutText {
238 /** ListenEvent to accept a vnc client connection */
239 class ListenEvent: public PollEvent
242 VncServer *vncserver;
245 ListenEvent(VncServer *vs, int fd, int e);
246 void process(int revent);
249 friend class ListenEvent;
250 ListenEvent *listenEvent;
252 /** DataEvent to read data from vnc */
253 class DataEvent: public PollEvent
256 VncServer *vncserver;
259 DataEvent(VncServer *vs, int fd, int e);
260 void process(int revent);
263 friend class DataEvent;
264 DataEvent *dataEvent;
267 int dataFd; // data stream file describer
269 ListenSocket listener;
271 void listen(int port);
277 typedef VncServerParams Params;
278 VncServer(const Params *p);
284 /** The rfb prototol state the connection is in */
285 ConnectionState curState;
287 /** the width of the frame buffer we are sending to the client */
288 uint16_t _videoWidth;
290 /** the height of the frame buffer we are sending to the client */
291 uint16_t _videoHeight;
293 /** pointer to the actual data that is stored in the frame buffer device */
296 /** The device to notify when we get key events */
297 VncKeyboard *keyboard;
299 /** The device to notify when we get mouse events */
302 /** An update needs to be sent to the client. Without doing this the
303 * client will constantly request data that is pointless */
306 /** The one and only pixel format we support */
307 PixelFormat pixelFormat;
309 /** If the vnc client supports receiving raw data. It always should */
312 /** If the vnc client supports the desktop resize command */
313 bool supportsResizeEnc;
315 /** The mode of data we're getting frame buffer in */
316 VideoConvert::Mode videoMode;
318 /** The video converter that transforms data for us */
321 /** Flag indicating whether to capture snapshots of frame buffer or not */
324 /** Current frame number being captured to a file */
325 int captureCurrentFrame;
327 /** Directory to store captured frames to */
328 std::string captureOutputDirectory;
330 /** Computed hash of the last captured frame */
331 uint64_t captureLastHash;
333 /** Cached bitmap object for writing out frame buffers to file */
334 Bitmap *captureBitmap;
337 /** Captures the current frame buffer to a file */
338 void captureFrameBuffer();
341 * vnc client Interface
344 /** Send an error message to the client
345 * @param error_msg text to send describing the error
347 void sendError(const char* error_msg);
349 /** Read some data from the client
350 * @param buf the data to read
351 * @param len the amount of data to read
352 * @return length read
354 size_t read(uint8_t *buf, size_t len);
356 /** Read len -1 bytes from the client into the buffer provided + 1
357 * assert that we read enough bytes. This function exists to handle
358 * reading all of the protocol structs above when we've already read
359 * the first byte which describes which one we're reading
360 * @param buf the address of the buffer to add one to and read data into
361 * @param len the amount of data + 1 to read
362 * @return length read
364 size_t read1(uint8_t *buf, size_t len);
367 /** Templated version of the read function above to
368 * read simple data to the client
369 * @param val data to recv from the client
371 template <typename T> size_t read(T* val);
374 /** Write a buffer to the client.
375 * @param buf buffer to send
376 * @param len length of the buffer
377 * @return number of bytes sent
379 size_t write(const uint8_t *buf, size_t len);
381 /** Templated version of the write function above to
382 * write simple data to the client
383 * @param val data to send to the client
385 template <typename T> size_t write(T* val);
387 /** Send a string to the client
388 * @param str string to transmit
390 size_t write(const char* str);
392 /** Check the client's protocol verion for compatibility and send
393 * the security types we support
395 void checkProtocolVersion();
397 /** Check that the security exchange was successful
399 void checkSecurity();
401 /** Send client our idea about what the frame buffer looks like */
402 void sendServerInit();
404 /** Send an error message to the client when something goes wrong
405 * @param error_msg error to send
407 void sendError(std::string error_msg);
409 /** Send a updated frame buffer to the client.
410 * @todo this doesn't do anything smart and just sends the entire image
412 void sendFrameBufferUpdate();
414 /** Receive pixel foramt message from client and process it. */
415 void setPixelFormat();
417 /** Receive encodings message from client and process it. */
420 /** Receive message from client asking for updated frame buffer */
421 void requestFbUpdate();
423 /** Receive message from client providing new keyboard input */
424 void recvKeyboardInput();
426 /** Recv message from client providing new mouse movement or button click */
427 void recvPointerInput();
429 /** Receive message from client that there is text in it's paste buffer.
430 * This is a no-op at the moment, but perhaps we would want to be able to
431 * paste it at some point.
435 /** Tell the client that the frame buffer resized. This happens when the
436 * simulated system changes video modes (E.g. X11 starts).
438 void sendFrameBufferResized();
441 /** Set the address of the frame buffer we are going to show.
442 * To avoid copying, just have the display controller
443 * tell us where the data is instead of constanly copying it around
444 * @param rfb frame buffer that we're going to use
447 setFramebufferAddr(uint8_t* rfb)
452 /** Set up the device that would like to receive notifications when keys are
453 * pressed in the vnc client keyboard
454 * @param _keyboard an object that derrives from VncKeyboard
456 void setKeyboard(VncKeyboard *_keyboard) { keyboard = _keyboard; }
458 /** Setup the device that would like to receive notifications when mouse
459 * movements or button presses are received from the vnc client.
460 * @param _mouse an object that derrives from VncMouse
462 void setMouse(VncMouse *_mouse) { mouse = _mouse; }
464 /** The frame buffer uses this call to notify the vnc server that
465 * the frame buffer has been updated and a new image needs to be sent to the
473 captureFrameBuffer();
474 sendFrameBufferUpdate();
477 /** What is the width of the screen we're displaying.
478 * This is used for pointer/tablet devices that need to know to calculate
479 * the correct value to send to the device driver.
480 * @return the width of the simulated screen
482 uint16_t videoWidth() { return _videoWidth; }
484 /** What is the height of the screen we're displaying.
485 * This is used for pointer/tablet devices that need to know to calculate
486 * the correct value to send to the device driver.
487 * @return the height of the simulated screen
489 uint16_t videoHeight() { return _videoHeight; }
491 /** Set the mode of the data the frame buffer will be sending us
492 * @param mode the mode
494 void setFrameBufferParams(VideoConvert::Mode mode, int width, int height);