From 55787cc0d0ecdbd060f7ee1caaaab90d2482eb67 Mon Sep 17 00:00:00 2001 From: Chander Sudanthi Date: Fri, 2 Nov 2012 11:32:00 -0500 Subject: base: split out the VncServer into a VncInput and Server classes This patch adds a VncInput base class which VncServer inherits from. Another class can implement the same interface and be used instead of the VncServer, for example a class that replays Vnc traffic. --HG-- rename : src/base/vnc/VncServer.py => src/base/vnc/Vnc.py rename : src/base/vnc/vncserver.cc => src/base/vnc/vncinput.cc rename : src/base/vnc/vncserver.hh => src/base/vnc/vncinput.hh --- src/base/vnc/SConscript | 3 +- src/base/vnc/Vnc.py | 48 +++++++++ src/base/vnc/VncServer.py | 46 --------- src/base/vnc/vncinput.cc | 130 ++++++++++++++++++++++++ src/base/vnc/vncinput.hh | 250 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/vnc/vncserver.cc | 82 +++------------ src/base/vnc/vncserver.hh | 186 ++-------------------------------- src/dev/arm/RealView.py | 4 +- src/dev/arm/kmi.cc | 2 +- src/dev/arm/kmi.hh | 4 +- src/dev/arm/pl111.cc | 26 ++--- src/dev/arm/pl111.hh | 4 +- 12 files changed, 473 insertions(+), 312 deletions(-) create mode 100644 src/base/vnc/Vnc.py delete mode 100644 src/base/vnc/VncServer.py create mode 100644 src/base/vnc/vncinput.cc create mode 100644 src/base/vnc/vncinput.hh diff --git a/src/base/vnc/SConscript b/src/base/vnc/SConscript index 62448cd70..416743200 100644 --- a/src/base/vnc/SConscript +++ b/src/base/vnc/SConscript @@ -41,6 +41,7 @@ Import('*') Source('convert.cc') -SimObject('VncServer.py') +SimObject('Vnc.py') +Source('vncinput.cc') Source('vncserver.cc') DebugFlag('VNC') diff --git a/src/base/vnc/Vnc.py b/src/base/vnc/Vnc.py new file mode 100644 index 000000000..4e8e18512 --- /dev/null +++ b/src/base/vnc/Vnc.py @@ -0,0 +1,48 @@ +# Copyright (c) 2010 ARM Limited +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: William Wang + +from m5.SimObject import SimObject +from m5.params import * + +class VncInput(SimObject): + type = 'VncInput' + frame_capture = Param.Bool(False, "capture changed frames to files") + +class VncServer(VncInput): + type = 'VncServer' + port = Param.TcpPort(5900, "listen port") + number = Param.Int(0, "vnc client number") diff --git a/src/base/vnc/VncServer.py b/src/base/vnc/VncServer.py deleted file mode 100644 index 6b746f2e2..000000000 --- a/src/base/vnc/VncServer.py +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2010 ARM Limited -# All rights reserved. -# -# The license below extends only to copyright in the software and shall -# not be construed as granting a license to any other intellectual -# property including but not limited to intellectual property relating -# to a hardware implementation of the functionality of the software -# licensed hereunder. You may use the software subject to the license -# terms below provided that you ensure that this notice is replicated -# unmodified and in its entirety in all distributions of the software, -# modified or unmodified, in source code or in binary form. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer; -# redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution; -# neither the name of the copyright holders nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: William Wang - -from m5.SimObject import SimObject -from m5.params import * -from m5.proxy import * - -class VncServer(SimObject): - type = 'VncServer' - port = Param.TcpPort(5900, "listen port") - number = Param.Int(0, "vnc client number") - frame_capture = Param.Bool(False, "capture changed frames to files") diff --git a/src/base/vnc/vncinput.cc b/src/base/vnc/vncinput.cc new file mode 100644 index 000000000..526f61bc1 --- /dev/null +++ b/src/base/vnc/vncinput.cc @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * William Wang + */ + +/** @file + * Implementiation of a VNC input + */ + +#include + +#include "base/vnc/vncinput.hh" +#include "base/output.hh" //simout +#include "debug/VNC.hh" + +using namespace std; + +VncInput::VncInput(const Params *p) + : SimObject(p), keyboard(NULL), mouse(NULL), + vc(NULL), fbPtr(NULL), videoMode(VideoConvert::UnknownMode), + _videoWidth(1), _videoHeight(1), captureEnabled(p->frame_capture), + captureCurrentFrame(0), captureLastHash(0), captureBitmap(0) +{ + if (captureEnabled) { + // remove existing frame output directory if it exists, then create a + // clean empty directory + const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); + simout.remove(FRAME_OUTPUT_SUBDIR, true); + captureOutputDirectory = simout.createSubdirectory( + FRAME_OUTPUT_SUBDIR); + } +} + +void +VncInput::setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, + uint16_t height) +{ + DPRINTF(VNC, "Updating video params: mode: %d width: %d height: %d\n", mode, + width, height); + + if (mode != videoMode || width != videoWidth() || height != videoHeight()) { + videoMode = mode; + _videoWidth = width; + _videoHeight = height; + + if (vc) + delete vc; + + vc = new VideoConvert(mode, VideoConvert::rgb8888, videoWidth(), + videoHeight()); + + if (captureEnabled) { + // create bitmap of the frame with new attributes + if (captureBitmap) + delete captureBitmap; + + assert(fbPtr); + captureBitmap = new Bitmap(videoMode, width, height, fbPtr); + assert(captureBitmap); + } + } +} + +void +VncInput::captureFrameBuffer() +{ + assert(captureBitmap); + + // skip identical frames + uint64_t new_hash = captureBitmap->getHash(); + if (captureLastHash == new_hash) + return; + captureLastHash = new_hash; + + // get the filename for the current frame + char frameFilenameBuffer[64]; + snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz", + captureCurrentFrame, static_cast(curTick())); + const string frameFilename(frameFilenameBuffer); + + // create the compressed framebuffer file + ostream *fb_out = simout.create(captureOutputDirectory + frameFilename, + true); + captureBitmap->write(fb_out); + simout.close(fb_out); + + ++captureCurrentFrame; +} + +// create the VNC Replayer object +VncInput * +VncInputParams::create() +{ + return new VncInput(this); +} diff --git a/src/base/vnc/vncinput.hh b/src/base/vnc/vncinput.hh new file mode 100644 index 000000000..1686e3f25 --- /dev/null +++ b/src/base/vnc/vncinput.hh @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2010 ARM Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * William Wang + */ + +/** @file + * Declaration of a VNC input + */ + +#ifndef __BASE_VNC_VNC_INPUT_HH__ +#define __BASE_VNC_VNC_INPUT_HH__ + +#include + +#include "base/vnc/convert.hh" +#include "base/bitmap.hh" +#include "params/VncInput.hh" +#include "sim/sim_object.hh" + +/** + * A device that expects to receive input from the vnc server should derrive + * (through mulitple inheritence if necessary from VncKeyboard or VncMouse + * and call setKeyboard() or setMouse() respectively on the vnc server. + */ +class VncKeyboard +{ + public: + /** + * Called when the vnc server receives a key press event from the + * client. + * @param key the key passed is an x11 keysym + * @param down is the key now down or up? + */ + virtual void keyPress(uint32_t key, bool down) = 0; +}; + +class VncMouse +{ + public: + /** + * called whenever the mouse moves or it's button state changes + * buttons is a simple mask with each button (0-8) corresponding to + * a bit position in the byte with 1 being down and 0 being up + * @param x the x position of the mouse + * @param y the y position of the mouse + * @param buttos the button state as described above + */ + virtual void mouseAt(uint16_t x, uint16_t y, uint8_t buttons) = 0; +}; + +class VncInput : public SimObject +{ + public: + + /** Client -> Server message IDs */ + enum ClientMessages { + ClientSetPixelFormat = 0, + ClientSetEncodings = 2, + ClientFrameBufferUpdate = 3, + ClientKeyEvent = 4, + ClientPointerEvent = 5, + ClientCutText = 6 + }; + + struct PixelFormat { + uint8_t bpp; + uint8_t depth; + uint8_t bigendian; + uint8_t truecolor; + uint16_t redmax; + uint16_t greenmax; + uint16_t bluemax; + uint8_t redshift; + uint8_t greenshift; + uint8_t blueshift; + uint8_t padding[3]; + } M5_ATTR_PACKED; + + struct PixelFormatMessage { + uint8_t type; + uint8_t padding[3]; + PixelFormat px; + } M5_ATTR_PACKED; + + struct PixelEncodingsMessage { + uint8_t type; + uint8_t padding; + uint16_t num_encodings; + } M5_ATTR_PACKED; + + struct FrameBufferUpdateReq { + uint8_t type; + uint8_t incremental; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + } M5_ATTR_PACKED; + + struct KeyEventMessage { + uint8_t type; + uint8_t down_flag; + uint8_t padding[2]; + uint32_t key; + } M5_ATTR_PACKED; + + struct PointerEventMessage { + uint8_t type; + uint8_t button_mask; + uint16_t x; + uint16_t y; + } M5_ATTR_PACKED; + + struct ClientCutTextMessage { + uint8_t type; + uint8_t padding[3]; + uint32_t length; + } M5_ATTR_PACKED; + + typedef VncInputParams Params; + VncInput(const Params *p); + + /** Set the address of the frame buffer we are going to show. + * To avoid copying, just have the display controller + * tell us where the data is instead of constanly copying it around + * @param rfb frame buffer that we're going to use + */ + void + setFramebufferAddr(uint8_t* rfb) + { + fbPtr = rfb; + } + + /** Set up the device that would like to receive notifications when keys are + * pressed in the vnc client keyboard + * @param _keyboard an object that derrives from VncKeyboard + */ + void setKeyboard(VncKeyboard *_keyboard) { keyboard = _keyboard; } + + /** Setup the device that would like to receive notifications when mouse + * movements or button presses are received from the vnc client. + * @param _mouse an object that derrives from VncMouse + */ + void setMouse(VncMouse *_mouse) { mouse = _mouse; } + + /** What is the width of the screen we're displaying. + * This is used for pointer/tablet devices that need to know to calculate + * the correct value to send to the device driver. + * @return the width of the simulated screen + */ + uint16_t videoWidth() const { return _videoWidth; } + + /** What is the height of the screen we're displaying. + * This is used for pointer/tablet devices that need to know to calculate + * the correct value to send to the device driver. + * @return the height of the simulated screen + */ + uint16_t videoHeight() const { return _videoHeight; } + + /** The frame buffer uses this call to notify the vnc server that + * the frame buffer has been updated and a new image needs to be sent to the + * client + */ + virtual void setDirty() + { + if (captureEnabled) + captureFrameBuffer(); + } + + /** Set the mode of the data the frame buffer will be sending us + * @param mode the mode + */ + virtual void setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, uint16_t height); + + protected: + /** The device to notify when we get key events */ + VncKeyboard *keyboard; + + /** The device to notify when we get mouse events */ + VncMouse *mouse; + + /** The video converter that transforms data for us */ + VideoConvert *vc; + + /** pointer to the actual data that is stored in the frame buffer device */ + uint8_t* fbPtr; + + /** The mode of data we're getting frame buffer in */ + VideoConvert::Mode videoMode; + + /** the width of the frame buffer we are sending to the client */ + uint16_t _videoWidth; + + /** the height of the frame buffer we are sending to the client */ + uint16_t _videoHeight; + + /** Flag indicating whether to capture snapshots of frame buffer or not */ + bool captureEnabled; + + /** Current frame number being captured to a file */ + int captureCurrentFrame; + + /** Directory to store captured frames to */ + std::string captureOutputDirectory; + + /** Computed hash of the last captured frame */ + uint64_t captureLastHash; + + /** Cached bitmap object for writing out frame buffers to file */ + Bitmap *captureBitmap; + + /** Captures the current frame buffer to a file */ + void captureFrameBuffer(); +}; +#endif diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 3f0393104..debf82014 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -66,6 +66,10 @@ using namespace std; +/** @file + * Implementiation of a VNC server + */ + /** * Poll event for the listen socket */ @@ -101,11 +105,8 @@ VncServer::DataEvent::process(int revent) * VncServer */ VncServer::VncServer(const Params *p) - : SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number), - dataFd(-1), _videoWidth(1), _videoHeight(1), clientRfb(0), keyboard(NULL), - mouse(NULL), sendUpdate(false), videoMode(VideoConvert::UnknownMode), - vc(NULL), captureEnabled(p->frame_capture), captureCurrentFrame(0), - captureLastHash(0), captureBitmap(0) + : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p->number), + dataFd(-1), sendUpdate(false) { if (p->port) listen(p->port); @@ -127,15 +128,6 @@ VncServer::VncServer(const Params *p) pixelFormat.greenshift = 8; pixelFormat.blueshift = 0; - if (captureEnabled) { - // remove existing frame output directory if it exists, then create a - // clean empty directory - const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); - simout.remove(FRAME_OUTPUT_SUBDIR, true); - captureOutputDirectory = simout.createSubdirectory( - FRAME_OUTPUT_SUBDIR); - } - DPRINTF(VNC, "Vnc server created at port %d\n", p->port); } @@ -465,7 +457,6 @@ VncServer::sendServerInit() curState = NormalPhase; } - void VncServer::setPixelFormat() { @@ -608,7 +599,7 @@ void VncServer::sendFrameBufferUpdate() { - if (!clientRfb || dataFd <= 0 || curState != NormalPhase || !sendUpdate) { + if (!fbPtr || dataFd <= 0 || curState != NormalPhase || !sendUpdate) { DPRINTF(VNC, "NOT sending framebuffer update\n"); return; } @@ -643,9 +634,9 @@ VncServer::sendFrameBufferUpdate() write(&fbu); write(&fbr); - assert(clientRfb); + assert(fbPtr); - uint8_t *tmp = vc->convert(clientRfb); + uint8_t *tmp = vc->convert(fbPtr); write(tmp, videoWidth() * videoHeight() * sizeof(uint32_t)); delete [] tmp; @@ -654,7 +645,7 @@ VncServer::sendFrameBufferUpdate() void VncServer::sendFrameBufferResized() { - assert(clientRfb && dataFd > 0 && curState == NormalPhase); + assert(fbPtr && dataFd > 0 && curState == NormalPhase); DPRINTF(VNC, "Sending framebuffer resize\n"); FrameBufferUpdate fbu; @@ -684,33 +675,13 @@ VncServer::sendFrameBufferResized() } void -VncServer::setFrameBufferParams(VideoConvert::Mode mode, int width, int height) +VncServer::setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, + uint16_t height) { - DPRINTF(VNC, "Updating video params: mode: %d width: %d height: %d\n", mode, - width, height); + VncInput::setFrameBufferParams(mode, width, height); if (mode != videoMode || width != videoWidth() || height != videoHeight()) { - videoMode = mode; - _videoWidth = width; - _videoHeight = height; - - if (vc) - delete vc; - - vc = new VideoConvert(mode, VideoConvert::rgb8888, videoWidth(), - videoHeight()); - - if (captureEnabled) { - // create bitmap of the frame with new attributes - if (captureBitmap) - delete captureBitmap; - - assert(clientRfb); - captureBitmap = new Bitmap(videoMode, width, height, clientRfb); - assert(captureBitmap); - } - - if (dataFd > 0 && clientRfb && curState == NormalPhase) { + if (dataFd > 0 && fbPtr && curState == NormalPhase) { if (supportsResizeEnc) sendFrameBufferResized(); else @@ -727,28 +698,3 @@ VncServerParams::create() return new VncServer(this); } -void -VncServer::captureFrameBuffer() -{ - assert(captureBitmap); - - // skip identical frames - uint64_t new_hash = captureBitmap->getHash(); - if (captureLastHash == new_hash) - return; - captureLastHash = new_hash; - - // get the filename for the current frame - char frameFilenameBuffer[64]; - snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz", - captureCurrentFrame, static_cast(curTick())); - const string frameFilename(frameFilenameBuffer); - - // create the compressed framebuffer file - ostream *fb_out = simout.create(captureOutputDirectory + frameFilename, - true); - captureBitmap->write(fb_out); - simout.close(fb_out); - - ++captureCurrentFrame; -} diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh index 33d833f26..17c097536 100644 --- a/src/base/vnc/vncserver.hh +++ b/src/base/vnc/vncserver.hh @@ -42,12 +42,13 @@ * Declaration of a VNC server */ -#ifndef __DEV_VNC_SERVER_HH__ -#define __DEV_VNC_SERVER_HH__ +#ifndef __BASE_VNC_VNC_SERVER_HH__ +#define __BASE_VNC_VNC_SERVER_HH__ #include #include "base/vnc/convert.hh" +#include "base/vnc/vncinput.hh" #include "base/bitmap.hh" #include "base/circlebuf.hh" #include "base/pollevent.hh" @@ -56,39 +57,11 @@ #include "params/VncServer.hh" #include "sim/sim_object.hh" - -/** - * A device that expects to receive input from the vnc server should derrive - * (through mulitple inheritence if necessary from VncKeyboard or VncMouse - * and call setKeyboard() or setMouse() respectively on the vnc server. +/** @file + * Declaration of a VNC server */ -class VncKeyboard -{ - public: - /** - * Called when the vnc server receives a key press event from the - * client. - * @param key the key passed is an x11 keysym - * @param down is the key now down or up? - */ - virtual void keyPress(uint32_t key, bool down) = 0; -}; -class VncMouse -{ - public: - /** - * called whenever the mouse moves or it's button state changes - * buttons is a simple mask with each button (0-8) corresponding to - * a bit position in the byte with 1 being down and 0 being up - * @param x the x position of the mouse - * @param y the y position of the mouse - * @param buttos the button state as described above - */ - virtual void mouseAt(uint16_t x, uint16_t y, uint8_t buttons) = 0; -}; - -class VncServer : public SimObject +class VncServer : public VncInput { public: @@ -103,16 +76,6 @@ class VncServer : public SimObject /** Error conditions */ const static uint32_t VncOK = 0; - /** Client -> Server message IDs */ - enum ClientMessages { - ClientSetPixelFormat = 0, - ClientSetEncodings = 2, - ClientFrameBufferUpdate = 3, - ClientKeyEvent = 4, - ClientPointerEvent = 5, - ClientCutText = 6 - }; - /** Server -> Client message IDs */ enum ServerMessages { ServerFrameBufferUpdate = 0, @@ -149,20 +112,6 @@ class VncServer : public SimObject NormalPhase }; - struct PixelFormat { - uint8_t bpp; - uint8_t depth; - uint8_t bigendian; - uint8_t truecolor; - uint16_t redmax; - uint16_t greenmax; - uint16_t bluemax; - uint8_t redshift; - uint8_t greenshift; - uint8_t blueshift; - uint8_t padding[3]; - } M5_ATTR_PACKED; - struct ServerInitMsg { uint16_t fbWidth; uint16_t fbHeight; @@ -171,47 +120,6 @@ class VncServer : public SimObject char name[2]; // just to put M5 in here } M5_ATTR_PACKED; - struct PixelFormatMessage { - uint8_t type; - uint8_t padding[3]; - PixelFormat px; - } M5_ATTR_PACKED; - - struct PixelEncodingsMessage { - uint8_t type; - uint8_t padding; - uint16_t num_encodings; - } M5_ATTR_PACKED; - - struct FrameBufferUpdateReq { - uint8_t type; - uint8_t incremental; - uint16_t x; - uint16_t y; - uint16_t width; - uint16_t height; - } M5_ATTR_PACKED; - - struct KeyEventMessage { - uint8_t type; - uint8_t down_flag; - uint8_t padding[2]; - uint32_t key; - } M5_ATTR_PACKED; - - struct PointerEventMessage { - uint8_t type; - uint8_t button_mask; - uint16_t x; - uint16_t y; - } M5_ATTR_PACKED; - - struct ClientCutTextMessage { - uint8_t type; - uint8_t padding[3]; - uint32_t length; - } M5_ATTR_PACKED; - struct FrameBufferUpdate { uint8_t type; uint8_t padding; @@ -284,21 +192,6 @@ class VncServer : public SimObject /** The rfb prototol state the connection is in */ ConnectionState curState; - /** the width of the frame buffer we are sending to the client */ - uint16_t _videoWidth; - - /** the height of the frame buffer we are sending to the client */ - uint16_t _videoHeight; - - /** pointer to the actual data that is stored in the frame buffer device */ - uint8_t* clientRfb; - - /** The device to notify when we get key events */ - VncKeyboard *keyboard; - - /** The device to notify when we get mouse events */ - VncMouse *mouse; - /** An update needs to be sent to the client. Without doing this the * client will constantly request data that is pointless */ bool sendUpdate; @@ -312,31 +205,7 @@ class VncServer : public SimObject /** If the vnc client supports the desktop resize command */ bool supportsResizeEnc; - /** The mode of data we're getting frame buffer in */ - VideoConvert::Mode videoMode; - - /** The video converter that transforms data for us */ - VideoConvert *vc; - - /** Flag indicating whether to capture snapshots of frame buffer or not */ - bool captureEnabled; - - /** Current frame number being captured to a file */ - int captureCurrentFrame; - - /** Directory to store captured frames to */ - std::string captureOutputDirectory; - - /** Computed hash of the last captured frame */ - uint64_t captureLastHash; - - /** Cached bitmap object for writing out frame buffers to file */ - Bitmap *captureBitmap; - protected: - /** Captures the current frame buffer to a file */ - void captureFrameBuffer(); - /** * vnc client Interface */ @@ -438,29 +307,6 @@ class VncServer : public SimObject void sendFrameBufferResized(); public: - /** Set the address of the frame buffer we are going to show. - * To avoid copying, just have the display controller - * tell us where the data is instead of constanly copying it around - * @param rfb frame buffer that we're going to use - */ - void - setFramebufferAddr(uint8_t* rfb) - { - clientRfb = rfb; - } - - /** Set up the device that would like to receive notifications when keys are - * pressed in the vnc client keyboard - * @param _keyboard an object that derrives from VncKeyboard - */ - void setKeyboard(VncKeyboard *_keyboard) { keyboard = _keyboard; } - - /** Setup the device that would like to receive notifications when mouse - * movements or button presses are received from the vnc client. - * @param _mouse an object that derrives from VncMouse - */ - void setMouse(VncMouse *_mouse) { mouse = _mouse; } - /** The frame buffer uses this call to notify the vnc server that * the frame buffer has been updated and a new image needs to be sent to the * client @@ -468,30 +314,16 @@ class VncServer : public SimObject void setDirty() { + VncInput::setDirty(); sendUpdate = true; - if (captureEnabled) - captureFrameBuffer(); sendFrameBufferUpdate(); } - /** What is the width of the screen we're displaying. - * This is used for pointer/tablet devices that need to know to calculate - * the correct value to send to the device driver. - * @return the width of the simulated screen - */ - uint16_t videoWidth() { return _videoWidth; } - - /** What is the height of the screen we're displaying. - * This is used for pointer/tablet devices that need to know to calculate - * the correct value to send to the device driver. - * @return the height of the simulated screen - */ - uint16_t videoHeight() { return _videoHeight; } - /** Set the mode of the data the frame buffer will be sending us * @param mode the mode */ - void setFrameBufferParams(VideoConvert::Mode mode, int width, int height); + void setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, + uint16_t height); }; #endif diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 93f534eb3..f0b629b38 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -128,7 +128,7 @@ class PL031(AmbaIntDevice): class Pl050(AmbaIntDevice): type = 'Pl050' - vnc = Param.VncServer(Parent.any, "Vnc server for remote frame buffer display") + vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") is_mouse = Param.Bool(False, "Is this interface a mouse, if not a keyboard") int_delay = '1us' amba_id = 0x00141050 @@ -137,7 +137,7 @@ class Pl111(AmbaDmaDevice): type = 'Pl111' # Override the default clock clock = '24MHz' - vnc = Param.VncServer(Parent.any, "Vnc server for remote frame buffer display") + vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") amba_id = 0x00141111 class RealView(Platform): diff --git a/src/dev/arm/kmi.cc b/src/dev/arm/kmi.cc index c90e00125..b5819c9d8 100644 --- a/src/dev/arm/kmi.cc +++ b/src/dev/arm/kmi.cc @@ -41,7 +41,7 @@ * William Wang */ -#include "base/vnc/vncserver.hh" +#include "base/vnc/vncinput.hh" #include "base/trace.hh" #include "debug/Pl050.hh" #include "dev/arm/amba_device.hh" diff --git a/src/dev/arm/kmi.hh b/src/dev/arm/kmi.hh index e769a8a46..e2e75cfef 100644 --- a/src/dev/arm/kmi.hh +++ b/src/dev/arm/kmi.hh @@ -50,7 +50,7 @@ #include -#include "base/vnc/vncserver.hh" +#include "base/vnc/vncinput.hh" #include "dev/arm/amba_device.hh" #include "params/Pl050.hh" @@ -118,7 +118,7 @@ class Pl050 : public AmbaIntDevice, public VncKeyboard, public VncMouse bool shiftDown; /** The vnc server we're connected to (if any) */ - VncServer *vnc; + VncInput *vnc; /** If the linux driver has initialized the device yet and thus can we send * mouse data */ diff --git a/src/dev/arm/pl111.cc b/src/dev/arm/pl111.cc index 22eba1458..c68f606cd 100644 --- a/src/dev/arm/pl111.cc +++ b/src/dev/arm/pl111.cc @@ -38,7 +38,7 @@ * Ali Saidi */ -#include "base/vnc/vncserver.hh" +#include "base/vnc/vncinput.hh" #include "base/bitmap.hh" #include "base/output.hh" #include "base/trace.hh" @@ -64,7 +64,7 @@ Pl111::Pl111(const Params *p) clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0), clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0), clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0), - vncserver(p->vnc), bmp(NULL), width(LcdMaxWidth), height(LcdMaxHeight), + vnc(p->vnc), bmp(NULL), width(LcdMaxWidth), height(LcdMaxHeight), bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0), waterMark(0), dmaPendingNum(0), readEvent(this), fillFifoEvent(this), dmaDoneEvent(maxOutstandingDma, this), intEvent(this) @@ -80,8 +80,8 @@ Pl111::Pl111(const Params *p) memset(cursorImage, 0, sizeof(cursorImage)); memset(dmaBuffer, 0, buffer_size); - if (vncserver) - vncserver->setFramebufferAddr(dmaBuffer); + if (vnc) + vnc->setFramebufferAddr(dmaBuffer); } Pl111::~Pl111() @@ -386,18 +386,18 @@ Pl111::updateVideoParams() bytesPerPixel = 2; } - if (vncserver) { + if (vnc) { if (lcdControl.lcdbpp == bpp24 && lcdControl.bgr) - vncserver->setFrameBufferParams(VideoConvert::bgr8888, width, + vnc->setFrameBufferParams(VideoConvert::bgr8888, width, height); else if (lcdControl.lcdbpp == bpp24 && !lcdControl.bgr) - vncserver->setFrameBufferParams(VideoConvert::rgb8888, width, + vnc->setFrameBufferParams(VideoConvert::rgb8888, width, height); else if (lcdControl.lcdbpp == bpp16m565 && lcdControl.bgr) - vncserver->setFrameBufferParams(VideoConvert::bgr565, width, + vnc->setFrameBufferParams(VideoConvert::bgr565, width, height); else if (lcdControl.lcdbpp == bpp16m565 && !lcdControl.bgr) - vncserver->setFrameBufferParams(VideoConvert::rgb565, width, + vnc->setFrameBufferParams(VideoConvert::rgb565, width, height); else panic("Unimplemented video mode\n"); @@ -489,8 +489,8 @@ Pl111::dmaDone() } assert(!readEvent.scheduled()); - if (vncserver) - vncserver->setDirty(); + if (vnc) + vnc->setDirty(); DPRINTF(PL111, "-- write out frame buffer into bmp\n"); @@ -710,8 +710,8 @@ Pl111::unserialize(Checkpoint *cp, const std::string §ion) if (lcdControl.lcdpwr) { updateVideoParams(); - if (vncserver) - vncserver->setDirty(); + if (vnc) + vnc->setDirty(); } } diff --git a/src/dev/arm/pl111.hh b/src/dev/arm/pl111.hh index 5776f199c..49512fcc0 100644 --- a/src/dev/arm/pl111.hh +++ b/src/dev/arm/pl111.hh @@ -53,7 +53,7 @@ #include "sim/serialize.hh" class Gic; -class VncServer; +class VncInput; class Bitmap; class Pl111: public AmbaDmaDevice @@ -228,7 +228,7 @@ class Pl111: public AmbaDmaDevice InterruptReg clcdCrsrMis; /** VNC server */ - VncServer *vncserver; + VncInput *vnc; /** Helper to write out bitmaps */ Bitmap *bmp; -- cgit v1.2.3