vncinput.cc revision 11359
17949SN/A/* 210839Sandreas.sandberg@arm.com * Copyright (c) 2010, 2015 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 458635SN/A#include <sys/types.h> 467949SN/A 479330Schander.sudanthi@arm.com#include "base/vnc/vncinput.hh" 489330Schander.sudanthi@arm.com#include "base/output.hh" //simout 499356Snilay@cs.wisc.edu#include "base/trace.hh" 508232SN/A#include "debug/VNC.hh" 517949SN/A 527949SN/Ausing namespace std; 537949SN/A 549330Schander.sudanthi@arm.comVncInput::VncInput(const Params *p) 559330Schander.sudanthi@arm.com : SimObject(p), keyboard(NULL), mouse(NULL), 5610839Sandreas.sandberg@arm.com fb(&FrameBuffer::dummy), 5710839Sandreas.sandberg@arm.com _videoWidth(fb->width()), _videoHeight(fb->height()), 5810839Sandreas.sandberg@arm.com captureEnabled(p->frame_capture), 5910839Sandreas.sandberg@arm.com captureCurrentFrame(0), captureLastHash(0) 607949SN/A{ 618635SN/A if (captureEnabled) { 628635SN/A // remove existing frame output directory if it exists, then create a 638635SN/A // clean empty directory 648635SN/A const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); 658635SN/A simout.remove(FRAME_OUTPUT_SUBDIR, true); 668635SN/A captureOutputDirectory = simout.createSubdirectory( 678635SN/A FRAME_OUTPUT_SUBDIR); 688635SN/A } 697949SN/A} 707949SN/A 717949SN/Avoid 7210839Sandreas.sandberg@arm.comVncInput::setFrameBuffer(const FrameBuffer *rfb) 737949SN/A{ 7410839Sandreas.sandberg@arm.com if (!rfb) 7510839Sandreas.sandberg@arm.com panic("Trying to VNC frame buffer to NULL!"); 767949SN/A 7710839Sandreas.sandberg@arm.com fb = rfb; 7810839Sandreas.sandberg@arm.com 7910839Sandreas.sandberg@arm.com // create bitmap of the frame with new attributes 8010839Sandreas.sandberg@arm.com if (captureEnabled) 8110839Sandreas.sandberg@arm.com captureBitmap.reset(new Bitmap(rfb)); 8210839Sandreas.sandberg@arm.com 8310839Sandreas.sandberg@arm.com // Setting a new frame buffer means that we need to send an update 8410839Sandreas.sandberg@arm.com // to the client. Mark the internal buffers as dirty to do so. 8510839Sandreas.sandberg@arm.com setDirty(); 8610839Sandreas.sandberg@arm.com} 8710839Sandreas.sandberg@arm.com 8810839Sandreas.sandberg@arm.comvoid 8910839Sandreas.sandberg@arm.comVncInput::setDirty() 9010839Sandreas.sandberg@arm.com{ 9110839Sandreas.sandberg@arm.com const unsigned width(fb->width()); 9210839Sandreas.sandberg@arm.com const unsigned height(fb->height()); 9310839Sandreas.sandberg@arm.com 9410839Sandreas.sandberg@arm.com if (_videoWidth != width || _videoHeight != height) { 9510839Sandreas.sandberg@arm.com DPRINTF(VNC, "Updating video params: width: %d height: %d\n", 9610839Sandreas.sandberg@arm.com width, height); 9710839Sandreas.sandberg@arm.com 987949SN/A _videoWidth = width; 997949SN/A _videoHeight = height; 1007949SN/A 10110839Sandreas.sandberg@arm.com frameBufferResized(); 10210839Sandreas.sandberg@arm.com } 1037949SN/A 10410839Sandreas.sandberg@arm.com if (captureEnabled) 10510839Sandreas.sandberg@arm.com captureFrameBuffer(); 1067949SN/A} 1077949SN/A 1088635SN/Avoid 1099330Schander.sudanthi@arm.comVncInput::captureFrameBuffer() 1108635SN/A{ 1118635SN/A assert(captureBitmap); 1128635SN/A 1138635SN/A // skip identical frames 11410839Sandreas.sandberg@arm.com uint64_t new_hash = fb->getHash(); 1158635SN/A if (captureLastHash == new_hash) 1168635SN/A return; 1178635SN/A captureLastHash = new_hash; 1188635SN/A 1198635SN/A // get the filename for the current frame 1208635SN/A char frameFilenameBuffer[64]; 1218635SN/A snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz", 1228635SN/A captureCurrentFrame, static_cast<long long int>(curTick())); 1238635SN/A const string frameFilename(frameFilenameBuffer); 1248635SN/A 1258635SN/A // create the compressed framebuffer file 12611359Sandreas@sandberg.pp.se OutputStream *fb_out(captureOutputDirectory->create(frameFilename, true)); 12711359Sandreas@sandberg.pp.se captureBitmap->write(*fb_out->stream()); 12811359Sandreas@sandberg.pp.se captureOutputDirectory->close(fb_out); 1298635SN/A 1308635SN/A ++captureCurrentFrame; 1318635SN/A} 1329330Schander.sudanthi@arm.com 1339330Schander.sudanthi@arm.com// create the VNC Replayer object 1349330Schander.sudanthi@arm.comVncInput * 1359330Schander.sudanthi@arm.comVncInputParams::create() 1369330Schander.sudanthi@arm.com{ 1379330Schander.sudanthi@arm.com return new VncInput(this); 1389330Schander.sudanthi@arm.com} 139