vncinput.cc revision 12230
17949SN/A/* 212230Sgiacomo.travaglini@arm.com * Copyright (c) 2010, 2015, 2017 ARM Limited 37949SN/A * All rights reserved 47949SN/A * 57949SN/A * The license below extends only to copyright in the software and shall 67949SN/A * not be construed as granting a license to any other intellectual 77949SN/A * property including but not limited to intellectual property relating 87949SN/A * to a hardware implementation of the functionality of the software 97949SN/A * licensed hereunder. You may use the software subject to the license 107949SN/A * terms below provided that you ensure that this notice is replicated 117949SN/A * unmodified and in its entirety in all distributions of the software, 127949SN/A * modified or unmodified, in source code or in binary form. 137949SN/A * 147949SN/A * Redistribution and use in source and binary forms, with or without 157949SN/A * modification, are permitted provided that the following conditions are 167949SN/A * met: redistributions of source code must retain the above copyright 177949SN/A * notice, this list of conditions and the following disclaimer; 187949SN/A * redistributions in binary form must reproduce the above copyright 197949SN/A * notice, this list of conditions and the following disclaimer in the 207949SN/A * documentation and/or other materials provided with the distribution; 217949SN/A * neither the name of the copyright holders nor the names of its 227949SN/A * contributors may be used to endorse or promote products derived from 237949SN/A * this software without specific prior written permission. 247949SN/A * 257949SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 267949SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277949SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 287949SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 297949SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 307949SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 317949SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 327949SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337949SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 347949SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 357949SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 367949SN/A * 377949SN/A * Authors: Ali Saidi 387949SN/A * William Wang 397949SN/A */ 407949SN/A 417949SN/A/** @file 429330Schander.sudanthi@arm.com * Implementiation of a VNC input 437949SN/A */ 447949SN/A 4511793Sbrandon.potter@amd.com#include "base/vnc/vncinput.hh" 4611793Sbrandon.potter@amd.com 478635SN/A#include <sys/types.h> 487949SN/A 4911800Sbrandon.potter@amd.com#include "base/misc.hh" 5011800Sbrandon.potter@amd.com#include "base/output.hh" 5112230Sgiacomo.travaglini@arm.com 529356Snilay@cs.wisc.edu#include "base/trace.hh" 538232SN/A#include "debug/VNC.hh" 547949SN/A 557949SN/Ausing namespace std; 567949SN/A 579330Schander.sudanthi@arm.comVncInput::VncInput(const Params *p) 589330Schander.sudanthi@arm.com : SimObject(p), keyboard(NULL), mouse(NULL), 5910839Sandreas.sandberg@arm.com fb(&FrameBuffer::dummy), 6010839Sandreas.sandberg@arm.com _videoWidth(fb->width()), _videoHeight(fb->height()), 6110839Sandreas.sandberg@arm.com captureEnabled(p->frame_capture), 6212230Sgiacomo.travaglini@arm.com captureCurrentFrame(0), captureLastHash(0), 6312230Sgiacomo.travaglini@arm.com imgFormat(p->img_format) 647949SN/A{ 658635SN/A if (captureEnabled) { 668635SN/A // remove existing frame output directory if it exists, then create a 678635SN/A // clean empty directory 688635SN/A const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); 698635SN/A simout.remove(FRAME_OUTPUT_SUBDIR, true); 708635SN/A captureOutputDirectory = simout.createSubdirectory( 718635SN/A FRAME_OUTPUT_SUBDIR); 728635SN/A } 737949SN/A} 747949SN/A 757949SN/Avoid 7610839Sandreas.sandberg@arm.comVncInput::setFrameBuffer(const FrameBuffer *rfb) 777949SN/A{ 7810839Sandreas.sandberg@arm.com if (!rfb) 7910839Sandreas.sandberg@arm.com panic("Trying to VNC frame buffer to NULL!"); 807949SN/A 8110839Sandreas.sandberg@arm.com fb = rfb; 8210839Sandreas.sandberg@arm.com 8312230Sgiacomo.travaglini@arm.com // Create the Image Writer object in charge of dumping 8412230Sgiacomo.travaglini@arm.com // the frame buffer raw data into a file in a specific format. 8512230Sgiacomo.travaglini@arm.com if (captureEnabled) { 8612230Sgiacomo.travaglini@arm.com captureImage = createImgWriter(imgFormat, rfb); 8712230Sgiacomo.travaglini@arm.com } 8810839Sandreas.sandberg@arm.com 8910839Sandreas.sandberg@arm.com // Setting a new frame buffer means that we need to send an update 9010839Sandreas.sandberg@arm.com // to the client. Mark the internal buffers as dirty to do so. 9110839Sandreas.sandberg@arm.com setDirty(); 9210839Sandreas.sandberg@arm.com} 9310839Sandreas.sandberg@arm.com 9410839Sandreas.sandberg@arm.comvoid 9510839Sandreas.sandberg@arm.comVncInput::setDirty() 9610839Sandreas.sandberg@arm.com{ 9710839Sandreas.sandberg@arm.com const unsigned width(fb->width()); 9810839Sandreas.sandberg@arm.com const unsigned height(fb->height()); 9910839Sandreas.sandberg@arm.com 10010839Sandreas.sandberg@arm.com if (_videoWidth != width || _videoHeight != height) { 10110839Sandreas.sandberg@arm.com DPRINTF(VNC, "Updating video params: width: %d height: %d\n", 10210839Sandreas.sandberg@arm.com width, height); 10310839Sandreas.sandberg@arm.com 1047949SN/A _videoWidth = width; 1057949SN/A _videoHeight = height; 1067949SN/A 10710839Sandreas.sandberg@arm.com frameBufferResized(); 10810839Sandreas.sandberg@arm.com } 1097949SN/A 11010839Sandreas.sandberg@arm.com if (captureEnabled) 11110839Sandreas.sandberg@arm.com captureFrameBuffer(); 1127949SN/A} 1137949SN/A 1148635SN/Avoid 1159330Schander.sudanthi@arm.comVncInput::captureFrameBuffer() 1168635SN/A{ 11712230Sgiacomo.travaglini@arm.com assert(captureImage); 1188635SN/A 1198635SN/A // skip identical frames 12010839Sandreas.sandberg@arm.com uint64_t new_hash = fb->getHash(); 1218635SN/A if (captureLastHash == new_hash) 1228635SN/A return; 1238635SN/A captureLastHash = new_hash; 1248635SN/A 1258635SN/A // get the filename for the current frame 1268635SN/A char frameFilenameBuffer[64]; 12712230Sgiacomo.travaglini@arm.com snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.%s.gz", 12812230Sgiacomo.travaglini@arm.com captureCurrentFrame, static_cast<long long int>(curTick()), 12912230Sgiacomo.travaglini@arm.com captureImage->getImgExtension()); 1308635SN/A const string frameFilename(frameFilenameBuffer); 1318635SN/A 1328635SN/A // create the compressed framebuffer file 13311359Sandreas@sandberg.pp.se OutputStream *fb_out(captureOutputDirectory->create(frameFilename, true)); 13412230Sgiacomo.travaglini@arm.com captureImage->write(*fb_out->stream()); 13511359Sandreas@sandberg.pp.se captureOutputDirectory->close(fb_out); 1368635SN/A 1378635SN/A ++captureCurrentFrame; 1388635SN/A} 1399330Schander.sudanthi@arm.com 1409330Schander.sudanthi@arm.com// create the VNC Replayer object 1419330Schander.sudanthi@arm.comVncInput * 1429330Schander.sudanthi@arm.comVncInputParams::create() 1439330Schander.sudanthi@arm.com{ 1449330Schander.sudanthi@arm.com return new VncInput(this); 1459330Schander.sudanthi@arm.com} 146