From ff9eb5a949f7af0198db8c563a7d9d735ad083c3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 30 Jan 2014 17:47:31 +0100 Subject: [PATCH] Get rid of the direct access abuse of FullFramePixelBuffer's data --- common/rfb/PixelBuffer.h | 5 ++--- common/rfb/SDesktop.h | 4 ++-- common/rfb/VNCSConnectionST.cxx | 16 +++++++++++----- common/rfb/VNCServer.h | 2 +- common/rfb/VNCServerST.cxx | 17 ++++++++++++----- common/rfb/VNCServerST.h | 2 +- vncviewer/Viewport.cxx | 14 ++++++++++---- win/rfb_win32/DeviceFrameBuffer.cxx | 25 +++++++++++++++++++------ 8 files changed, 58 insertions(+), 27 deletions(-) diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h index bff28021..94230247 100644 --- a/common/rfb/PixelBuffer.h +++ b/common/rfb/PixelBuffer.h @@ -130,11 +130,10 @@ namespace rfb { // pixel is the Pixel value to be used where mask_ is set void maskRect(const Rect& r, Pixel pixel, const void* mask_); - // *** Should this be visible? - rdr::U8* data; - protected: FullFramePixelBuffer(); + + rdr::U8* data; }; // -=- Managed pixel buffer class diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h index 57ceb076..546506a9 100644 --- a/common/rfb/SDesktop.h +++ b/common/rfb/SDesktop.h @@ -93,11 +93,11 @@ namespace rfb { SStaticDesktop(const Point& size) : server(0), buffer(0) { PixelFormat pf; buffer = new ManagedPixelBuffer(pf, size.x, size.y); - if (buffer) memset(buffer->data, 0, (pf.bpp/8) * (size.x*size.y)); + if (buffer) buffer->fillRect(buffer->getRect(), 0); } SStaticDesktop(const Point& size, const PixelFormat& pf) : buffer(0) { buffer = new ManagedPixelBuffer(pf, size.x, size.y); - if (buffer) memset(buffer->data, 0, (pf.bpp/8) * (size.x*size.y)); + if (buffer) buffer->fillRect(buffer->getRect(), 0); } virtual ~SStaticDesktop() { if (buffer) delete buffer; diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index a4b704a4..fcb678ad 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009-2011 Pierre Ossman for Cendio AB + * Copyright 2009-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -737,13 +737,19 @@ void VNCSConnectionST::writeSetCursorCallback() } // Use RichCursor - rdr::U8* transData = writer()->getImageBuf(server->cursor.area()); - image_getter.translatePixels(server->cursor.data, transData, - server->cursor.area()); + rdr::U8* transBuffer; + int stride; + const rdr::U8* buffer; + + transBuffer = writer()->getImageBuf(server->cursor.area()); + + buffer = server->cursor.getBuffer(server->cursor.getRect(), &stride); + image_getter.translatePixels(buffer, transBuffer, server->cursor.area()); + writer()->writeSetCursor(server->cursor.width(), server->cursor.height(), server->cursor.hotspot, - transData, server->cursor.mask.buf); + transBuffer, server->cursor.mask.buf); } diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h index 787bf8cb..c76e5c9c 100644 --- a/common/rfb/VNCServer.h +++ b/common/rfb/VNCServer.h @@ -73,7 +73,7 @@ namespace rfb { // in left-to-right order. The server takes its own copy of the data in // cursorData and mask. virtual void setCursor(int width, int height, const Point& hotspot, - void* cursorData, void* mask) = 0; + const void* cursorData, const void* mask) = 0; // setCursorPos() tells the server the current position of the cursor. virtual void setCursorPos(const Point& p) = 0; diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index db142fe4..f1e378ed 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2009-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -408,11 +409,11 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta) } void VNCServerST::setCursor(int width, int height, const Point& newHotspot, - void* data, void* mask) + const void* data, const void* mask) { cursor.hotspot = newHotspot; cursor.setSize(width, height); - memcpy(cursor.data, data, cursor.dataLen()); + cursor.imageRect(cursor.getRect(), data); memcpy(cursor.mask.buf, mask, cursor.maskLen()); cursor.crop(); @@ -621,11 +622,17 @@ bool VNCServerST::checkUpdate() comparer->getUpdateInfo(&ui, pb->getRect()); if (renderCursor) { - pb->getImage(renderedCursor.data, - renderedCursor.getRect(renderedCursorTL)); + const rdr::U8* buffer; + int stride; + + buffer = pb->getBuffer(renderedCursor.getRect(renderedCursorTL), &stride); + renderedCursor.imageRect(renderedCursor.getRect(), buffer, stride); + + buffer = cursor.getBuffer(cursor.getRect(), &stride); renderedCursor.maskRect(cursor.getRect(cursorTL() .subtract(renderedCursorTL)), - cursor.data, cursor.mask.buf); + buffer, cursor.mask.buf); + renderedCursorInvalid = false; } diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 88d02559..ed7833ab 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -92,7 +92,7 @@ namespace rfb { virtual void add_changed(const Region ®ion); virtual void add_copied(const Region &dest, const Point &delta); virtual void setCursor(int width, int height, const Point& hotspot, - void* cursorData, void* mask); + const void* cursorData, const void* mask); virtual void setCursorPos(const Point& p); virtual void bell(); diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx index a930cf89..d1d51622 100644 --- a/vncviewer/Viewport.cxx +++ b/vncviewer/Viewport.cxx @@ -1,5 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2011 Pierre Ossman for Cendio AB + * Copyright 2011-2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -223,10 +223,12 @@ void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) { void Viewport::imageRect(const rfb::Rect& r, void* pixels) { if (pixelTrans) { + rdr::U8* buffer; + int stride; + buffer = frameBuffer->getBufferRW(r, &stride); pixelTrans->translateRect(pixels, r.width(), rfb::Rect(0, 0, r.width(), r.height()), - frameBuffer->data, frameBuffer->getStride(), - r.tl); + buffer, stride, rfb::Point(0, 0)); } else { frameBuffer->imageRect(r, pixels); } @@ -348,6 +350,9 @@ void Viewport::resize(int x, int y, int w, int h) PlatformPixelBuffer* newBuffer; rfb::Rect rect; + const rdr::U8* data; + int stride; + // FIXME: Resize should probably be a feature of the pixel buffer itself if ((w == frameBuffer->width()) && (h == frameBuffer->height())) @@ -362,7 +367,8 @@ void Viewport::resize(int x, int y, int w, int h) rect.setXYWH(0, 0, __rfbmin(newBuffer->width(), frameBuffer->width()), __rfbmin(newBuffer->height(), frameBuffer->height())); - newBuffer->imageRect(rect, frameBuffer->data, frameBuffer->getStride()); + data = frameBuffer->getBuffer(frameBuffer->getRect(), &stride); + newBuffer->imageRect(rect, data, stride); // Black out any new areas diff --git a/win/rfb_win32/DeviceFrameBuffer.cxx b/win/rfb_win32/DeviceFrameBuffer.cxx index 33b1be5a..0ad06e9e 100644 --- a/win/rfb_win32/DeviceFrameBuffer.cxx +++ b/win/rfb_win32/DeviceFrameBuffer.cxx @@ -1,4 +1,5 @@ /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. + * Copyright 2014 Pierre Ossman for Cendio AB * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -141,6 +142,10 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server) try { + const rdr::U8* buffer; + rdr::U8* rwbuffer; + int stride; + // - Get the size and other details about the cursor. IconInfo iconInfo((HICON)hCursor); @@ -192,6 +197,7 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server) bool doOutline = false; if (!iconInfo.hbmColor) { + rwbuffer = cursorBm.getBufferRW(cursorBm.getRect(), &stride); Pixel xorColour = format.pixelFromRGB((rdr::U16)0, (rdr::U16)0, (rdr::U16)0); for (int y = 0; y < cursor.height(); y++) { for (int x = 0; x < cursor.width(); x++) { @@ -203,11 +209,11 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server) switch (format.bpp) { case 8: - ((rdr::U8*)cursorBm.data)[y * cursor.width() + x] = xorColour; break; + rwbuffer[y * cursor.width() + x] = xorColour; break; case 16: - ((rdr::U16*)cursorBm.data)[y * cursor.width() + x] = xorColour; break; + rwbuffer[y * cursor.width() + x] = xorColour; break; case 32: - ((rdr::U32*)cursorBm.data)[y * cursor.width() + x] = xorColour; break; + rwbuffer[y * cursor.width() + x] = xorColour; break; } doOutline = true; @@ -229,13 +235,20 @@ void DeviceFrameBuffer::setCursor(HCURSOR hCursor, VNCServer* server) if (doOutline) { vlog.debug("drawing cursor outline!"); - memcpy(cursor.data, cursorBm.data, cursor.dataLen()); + + buffer = cursorBm.getBuffer(cursorBm.getRect(), &stride); + cursor.imageRect(cursorBm.getRect(), buffer, stride); + cursor.drawOutline(format.pixelFromRGB((rdr::U16)0xffff, (rdr::U16)0xffff, (rdr::U16)0xffff)); - memcpy(cursorBm.data, cursor.data, cursor.dataLen()); + + buffer = cursor.getBuffer(cursor.getRect(), &stride); + cursorBm.imageRect(cursor.getRect(), buffer, stride); } + buffer = cursorBm.getBuffer(cursorBm.getRect(), &stride); server->setCursor(cursor.width(), cursor.height(), cursor.hotspot, - cursorBm.data, cursor.mask.buf); + buffer, cursor.mask.buf); + } catch (rdr::Exception& e) { vlog.error("%s", e.str()); } -- 2.39.5