📄 vncbuffer.cpp
字号:
if (fCanReduceColors)
{
lScaledPixel = To8GreyColors(lRed, lGreen, lBlue);
}
else
{
// Calculate the resulting "medium" pixel
lScaledPixel = (lRed << m_scrinfo.format.redShift) + (lGreen << m_scrinfo.format.greenShift) + (lBlue << m_scrinfo.format.blueShift);
}
// Copy the resulting pixel in the Scaled Buffer
for (int b = 0; b < nBytesPerPixel; b++)
{
pScaled[(x * nBytesPerPixel) + b] = (BYTE)(lScaledPixel >> (8 * b)) & 0xFF;
}
}
// Move the buffers' pointers to their next "line"
pMain += (m_bytesPerRow * m_nScale); // Skip m_nScale raws of the mainbuffer's Rect
pScaled += m_bytesPerRow;
}
}
// Keep only the topleft pixel of each MainBuffer's m_Scale*m_nScale block
// Very incurate method...but bearable result in 256 and 16bit colors modes.
else
{
UINT nBytesPerPixel = (m_scrinfo.format.bitsPerPixel / 8);
for (int y = ScaledRect.tl.y; y < ScaledRect.br.y; y++)
{
for (int x = 0; x < (ScaledRect.br.x - ScaledRect.tl.x); x++)
{
memcpy(&pScaled[x * nBytesPerPixel], &pMain[x * m_nScale * nBytesPerPixel], nBytesPerPixel);
}
// Move the buffers' pointers to their next "line"
pMain += (m_bytesPerRow * m_nScale); // Skip m_nScale lines of the mainbuffer's Rect
pScaled += m_bytesPerRow;
}
}
}
// Modif sf@2005 - Grey Scale transformation
// Ok, it's a little wild to do it here... should be done in Translate.cpp,..
void vncBuffer::GreyScaleRect(rfb::Rect &rect)
{
bool fCanReduceColors = true;
//JK 26th Jan, 2005: Color conversion to 8 shades of gray added,
//at the moment only works if server has 24/32-bit color
if ((m_scrinfo.format.redMax == 255)
&&
(m_scrinfo.format.blueMax == 255)
&&
(m_scrinfo.format.greenMax == 255)
&&
m_fGreyPalette
)
fCanReduceColors = true;
else
fCanReduceColors = false;
//End JK
if (!fCanReduceColors) return;
// if (!m_scrinfo.format.trueColour) return;
UINT nBytesPerPixel = (m_scrinfo.format.bitsPerPixel / 8);
// Copy and scale data from screen Main buffer to Scaled buffer
BYTE *pMain = m_mainbuff + (rect.tl.y * m_bytesPerRow) +
(rect.tl.x * m_scrinfo.format.bitsPerPixel / 8);
unsigned long lRed;
unsigned long lGreen;
unsigned long lBlue;
unsigned long lPixel;
for (int y = rect.tl.y; y < rect.br.y; y++)
{
for (int x = 0; x < (rect.br.x - rect.tl.x); x++)
{
lPixel = 0;
for (int b = 0; b < nBytesPerPixel; b++)
lPixel += ((pMain[(x * nBytesPerPixel) + b]) << (8 * b));
lRed = (lPixel >> m_scrinfo.format.redShift) & m_scrinfo.format.redMax;
lGreen = (lPixel >> m_scrinfo.format.greenShift) & m_scrinfo.format.greenMax;
lBlue = (lPixel >> m_scrinfo.format.blueShift) & m_scrinfo.format.blueMax;
lPixel = To8GreyColors(lRed, lGreen, lBlue);
for (int b = 0; b < nBytesPerPixel; b++)
pMain[(x * nBytesPerPixel) + b] = (BYTE)(lPixel >> (8 * b)) & 0xFF;
}
pMain += m_bytesPerRow;
}
}
void
vncBuffer::GrabRect(const rfb::Rect &rect,BOOL driver)
{
//no lock needed
if (!FastCheckMainbuffer()) return;
if (!driver) m_desktop->CaptureScreen(rect, m_mainbuff, m_backbuffsize);
// Modif sf@2002 - Scaling
// Only use scaledbuffer if necessary !
rfb::Rect TheRect = rect;
// if (m_nScale > 1) ScaleRect(rfb::Rect(rect.tl.x, rect.tl.y, rect.br.x, rect.br.y)); // sf@2002 - Waste of time !!!
if (m_nScale > 1)
ScaleRect(TheRect);
else if (m_fGreyPalette)
GreyScaleRect(TheRect);
}
void
vncBuffer::CopyRect(const rfb::Rect &dest, const rfb::Point &delta)
{
rfb::Rect ScaledDest;
rfb::Rect ScaledSource;
rfb::Rect src = dest.translate(delta.negate());
// Modif sf@2002 - Scaling
ScaledDest.tl.y = dest.tl.y / m_nScale;
ScaledDest.br.y = dest.br.y / m_nScale;
ScaledDest.tl.x = dest.tl.x / m_nScale;
ScaledDest.br.x = dest.br.x / m_nScale;
ScaledSource.tl.y = src.tl.y / m_nScale;
ScaledSource.br.y = src.br.y / m_nScale;
ScaledSource.tl.x = src.tl.x / m_nScale;
ScaledSource.br.x = src.br.x / m_nScale;
ClearCacheRect(ScaledSource);
ClearCacheRect(ScaledDest);
// Copy the data from one part of the back-buffer to another!
const UINT bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8;
const UINT bytesPerLine = (ScaledDest.br.x - ScaledDest.tl.x) * bytesPerPixel;
BYTE *srcptr = m_backbuff + (ScaledSource.tl.y * m_bytesPerRow) +
(ScaledSource.tl.x * bytesPerPixel);
BYTE *destptr = m_backbuff + (ScaledDest.tl.y * m_bytesPerRow) +
(ScaledDest.tl.x * bytesPerPixel);
// Copy the data around in the right order
if (ScaledDest.tl.y < ScaledSource.tl.y)
{
for (int y = ScaledDest.tl.y; y < ScaledDest.br.y; y++)
{
memmove(destptr, srcptr, bytesPerLine);
srcptr += m_bytesPerRow;
destptr += m_bytesPerRow;
}
}
else
{
srcptr += (m_bytesPerRow * ((ScaledDest.br.y - ScaledDest.tl.y)-1));
destptr += (m_bytesPerRow * ((ScaledDest.br.y - ScaledDest.tl.y)-1));
for (int y = ScaledDest.br.y; y > ScaledDest.tl.y; y--)
{
memmove(destptr, srcptr, bytesPerLine);
srcptr -= m_bytesPerRow;
destptr -= m_bytesPerRow;
}
}
}
void
vncBuffer::ClearCache()
{
m_cursor_shape_cleared=TRUE;
if (m_use_cache && m_cachebuff)
{
RECT dest;
dest.left=0;
dest.top=0;
dest.right=m_scrinfo.framebufferWidth;
dest.bottom=m_scrinfo.framebufferHeight;
// Modif sf@2002 - v1.1.0 - Scramble the cache
int nValue = 0;
BYTE *cacheptr = m_cachebuff + (dest.top * m_bytesPerRow) +
(dest.left * m_scrinfo.format.bitsPerPixel/8);
const UINT bytesPerLine = (dest.right-dest.left)*(m_scrinfo.format.bitsPerPixel/8);
for (int y=dest.top; y < dest.bottom; y++)
{
memset(cacheptr, nValue++, bytesPerLine);
cacheptr+=m_bytesPerRow;
if (nValue == 255) nValue = 0;
}
}
}
void
vncBuffer::ClearCacheRect(const rfb::Rect &dest)
{
if (m_use_cache && m_cachebuff)
{
if (!dest.is_empty())
{
int nValue = 0;
BYTE *cacheptr = m_cachebuff + (dest.tl.y * m_bytesPerRow) +
(dest.tl.x * m_scrinfo.format.bitsPerPixel/8);
const UINT bytesPerLine = (dest.br.x-dest.tl.x)*(m_scrinfo.format.bitsPerPixel/8);
for (int y=dest.tl.y; y < dest.br.y; y++)
{
memset(cacheptr, nValue++, bytesPerLine);
cacheptr+=m_bytesPerRow;
if (nValue == 255) nValue = 0;
}
}
}
}
void
vncBuffer::ClearBack()
{
if (m_mainbuff) memcpy(m_backbuff, m_mainbuff, m_desktop->ScreenBuffSize());
}
//***************************
// This is used on SW switch
// if backbuffer is not cleared
// the checker marks the rects
// as already send
//***************************
void
vncBuffer::BlackBack()
{
RECT dest;
dest.left=0;
dest.top=0;
dest.right=m_scrinfo.framebufferWidth;
dest.bottom=m_scrinfo.framebufferHeight;
int nValue = 1;
BYTE *backptr = 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);
for (int y=dest.top; y < dest.bottom; y++)
{
memset(backptr, nValue, bytesPerLine);
backptr+=m_bytesPerRow;
if (nValue == 255) nValue = 0;
}
}
void
vncBuffer::GrabMouse()
{
//no lock needed
if (!FastCheckMainbuffer()) return;
m_desktop->CaptureMouse(m_mainbuff, m_backbuffsize);
// Modif sf@2002 - Scaling
rfb::Rect rect = m_desktop->MouseRect();
if (m_nScale > 1)
ScaleRect(rect);
}
void
vncBuffer::GetMousePos(rfb::Rect &rect)
{
rect = m_desktop->MouseRect();
}
// Verify that the fast blit buffer hasn't changed
inline BOOL
vncBuffer::FastCheckMainbuffer() {
// Modif rdv@2002 - v1.1.x - videodriver
VOID *tmp = m_desktop->OptimisedBlitBuffer();
if (tmp && (m_mainbuff != tmp))
{
// omni_mutex_lock l(m_desktop->m_videodriver_lock2);
BOOL result=CheckBuffer();
return result;
}
return TRUE;
}
// sf@2005
void vncBuffer::EnableGreyPalette(BOOL enable)
{
m_fGreyPalette = enable;
}
// RDV
void
vncBuffer::EnableCache(BOOL enable)
{
m_use_cache = enable;
if (m_use_cache)
{
if (m_cachebuff != NULL)
{
delete [] m_cachebuff;
m_cachebuff = NULL;
}
if ((m_cachebuff = new BYTE [m_desktop->ScreenBuffSize()]) == NULL)
{
vnclog.Print(LL_INTERR, VNCLOG("unable to allocate cache buffer[%d]"), m_desktop->ScreenBuffSize());
return;
}
ClearCache();
// BlackBack();
}
/*else
{
if (m_cachebuff != NULL)
{
delete [] m_cachebuff;
m_cachebuff = NULL;
}
}*/
}
BOOL
vncBuffer::IsCacheEnabled()
{
return m_use_cache;
}
BOOL
vncBuffer::IsShapeCleared()
{
BOOL value=m_cursor_shape_cleared;
m_cursor_shape_cleared=FALSE;
return value;
}
void
vncBuffer::Display(int number)
{
if (number==1) m_display_prim=true;
if (number==-1) m_display_prim=false;
if (number==2) m_display_sec=true;
if (number==-2) m_display_sec=false;
}
int
vncBuffer::GetDisplay()
{
if (!m_display_prim && !m_display_sec) return 1;//we need at least 1 display
if (m_display_prim && !m_display_sec) return 1;
if (!m_display_prim &&m_display_sec) return 2;
if (m_display_prim &&m_display_sec) return 3;
return 1;
}
bool
vncBuffer::ClipRect(int *x, int *y, int *w, int *h,
int cx, int cy, int cw, int ch) {
if (*x < cx) {
*w -= (cx-*x);
*x = cx;
}
if (*y < cy) {
*h -= (cy-*y);
*y = cy;
}
if (*x+*w > cx+cw) {
*w = (cx+cw)-*x;
}
if (*y+*h > cy+ch) {
*h = (cy+ch)-*y;
}
return (*w>0) && (*h>0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -