VNC截图方案

fakayang 2012-05-12 10:47:21
本人小白中的小白,哪位大侠能够解释一下以下代码的截图方案啊。又如何编代码实现存储呢?

// ScrBuffer implementation

#include "stdhdrs.h"

// Header

#include "vncDesktop.h"
#include "vncEncoder.h"
#include "vncEncodeRRE.h"
#include "vncEncodeCoRRE.h"
#include "vncEncodeHexT.h"


#include "vncBuffer.h"

// Implementation

vncBuffer::vncBuffer(vncDesktop *desktop)
{
m_desktop = desktop;
m_encoder = NULL;

m_freemainbuff = FALSE;
m_mainbuff = NULL;
m_backbuff = NULL;
m_mainsize = 0;

m_clientbuff = NULL;
m_clientbuffsize = 0;
m_clientfmtset = FALSE;

// Initialise the screen buffers
CheckBuffer();
}

vncBuffer::~vncBuffer()
{
if (m_freemainbuff) {
// We need to free the slow-blit buffer
if (m_mainbuff != NULL)
{
delete [] m_mainbuff;
m_mainbuff = NULL;
}
}
if (m_backbuff != NULL)
{
delete [] m_backbuff;
m_backbuff = NULL;
}
if (m_encoder != NULL)
{
delete m_encoder;
m_encoder = NULL;
}
if (m_clientbuff != NULL)
{
delete m_clientbuff;
m_clientbuff = NULL;
}
m_clientbuffsize = 0;
m_mainsize = 0;
}

RECT
vncBuffer::GetSize()
{
RECT rect;

rect.left = 0;
rect.top = 0;
rect.right = m_scrinfo.framebufferWidth;
rect.bottom = m_scrinfo.framebufferHeight;

return rect;
}

rfbPixelFormat
vncBuffer::GetLocalFormat()
{
return m_scrinfo.format;
}

BYTE *
vncBuffer::GetClientBuffer()
{
return m_clientbuff;
}

BOOL
vncBuffer::GetRemotePalette(RGBQUAD *quadlist, UINT ncolours)
{
// Try to get the RGBQUAD data from the encoder
// This will only work if the remote client is palette-based,
// in which case the encoder will be storing RGBQUAD data
if (m_encoder == NULL)
{
log.Print(LL_INTWARN, VNCLOG("GetRemotePalette called but no encoder set\n"));
return FALSE;
}

// Now get the palette data
return m_encoder->GetRemotePalette(quadlist, ncolours);
}

BOOL
vncBuffer::CheckBuffer()
{
// Get the screen format, in case it has changed
m_desktop->FillDisplayInfo(&m_scrinfo);

// If the client has not specified a pixel format then set one for it
if (!m_clientfmtset) {
m_clientfmtset = TRUE;
m_clientformat = m_scrinfo.format;
}

// If the client has not selected an encoding then set one for it
if (m_encoder == NULL) {
if (!SetEncoding(rfbEncodingRaw))
return FALSE;
}

m_bytesPerRow = m_scrinfo.framebufferWidth * m_scrinfo.format.bitsPerPixel/8;

// Check the client buffer is sufficient
const UINT clientbuffsize =
m_encoder->RequiredBuffSize(m_scrinfo.framebufferWidth,
m_scrinfo.framebufferHeight);
if (m_clientbuffsize != clientbuffsize)
{
if (m_clientbuff != NULL)
{
delete [] m_clientbuff;
m_clientbuff = NULL;
}
m_clientbuffsize = 0;

m_clientbuff = new BYTE [clientbuffsize];
if (m_clientbuff == NULL)
{
log.Print(LL_INTERR, VNCLOG("unable to allocate client buffer[%d]\n"), clientbuffsize);
return FALSE;
}

m_clientbuffsize = clientbuffsize;

ZeroMemory(m_clientbuff, m_clientbuffsize);
}

// Check that the local format buffers are sufficient
if ((m_mainsize != m_desktop->ScreenBuffSize()) || !m_freemainbuff)
{
if (m_freemainbuff) {
// Slow blits were enabled - free the slow blit buffer
if (m_mainbuff != NULL)
{
delete [] m_mainbuff;
m_mainbuff = NULL;
}
}

if (m_backbuff != NULL)
{
delete [] m_backbuff;
m_backbuff = NULL;
}
m_mainsize = 0;

// Check whether or not the vncDesktop is using fast blits
m_mainbuff = (BYTE *)m_desktop->OptimisedBlitBuffer();
if (m_mainbuff) {
// Prevent us from freeing the DIBsection buffer
m_freemainbuff = FALSE;
log.Print(LL_INTINFO, VNCLOG("fast blits detected - using DIBsection buffer\n"));
} else {
// Create our own buffer to copy blits through
m_freemainbuff = TRUE;
if ((m_mainbuff = new BYTE [m_desktop->ScreenBuffSize()]) == NULL)
{
log.Print(LL_INTERR, VNCLOG("unable to allocate main buffer[%d]\n"), m_desktop->ScreenBuffSize());
return FALSE;
}
}

// Always create a back buffer
if ((m_backbuff = new BYTE [m_desktop->ScreenBuffSize()]) == NULL)
{
log.Print(LL_INTERR, VNCLOG("unable to allocate back buffer[%d]\n"), m_desktop->ScreenBuffSize());
return FALSE;
}
m_mainsize = m_desktop->ScreenBuffSize();

// Clear the backbuffer
memcpy(m_backbuff, m_mainbuff, m_desktop->ScreenBuffSize());
}

log.Print(LL_INTINFO, VNCLOG("local buffer=%d, remote buffer=%d\n"), m_mainsize, m_clientbuffsize);

return TRUE;
}

// returns true if any *(p1+n) != *(p2+n) for 0<n<count-1
inline static bool
bytesdiff(BYTE *p1, BYTE *p2, int count) {
for (int i=0; i<count; i++) {
if (*(p1+i) != *(p2+i)) return true;
}
return false;
}

// New version of GetChangedRegion. This version tries to avoid
// sending too much unnecessary data.
#pragma function(memcpy,memcmp)
void
vncBuffer::GetChangedRegion(vncRegion &rgn, RECT &rect)
{
if (!FastCheckMainbuffer())
return;

const int BLOCK_SIZE = 32;
const UINT bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8;

RECT new_rect;

int x, y, ay, by;

// DWORD align the incoming rectangle. (bPP will be 8, 16 or 32)
if (bytesPerPixel < 4) {
if (bytesPerPixel == 1) // 1 byte per pixel
rect.left -= (rect.left & 3); // round down to nearest multiple of 4
else // 2 bytes per pixel
rect.left -= (rect.left & 1); // round down to nearest multiple of 2
}

// Scan down the rectangle
unsigned char *o_topleft_ptr = m_backbuff + (rect.top * m_bytesPerRow) + (rect.left * bytesPerPixel);
unsigned char *n_topleft_ptr = m_mainbuff + (rect.top * m_bytesPerRow) + (rect.left * bytesPerPixel);
for (y = rect.top; y<rect.bottom; y+=BLOCK_SIZE)
{
// Work out way down the bitmap
unsigned char * o_row_ptr = o_topleft_ptr;
unsigned char * n_row_ptr = n_topleft_ptr;

const UINT blockbottom = Min(y+BLOCK_SIZE, rect.bottom);
for (x = rect.left; x<rect.right; x+=BLOCK_SIZE)
{
// Work our way across the row
unsigned char *n_block_ptr = n_row_ptr;
unsigned char *o_block_ptr = o_row_ptr;

const UINT blockright = Min(x+BLOCK_SIZE, rect.right);
const UINT bytesPerBlockRow = (blockright-x) * bytesPerPixel;

// Scan this block
for (ay = y; ay < blockbottom; ay++)
{
if (memcmp(n_block_ptr, o_block_ptr, bytesPerBlockRow) != 0)
{
// A pixel has changed, so this block needs updating
new_rect.top = y;
new_rect.left = x;
new_rect.right = blockright;
new_rect.bottom = blockbottom;
rgn.AddRect(new_rect);

// Copy the changes to the back buffer
for (by = ay; by < blockbottom; by++)
{
memcpy(o_block_ptr, n_block_ptr, bytesPerBlockRow);
n_block_ptr+=m_bytesPerRow;
o_block_ptr+=m_bytesPerRow;
}

break;
}

n_block_ptr += m_bytesPerRow;
o_block_ptr += m_bytesPerRow;
}

o_row_ptr += bytesPerBlockRow;
n_row_ptr += bytesPerBlockRow;
}

o_topleft_ptr += m_bytesPerRow * BLOCK_SIZE;
n_topleft_ptr += m_bytesPerRow * BLOCK_SIZE;
}
}

UINT
vncBuffer::GetNumCodedRects(RECT &rect)
{
// Ask the encoder how many rectangles this update would become
return m_encoder->NumCodedRects(rect);
}

void
vncBuffer::GrabRect(RECT &rect)
{
if (!FastCheckMainbuffer())
return;
m_desktop->CaptureScreen(rect, m_mainbuff, m_mainsize);
}

void
vncBuffer::CopyRect(RECT &dest, POINT &source)
{
// Copy the data from one region of the back-buffer to another!
BYTE *srcptr = m_backbuff + (source.y * m_bytesPerRow) +
(source.x * m_scrinfo.format.bitsPerPixel/8);
BYTE *destptr = m_backbuff + (dest.top * m_bytesPerRow) +
(dest.left * m_scrinfo.format.bitsPerPixel/8);
const UINT bytesPerLine = (dest.right-dest.left)*(m_scrinfo.format.bitsPerPixel/8);
if (dest.top < source.y)
{
for (int y=dest.top; y < dest.bottom; y++)
{
memmove(destptr, srcptr, bytesPerLine);
srcptr+=m_bytesPerRow;
destptr+=m_bytesPerRow;
}
}
else
{
srcptr += (m_bytesPerRow * ((dest.bottom-dest.top)-1));
destptr += (m_bytesPerRow * ((dest.bottom-dest.top)-1));
for (int y=dest.bottom; y > dest.top; y--)
{
memmove(destptr, srcptr, bytesPerLine);
srcptr-=m_bytesPerRow;
destptr-=m_bytesPerRow;
}
}
}

RECT
vncBuffer::GrabMouse()
{
if (FastCheckMainbuffer()) {
m_desktop->CaptureScreen(m_desktop->MouseRect(), m_mainbuff, m_mainsize);
m_desktop->CaptureMouse(m_mainbuff, m_mainsize);
}
return m_desktop->MouseRect();
}

BOOL
vncBuffer::SetClientFormat(rfbPixelFormat &format)
{
log.Print(LL_INTINFO, VNCLOG("SetClientFormat called\n"));

// Save the desired format
m_clientfmtset = TRUE;
m_clientformat = format;

// Tell the encoder of the new format
if (m_encoder != NULL)
m_encoder->SetRemoteFormat(format);

// Check that the output buffer is sufficient
if (!CheckBuffer())
return FALSE;

return TRUE;
}
...全文
449 1 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
觅食的猫猫 2012-05-12
  • 打赏
  • 举报
回复
这么长的代码,就没自己疑问的地方吗...
客户机远程维护VNC自动配置方案 ============================================================= 【软件简介】 VNC(Virtual Network Computing,虚拟网络计算)最早是一套由英国剑桥大学ATT实验室在2002年开发的轻量型的远程控制计算机软件,其采用了 GPL 授权条款,任何人都可免费取得该软件。VNC软件主要由两个部分组成:VNC server及VNC viewer。用户需先将VNC server安装在被控端的计算机上后,才能在主控端执行 VNC viewer 控制被控端。 VNC server 与 VNC viewer 支持多种操作系统,如 windows,Linux,MacOS 及 Unix 系列(Unix,Solaris等),因此可将 VNC server 及 VNC viewer 分别安装在不同的操作系统中进行控制。RealVNC 的优越性还在于如果操作系统的主控端计算机没有安装 VNC viewer,也可以通过一般的网络浏览器(如 IE 等)来控制被控端(需要 Java 虚拟机的支持)。 整个 VNC 一般运行的工作流程如下: (1) VNC 客户端通过浏览器或 VNC Viewer 连接至 VNC Server。 (2) VNC Server 传送一对话窗口至客户端,要求输入连接密码(可能为空),以及存取的 VNC Server 显示装置。 (3) 在客户端输入连接密码后,VNC Server 验证客户端是否具有存取权限。 (4) 若是客户端通过 VNC Server 的验证,客户端即要求 VNC Server 显示桌面环境。 (5) 被控端将画面显示控制权交由 VNC Server 负责。 (6) VNC Server 将把被控端的桌面环境利用 VNC 通信协议送至客户端,并且允许客户端控制 VNC Server 的桌面环境及输入装置。 ------------------------------------------------------------- 【特别说明】 JMKT5-SAQF9-SLD2P-NPECM-TEXXA YLYDY-NSK95-KN2BG-KTN9C-92GJA 3XT42-LU2BP-N7JV2-BTSWL-7NKFA 3CJFW-2HLA6-KA44E-ZWG6D-9BT4A 安装方法: 解压RealVNC文件夹,配置到开机命或者系统安装,run.bat增加以下内容 rem 检测客户机还原状态 attrib -r -a -s -h \"d:\\ProtectedC00.sys\" if exist d:\\ProtectedC00.sys del /f /q d:\\ProtectedC00.sys 2>nul 1>nul rem 以下2行制定为非还原状态,安装远程控制服务! if exist d:\\ProtectedC00.sys call RealVNC\\unvnc.bat if not exist d:\\ProtectedC00.sys call RealVNC\\invnc.bat rem 注意:默认为系统账号和密码登陆! ============================================================= 安装批处理: @echo off if not exist \"C:\\Program Files\\RealVNC\" md \"C:\\Program Files\\RealVNC\" xcopy /d/r/y/e/h \"%~dp0*.*\" \"C:\\Program Files\\RealVNC\\\" 1>nul 2>nul set path=%path%;C:\\Program Files\\RealVNC sc query winvnc4|find /i \"指定的服务未安装\"&&call :register && exit sc query winvnc4|find /i \"STOPPED\"&&winvnc4.exe -start && exit exit :register winvnc4.exe -register vncconfig.exe -license JMKT5-SAQF9-SLD2P-NPECM-TEXXA regedit /s RealVNC.reg winvnc4.exe -start :eof 卸载批处理: @echo off if not exist \"C:\\Program Files\\RealVNC\\winvnc4.exe\" goto endvnc sc query winvnc4|find /i \"指定的服务未安装\" 1>nul 2>nul&&goto jumpvnc sc query winvnc4|find /i \"RUNNING\" 1>nul 2>nul&&winvnc4.exe -stop set path=%path%;C:\\Program Files\\RealVNC winvnc4.exe -unregister 1>nul 2>nul :jumpvnc reg delete \"HKEY_LOCAL_MACHINE\\SOFTWARE\\RealVNC\" /f 1>nul 2>nul if \"%~dp0\"==\"C:\\Program Files\\RealVNC\\\" cd.. rd /s /q \"C:\\Program Files\\RealVNC\" 1>nul 2>nul :endvnc 控制批处理: @echo off set path=%path%;C:\\Program Files\\RealVNC sc query winvnc4|find /i \"指定的服务未安装\"&&call :register && exit sc query winvnc4|find /i \"STOPPED\"&&winvnc4.exe -start && exit sc query winvnc4|find /i \"RUNNING\"&&winvnc4.exe -stop && exit :register winvnc4.exe -register vncconfig.exe -license JMKT5-SAQF9-SLD2P-NPECM-TEXXA regedit /s RealVNC.reg winvnc4.exe -start :eof

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧