vncserver.cc (8871:136328e218f2) | vncserver.cc (9330:4a3269a11230) |
---|---|
1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 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 --- 52 unchanged lines hidden (view full) --- 61#include "base/socket.hh" 62#include "base/trace.hh" 63#include "debug/VNC.hh" 64#include "sim/byteswap.hh" 65#include "sim/core.hh" 66 67using namespace std; 68 | 1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 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 --- 52 unchanged lines hidden (view full) --- 61#include "base/socket.hh" 62#include "base/trace.hh" 63#include "debug/VNC.hh" 64#include "sim/byteswap.hh" 65#include "sim/core.hh" 66 67using namespace std; 68 |
69/** @file 70 * Implementiation of a VNC server 71 */ 72 |
|
69/** 70 * Poll event for the listen socket 71 */ 72VncServer::ListenEvent::ListenEvent(VncServer *vs, int fd, int e) 73 : PollEvent(fd, e), vncserver(vs) 74{ 75} 76 --- 19 unchanged lines hidden (view full) --- 96 else if (revent & POLLNVAL) 97 vncserver->detach(); 98} 99 100/** 101 * VncServer 102 */ 103VncServer::VncServer(const Params *p) | 73/** 74 * Poll event for the listen socket 75 */ 76VncServer::ListenEvent::ListenEvent(VncServer *vs, int fd, int e) 77 : PollEvent(fd, e), vncserver(vs) 78{ 79} 80 --- 19 unchanged lines hidden (view full) --- 100 else if (revent & POLLNVAL) 101 vncserver->detach(); 102} 103 104/** 105 * VncServer 106 */ 107VncServer::VncServer(const Params *p) |
104 : SimObject(p), listenEvent(NULL), dataEvent(NULL), number(p->number), 105 dataFd(-1), _videoWidth(1), _videoHeight(1), clientRfb(0), keyboard(NULL), 106 mouse(NULL), sendUpdate(false), videoMode(VideoConvert::UnknownMode), 107 vc(NULL), captureEnabled(p->frame_capture), captureCurrentFrame(0), 108 captureLastHash(0), captureBitmap(0) | 108 : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p->number), 109 dataFd(-1), sendUpdate(false) |
109{ 110 if (p->port) 111 listen(p->port); 112 113 curState = WaitForProtocolVersion; 114 115 // currently we only support this one pixel format 116 // unpacked 32bit rgb (rgb888 + 8 bits of nothing/alpha) --- 5 unchanged lines hidden (view full) --- 122 pixelFormat.truecolor = 1; 123 pixelFormat.redmax = 0xff; 124 pixelFormat.greenmax = 0xff; 125 pixelFormat.bluemax = 0xff; 126 pixelFormat.redshift = 16; 127 pixelFormat.greenshift = 8; 128 pixelFormat.blueshift = 0; 129 | 110{ 111 if (p->port) 112 listen(p->port); 113 114 curState = WaitForProtocolVersion; 115 116 // currently we only support this one pixel format 117 // unpacked 32bit rgb (rgb888 + 8 bits of nothing/alpha) --- 5 unchanged lines hidden (view full) --- 123 pixelFormat.truecolor = 1; 124 pixelFormat.redmax = 0xff; 125 pixelFormat.greenmax = 0xff; 126 pixelFormat.bluemax = 0xff; 127 pixelFormat.redshift = 16; 128 pixelFormat.greenshift = 8; 129 pixelFormat.blueshift = 0; 130 |
130 if (captureEnabled) { 131 // remove existing frame output directory if it exists, then create a 132 // clean empty directory 133 const string FRAME_OUTPUT_SUBDIR = "frames_" + name(); 134 simout.remove(FRAME_OUTPUT_SUBDIR, true); 135 captureOutputDirectory = simout.createSubdirectory( 136 FRAME_OUTPUT_SUBDIR); 137 } 138 | |
139 DPRINTF(VNC, "Vnc server created at port %d\n", p->port); 140} 141 142VncServer::~VncServer() 143{ 144 if (dataFd != -1) 145 ::close(dataFd); 146 --- 313 unchanged lines hidden (view full) --- 460 msg.namelen = 2; 461 msg.namelen = htobe(msg.namelen); 462 memcpy(msg.name, "M5", 2); 463 464 write(&msg); 465 curState = NormalPhase; 466} 467 | 131 DPRINTF(VNC, "Vnc server created at port %d\n", p->port); 132} 133 134VncServer::~VncServer() 135{ 136 if (dataFd != -1) 137 ::close(dataFd); 138 --- 313 unchanged lines hidden (view full) --- 452 msg.namelen = 2; 453 msg.namelen = htobe(msg.namelen); 454 memcpy(msg.name, "M5", 2); 455 456 write(&msg); 457 curState = NormalPhase; 458} 459 |
468 | |
469void 470VncServer::setPixelFormat() 471{ 472 DPRINTF(VNC, "Received pixel format from client message\n"); 473 474 PixelFormatMessage pfm; 475 read1((uint8_t*)&pfm, sizeof(PixelFormatMessage)); 476 --- 126 unchanged lines hidden (view full) --- 603 604} 605 606 607void 608VncServer::sendFrameBufferUpdate() 609{ 610 | 460void 461VncServer::setPixelFormat() 462{ 463 DPRINTF(VNC, "Received pixel format from client message\n"); 464 465 PixelFormatMessage pfm; 466 read1((uint8_t*)&pfm, sizeof(PixelFormatMessage)); 467 --- 126 unchanged lines hidden (view full) --- 594 595} 596 597 598void 599VncServer::sendFrameBufferUpdate() 600{ 601 |
611 if (!clientRfb || dataFd <= 0 || curState != NormalPhase || !sendUpdate) { | 602 if (!fbPtr || dataFd <= 0 || curState != NormalPhase || !sendUpdate) { |
612 DPRINTF(VNC, "NOT sending framebuffer update\n"); 613 return; 614 } 615 616 assert(vc); 617 618 // The client will request data constantly, unless we throttle it 619 sendUpdate = false; --- 18 unchanged lines hidden (view full) --- 638 fbr.width = htobe(fbr.width); 639 fbr.height = htobe(fbr.height); 640 fbr.encoding = htobe(fbr.encoding); 641 642 // send headers to client 643 write(&fbu); 644 write(&fbr); 645 | 603 DPRINTF(VNC, "NOT sending framebuffer update\n"); 604 return; 605 } 606 607 assert(vc); 608 609 // The client will request data constantly, unless we throttle it 610 sendUpdate = false; --- 18 unchanged lines hidden (view full) --- 629 fbr.width = htobe(fbr.width); 630 fbr.height = htobe(fbr.height); 631 fbr.encoding = htobe(fbr.encoding); 632 633 // send headers to client 634 write(&fbu); 635 write(&fbr); 636 |
646 assert(clientRfb); | 637 assert(fbPtr); |
647 | 638 |
648 uint8_t *tmp = vc->convert(clientRfb); | 639 uint8_t *tmp = vc->convert(fbPtr); |
649 write(tmp, videoWidth() * videoHeight() * sizeof(uint32_t)); 650 delete [] tmp; 651 652} 653 654void 655VncServer::sendFrameBufferResized() 656{ | 640 write(tmp, videoWidth() * videoHeight() * sizeof(uint32_t)); 641 delete [] tmp; 642 643} 644 645void 646VncServer::sendFrameBufferResized() 647{ |
657 assert(clientRfb && dataFd > 0 && curState == NormalPhase); | 648 assert(fbPtr && dataFd > 0 && curState == NormalPhase); |
658 DPRINTF(VNC, "Sending framebuffer resize\n"); 659 660 FrameBufferUpdate fbu; 661 FrameBufferRect fbr; 662 663 fbu.type = ServerFrameBufferUpdate; 664 fbu.num_rects = 1; 665 fbr.x = 0; --- 13 unchanged lines hidden (view full) --- 679 // send headers to client 680 write(&fbu); 681 write(&fbr); 682 683 // No actual data is sent in this message 684} 685 686void | 649 DPRINTF(VNC, "Sending framebuffer resize\n"); 650 651 FrameBufferUpdate fbu; 652 FrameBufferRect fbr; 653 654 fbu.type = ServerFrameBufferUpdate; 655 fbu.num_rects = 1; 656 fbr.x = 0; --- 13 unchanged lines hidden (view full) --- 670 // send headers to client 671 write(&fbu); 672 write(&fbr); 673 674 // No actual data is sent in this message 675} 676 677void |
687VncServer::setFrameBufferParams(VideoConvert::Mode mode, int width, int height) | 678VncServer::setFrameBufferParams(VideoConvert::Mode mode, uint16_t width, 679 uint16_t height) |
688{ | 680{ |
689 DPRINTF(VNC, "Updating video params: mode: %d width: %d height: %d\n", mode, 690 width, height); | 681 VncInput::setFrameBufferParams(mode, width, height); |
691 692 if (mode != videoMode || width != videoWidth() || height != videoHeight()) { | 682 683 if (mode != videoMode || width != videoWidth() || height != videoHeight()) { |
693 videoMode = mode; 694 _videoWidth = width; 695 _videoHeight = height; 696 697 if (vc) 698 delete vc; 699 700 vc = new VideoConvert(mode, VideoConvert::rgb8888, videoWidth(), 701 videoHeight()); 702 703 if (captureEnabled) { 704 // create bitmap of the frame with new attributes 705 if (captureBitmap) 706 delete captureBitmap; 707 708 assert(clientRfb); 709 captureBitmap = new Bitmap(videoMode, width, height, clientRfb); 710 assert(captureBitmap); 711 } 712 713 if (dataFd > 0 && clientRfb && curState == NormalPhase) { | 684 if (dataFd > 0 && fbPtr && curState == NormalPhase) { |
714 if (supportsResizeEnc) 715 sendFrameBufferResized(); 716 else 717 // The frame buffer changed size and we can't update the client 718 detach(); 719 } 720 } 721} 722 723// create the VNC server object 724VncServer * 725VncServerParams::create() 726{ 727 return new VncServer(this); 728} 729 | 685 if (supportsResizeEnc) 686 sendFrameBufferResized(); 687 else 688 // The frame buffer changed size and we can't update the client 689 detach(); 690 } 691 } 692} 693 694// create the VNC server object 695VncServer * 696VncServerParams::create() 697{ 698 return new VncServer(this); 699} 700 |
730void 731VncServer::captureFrameBuffer() 732{ 733 assert(captureBitmap); 734 735 // skip identical frames 736 uint64_t new_hash = captureBitmap->getHash(); 737 if (captureLastHash == new_hash) 738 return; 739 captureLastHash = new_hash; 740 741 // get the filename for the current frame 742 char frameFilenameBuffer[64]; 743 snprintf(frameFilenameBuffer, 64, "fb.%06d.%lld.bmp.gz", 744 captureCurrentFrame, static_cast<long long int>(curTick())); 745 const string frameFilename(frameFilenameBuffer); 746 747 // create the compressed framebuffer file 748 ostream *fb_out = simout.create(captureOutputDirectory + frameFilename, 749 true); 750 captureBitmap->write(fb_out); 751 simout.close(fb_out); 752 753 ++captureCurrentFrame; 754} | |