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
This commit is contained in:
parent
ac161c1d72
commit
55787cc0d0
|
@ -41,6 +41,7 @@ Import('*')
|
|||
|
||||
Source('convert.cc')
|
||||
|
||||
SimObject('VncServer.py')
|
||||
SimObject('Vnc.py')
|
||||
Source('vncinput.cc')
|
||||
Source('vncserver.cc')
|
||||
DebugFlag('VNC')
|
||||
|
|
|
@ -37,10 +37,12 @@
|
|||
|
||||
from m5.SimObject import SimObject
|
||||
from m5.params import *
|
||||
from m5.proxy import *
|
||||
|
||||
class VncServer(SimObject):
|
||||
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")
|
||||
frame_capture = Param.Bool(False, "capture changed frames to files")
|
130
src/base/vnc/vncinput.cc
Normal file
130
src/base/vnc/vncinput.cc
Normal file
|
@ -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 <sys/types.h>
|
||||
|
||||
#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<long long int>(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);
|
||||
}
|
250
src/base/vnc/vncinput.hh
Normal file
250
src/base/vnc/vncinput.hh
Normal file
|
@ -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 <iostream>
|
||||
|
||||
#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
|
|
@ -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<long long int>(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;
|
||||
}
|
||||
|
|
|
@ -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 <iostream>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
#include <list>
|
||||
|
||||
#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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue