|
|
12537a |
From 53f913a76196c7357d4858bfbf2c33caa9181bae Mon Sep 17 00:00:00 2001
|
|
|
12537a |
From: Pierre Ossman <ossman@cendio.se>
|
|
|
12537a |
Date: Tue, 10 Sep 2019 15:18:30 +0200
|
|
|
12537a |
Subject: [PATCH] Encapsulate PixelBuffer internal details
|
|
|
12537a |
|
|
|
12537a |
Don't allow subclasses to just override dimensions or buffer details
|
|
|
12537a |
directly and instead force them to go via methods. This allows us
|
|
|
12537a |
to do sanity checks on the new values and catch bugs and attacks.
|
|
|
12537a |
---
|
|
|
12537a |
common/rfb/Cursor.cxx | 3 +-
|
|
|
12537a |
common/rfb/EncodeManager.cxx | 5 +-
|
|
|
12537a |
common/rfb/PixelBuffer.cxx | 103 ++++++++++++++++----------
|
|
|
12537a |
common/rfb/PixelBuffer.h | 17 +++--
|
|
|
12537a |
unix/x0vncserver/XPixelBuffer.cxx | 9 +--
|
|
|
12537a |
unix/xserver/hw/vnc/XserverDesktop.cc | 24 +++---
|
|
|
12537a |
unix/xserver/hw/vnc/XserverDesktop.h | 2 +-
|
|
|
12537a |
vncviewer/PlatformPixelBuffer.cxx | 9 +--
|
|
|
12537a |
win/rfb_win32/DIBSectionBuffer.cxx | 41 ++++------
|
|
|
12537a |
9 files changed, 111 insertions(+), 102 deletions(-)
|
|
|
12537a |
|
|
|
12537a |
diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx
|
|
|
12537a |
index 99df82d..7f3fc9a 100644
|
|
|
12537a |
--- a/common/rfb/Cursor.cxx
|
|
|
12537a |
+++ b/common/rfb/Cursor.cxx
|
|
|
12537a |
@@ -271,8 +271,7 @@ void RenderedCursor::update(PixelBuffer* framebuffer,
|
|
|
12537a |
assert(cursor);
|
|
|
12537a |
|
|
|
12537a |
format = framebuffer->getPF();
|
|
|
12537a |
- width_ = framebuffer->width();
|
|
|
12537a |
- height_ = framebuffer->height();
|
|
|
12537a |
+ setSize(framebuffer->width(), framebuffer->height());
|
|
|
12537a |
|
|
|
12537a |
rawOffset = pos.subtract(cursor->hotspot());
|
|
|
12537a |
clippedRect = Rect(0, 0, cursor->width(), cursor->height())
|
|
|
12537a |
diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx
|
|
|
12537a |
index 0cd5206..1653cea 100644
|
|
|
12537a |
--- a/common/rfb/EncodeManager.cxx
|
|
|
12537a |
+++ b/common/rfb/EncodeManager.cxx
|
|
|
12537a |
@@ -891,11 +891,8 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf,
|
|
|
12537a |
int stride_)
|
|
|
12537a |
{
|
|
|
12537a |
format = pf;
|
|
|
12537a |
- width_ = width;
|
|
|
12537a |
- height_ = height;
|
|
|
12537a |
// Forced cast. We never write anything though, so it should be safe.
|
|
|
12537a |
- data = (rdr::U8*)data_;
|
|
|
12537a |
- stride = stride_;
|
|
|
12537a |
+ setBuffer(width, height, (rdr::U8*)data_, stride_);
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
// Preprocessor generated, optimised methods
|
|
|
12537a |
diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx
|
|
|
12537a |
index 007b6c8..ad58324 100644
|
|
|
12537a |
--- a/common/rfb/PixelBuffer.cxx
|
|
|
12537a |
+++ b/common/rfb/PixelBuffer.cxx
|
|
|
12537a |
@@ -35,8 +35,14 @@ static LogWriter vlog("PixelBuffer");
|
|
|
12537a |
// -=- Generic pixel buffer class
|
|
|
12537a |
|
|
|
12537a |
PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h)
|
|
|
12537a |
- : format(pf), width_(w), height_(h) {}
|
|
|
12537a |
-PixelBuffer::PixelBuffer() : width_(0), height_(0) {}
|
|
|
12537a |
+ : format(pf), width_(0), height_(0)
|
|
|
12537a |
+{
|
|
|
12537a |
+ setSize(w, h);
|
|
|
12537a |
+}
|
|
|
12537a |
+
|
|
|
12537a |
+PixelBuffer::PixelBuffer() : width_(0), height_(0)
|
|
|
12537a |
+{
|
|
|
12537a |
+}
|
|
|
12537a |
|
|
|
12537a |
PixelBuffer::~PixelBuffer() {}
|
|
|
12537a |
|
|
|
12537a |
@@ -53,7 +59,7 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
r.width(), r.height(),
|
|
|
12537a |
- r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
data = getBuffer(r, &inStride);
|
|
|
12537a |
|
|
|
12537a |
@@ -89,7 +95,7 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf,
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
r.width(), r.height(),
|
|
|
12537a |
- r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
if (stride == 0)
|
|
|
12537a |
stride = r.width();
|
|
|
12537a |
@@ -100,6 +106,12 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf,
|
|
|
12537a |
stride, srcStride);
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
+void PixelBuffer::setSize(int width, int height)
|
|
|
12537a |
+{
|
|
|
12537a |
+ width_ = width;
|
|
|
12537a |
+ height_ = height;
|
|
|
12537a |
+}
|
|
|
12537a |
+
|
|
|
12537a |
// -=- Modifiable generic pixel buffer class
|
|
|
12537a |
|
|
|
12537a |
ModifiablePixelBuffer::ModifiablePixelBuffer(const PixelFormat& pf,
|
|
|
12537a |
@@ -124,7 +136,7 @@ void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix)
|
|
|
12537a |
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
- r.width(), r.height(), r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.width(), r.height(), r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
w = r.width();
|
|
|
12537a |
h = r.height();
|
|
|
12537a |
@@ -175,7 +187,7 @@ void ModifiablePixelBuffer::imageRect(const Rect& r,
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
r.width(), r.height(),
|
|
|
12537a |
- r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
bytesPerPixel = getPF().bpp/8;
|
|
|
12537a |
|
|
|
12537a |
@@ -213,13 +225,13 @@ void ModifiablePixelBuffer::copyRect(const Rect &rect,
|
|
|
12537a |
if (!drect.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
drect.width(), drect.height(),
|
|
|
12537a |
- drect.tl.x, drect.tl.y, width_, height_);
|
|
|
12537a |
+ drect.tl.x, drect.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
srect = drect.translate(move_by_delta.negate());
|
|
|
12537a |
if (!srect.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
srect.width(), srect.height(),
|
|
|
12537a |
- srect.tl.x, srect.tl.y, width_, height_);
|
|
|
12537a |
+ srect.tl.x, srect.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
srcData = getBuffer(srect, &srcStride);
|
|
|
12537a |
dstData = getBufferRW(drect, &dstStride);
|
|
|
12537a |
@@ -272,7 +284,7 @@ void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest,
|
|
|
12537a |
if (!dest.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
dest.width(), dest.height(),
|
|
|
12537a |
- dest.tl.x, dest.tl.y, width_, height_);
|
|
|
12537a |
+ dest.tl.x, dest.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
if (stride == 0)
|
|
|
12537a |
stride = dest.width();
|
|
|
12537a |
@@ -301,7 +313,7 @@ rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_)
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
r.width(), r.height(),
|
|
|
12537a |
- r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
*stride_ = stride;
|
|
|
12537a |
return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8];
|
|
|
12537a |
@@ -316,55 +328,69 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons
|
|
|
12537a |
if (!r.enclosed_by(getRect()))
|
|
|
12537a |
throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d",
|
|
|
12537a |
r.width(), r.height(),
|
|
|
12537a |
- r.tl.x, r.tl.y, width_, height_);
|
|
|
12537a |
+ r.tl.x, r.tl.y, width(), height());
|
|
|
12537a |
|
|
|
12537a |
*stride_ = stride;
|
|
|
12537a |
return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8];
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
+void FullFramePixelBuffer::setBuffer(int width, int height,
|
|
|
12537a |
+ rdr::U8* data_, int stride_)
|
|
|
12537a |
+{
|
|
|
12537a |
+ ModifiablePixelBuffer::setSize(width, height);
|
|
|
12537a |
+ stride = stride_;
|
|
|
12537a |
+ data = data_;
|
|
|
12537a |
+}
|
|
|
12537a |
+
|
|
|
12537a |
+void FullFramePixelBuffer::setSize(int w, int h)
|
|
|
12537a |
+{
|
|
|
12537a |
+ // setBuffer() should be used
|
|
|
12537a |
+ throw rfb::Exception("Invalid call to FullFramePixelBuffer::setSize()");
|
|
|
12537a |
+}
|
|
|
12537a |
+
|
|
|
12537a |
// -=- Managed pixel buffer class
|
|
|
12537a |
// Automatically allocates enough space for the specified format & area
|
|
|
12537a |
|
|
|
12537a |
ManagedPixelBuffer::ManagedPixelBuffer()
|
|
|
12537a |
- : datasize(0)
|
|
|
12537a |
+ : data_(NULL), datasize(0)
|
|
|
12537a |
{
|
|
|
12537a |
- checkDataSize();
|
|
|
12537a |
};
|
|
|
12537a |
|
|
|
12537a |
ManagedPixelBuffer::ManagedPixelBuffer(const PixelFormat& pf, int w, int h)
|
|
|
12537a |
- : FullFramePixelBuffer(pf, w, h, NULL, w), datasize(0)
|
|
|
12537a |
+ : FullFramePixelBuffer(pf, 0, 0, NULL, 0), data_(NULL), datasize(0)
|
|
|
12537a |
{
|
|
|
12537a |
- checkDataSize();
|
|
|
12537a |
-};
|
|
|
12537a |
+ setSize(w, h);
|
|
|
12537a |
+}
|
|
|
12537a |
|
|
|
12537a |
-ManagedPixelBuffer::~ManagedPixelBuffer() {
|
|
|
12537a |
- if (data) delete [] data;
|
|
|
12537a |
-};
|
|
|
12537a |
+ManagedPixelBuffer::~ManagedPixelBuffer()
|
|
|
12537a |
+{
|
|
|
12537a |
+ if (data_)
|
|
|
12537a |
+ delete [] data_;
|
|
|
12537a |
+}
|
|
|
12537a |
|
|
|
12537a |
+void ManagedPixelBuffer::setPF(const PixelFormat &pf)
|
|
|
12537a |
+{
|
|
|
12537a |
+ format = pf;
|
|
|
12537a |
+ setSize(width(), height());
|
|
|
12537a |
+}
|
|
|
12537a |
|
|
|
12537a |
-void
|
|
|
12537a |
-ManagedPixelBuffer::setPF(const PixelFormat &pf) {
|
|
|
12537a |
- format = pf; checkDataSize();
|
|
|
12537a |
-};
|
|
|
12537a |
-void
|
|
|
12537a |
-ManagedPixelBuffer::setSize(int w, int h) {
|
|
|
12537a |
- width_ = w; height_ = h; stride = w; checkDataSize();
|
|
|
12537a |
-};
|
|
|
12537a |
+void ManagedPixelBuffer::setSize(int w, int h)
|
|
|
12537a |
+{
|
|
|
12537a |
+ unsigned long new_datasize = w * h * (format.bpp/8);
|
|
|
12537a |
|
|
|
12537a |
+ new_datasize = w * h * (format.bpp/8);
|
|
|
12537a |
|
|
|
12537a |
-inline void
|
|
|
12537a |
-ManagedPixelBuffer::checkDataSize() {
|
|
|
12537a |
- unsigned long new_datasize = width_ * height_ * (format.bpp/8);
|
|
|
12537a |
if (datasize < new_datasize) {
|
|
|
12537a |
- if (data) {
|
|
|
12537a |
- delete [] data;
|
|
|
12537a |
- datasize = 0; data = 0;
|
|
|
12537a |
+ if (data_) {
|
|
|
12537a |
+ delete [] data_;
|
|
|
12537a |
+ data_ = NULL;
|
|
|
12537a |
+ datasize = 0;
|
|
|
12537a |
}
|
|
|
12537a |
if (new_datasize) {
|
|
|
12537a |
- data = new U8[new_datasize];
|
|
|
12537a |
- if (!data)
|
|
|
12537a |
- throw Exception("rfb::ManagedPixelBuffer unable to allocate buffer");
|
|
|
12537a |
+ data_ = new U8[new_datasize];
|
|
|
12537a |
datasize = new_datasize;
|
|
|
12537a |
}
|
|
|
12537a |
}
|
|
|
12537a |
-};
|
|
|
12537a |
+
|
|
|
12537a |
+ setBuffer(w, h, data_, w);
|
|
|
12537a |
+}
|
|
|
12537a |
diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h
|
|
|
12537a |
index 75caa63..518c692 100644
|
|
|
12537a |
--- a/common/rfb/PixelBuffer.h
|
|
|
12537a |
+++ b/common/rfb/PixelBuffer.h
|
|
|
12537a |
@@ -89,7 +89,12 @@ namespace rfb {
|
|
|
12537a |
|
|
|
12537a |
protected:
|
|
|
12537a |
PixelBuffer();
|
|
|
12537a |
+ virtual void setSize(int width, int height);
|
|
|
12537a |
+
|
|
|
12537a |
+ protected:
|
|
|
12537a |
PixelFormat format;
|
|
|
12537a |
+
|
|
|
12537a |
+ private:
|
|
|
12537a |
int width_, height_;
|
|
|
12537a |
};
|
|
|
12537a |
|
|
|
12537a |
@@ -153,7 +158,12 @@ namespace rfb {
|
|
|
12537a |
|
|
|
12537a |
protected:
|
|
|
12537a |
FullFramePixelBuffer();
|
|
|
12537a |
+ virtual void setBuffer(int width, int height, rdr::U8* data, int stride);
|
|
|
12537a |
|
|
|
12537a |
+ private:
|
|
|
12537a |
+ virtual void setSize(int w, int h);
|
|
|
12537a |
+
|
|
|
12537a |
+ private:
|
|
|
12537a |
rdr::U8* data;
|
|
|
12537a |
int stride;
|
|
|
12537a |
};
|
|
|
12537a |
@@ -171,12 +181,9 @@ namespace rfb {
|
|
|
12537a |
virtual void setPF(const PixelFormat &pf);
|
|
|
12537a |
virtual void setSize(int w, int h);
|
|
|
12537a |
|
|
|
12537a |
- // Return the total number of bytes of pixel data in the buffer
|
|
|
12537a |
- int dataLen() const { return width_ * height_ * (format.bpp/8); }
|
|
|
12537a |
-
|
|
|
12537a |
- protected:
|
|
|
12537a |
+ private:
|
|
|
12537a |
+ rdr::U8* data_; // Mirrors FullFramePixelBuffer::data
|
|
|
12537a |
unsigned long datasize;
|
|
|
12537a |
- void checkDataSize();
|
|
|
12537a |
};
|
|
|
12537a |
|
|
|
12537a |
};
|
|
|
12537a |
diff --git a/unix/x0vncserver/XPixelBuffer.cxx b/unix/x0vncserver/XPixelBuffer.cxx
|
|
|
12537a |
index f464182..6f0effe 100644
|
|
|
12537a |
--- a/unix/x0vncserver/XPixelBuffer.cxx
|
|
|
12537a |
+++ b/unix/x0vncserver/XPixelBuffer.cxx
|
|
|
12537a |
@@ -50,13 +50,8 @@ XPixelBuffer::XPixelBuffer(Display *dpy, ImageFactory &factory,
|
|
|
12537a |
ffs(m_image->xim->blue_mask) - 1);
|
|
|
12537a |
|
|
|
12537a |
// Set up the remaining data of the parent class.
|
|
|
12537a |
- width_ = rect.width();
|
|
|
12537a |
- height_ = rect.height();
|
|
|
12537a |
- data = (rdr::U8 *)m_image->xim->data;
|
|
|
12537a |
-
|
|
|
12537a |
- // Calculate the distance in pixels between two subsequent scan
|
|
|
12537a |
- // lines of the framebuffer. This may differ from image width.
|
|
|
12537a |
- stride = m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel;
|
|
|
12537a |
+ setBuffer(rect.width(), rect.height(), (rdr::U8 *)m_image->xim->data,
|
|
|
12537a |
+ m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel);
|
|
|
12537a |
|
|
|
12537a |
// Get initial screen image from the X display.
|
|
|
12537a |
m_image->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop);
|
|
|
12537a |
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
|
|
|
12537a |
index 4836782..7daa69b 100644
|
|
|
12537a |
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
|
|
|
12537a |
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
|
|
|
12537a |
@@ -101,7 +101,7 @@ XserverDesktop::XserverDesktop(int screenIndex_,
|
|
|
12537a |
: screenIndex(screenIndex_),
|
|
|
12537a |
server(0), httpServer(0),
|
|
|
12537a |
listeners(listeners_), httpListeners(httpListeners_),
|
|
|
12537a |
- directFbptr(true),
|
|
|
12537a |
+ shadowFramebuffer(NULL),
|
|
|
12537a |
queryConnectId(0)
|
|
|
12537a |
{
|
|
|
12537a |
format = pf;
|
|
|
12537a |
@@ -138,8 +138,8 @@ XserverDesktop::~XserverDesktop()
|
|
|
12537a |
delete httpListeners.back();
|
|
|
12537a |
httpListeners.pop_back();
|
|
|
12537a |
}
|
|
|
12537a |
- if (!directFbptr)
|
|
|
12537a |
- delete [] data;
|
|
|
12537a |
+ if (shadowFramebuffer)
|
|
|
12537a |
+ delete [] shadowFramebuffer;
|
|
|
12537a |
delete httpServer;
|
|
|
12537a |
delete server;
|
|
|
12537a |
}
|
|
|
12537a |
@@ -158,22 +158,18 @@ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride_)
|
|
|
12537a |
{
|
|
|
12537a |
ScreenSet layout;
|
|
|
12537a |
|
|
|
12537a |
- width_ = w;
|
|
|
12537a |
- height_ = h;
|
|
|
12537a |
-
|
|
|
12537a |
- if (!directFbptr) {
|
|
|
12537a |
- delete [] data;
|
|
|
12537a |
- directFbptr = true;
|
|
|
12537a |
+ if (shadowFramebuffer) {
|
|
|
12537a |
+ delete [] shadowFramebuffer;
|
|
|
12537a |
+ shadowFramebuffer = NULL;
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
if (!fbptr) {
|
|
|
12537a |
- fbptr = new rdr::U8[w * h * (format.bpp/8)];
|
|
|
12537a |
+ shadowFramebuffer = new rdr::U8[w * h * (format.bpp/8)];
|
|
|
12537a |
+ fbptr = shadowFramebuffer;
|
|
|
12537a |
stride_ = w;
|
|
|
12537a |
- directFbptr = false;
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
- data = (rdr::U8*)fbptr;
|
|
|
12537a |
- stride = stride_;
|
|
|
12537a |
+ setBuffer(w, h, (rdr::U8*)fbptr, stride_);
|
|
|
12537a |
|
|
|
12537a |
layout = computeScreenLayout();
|
|
|
12537a |
|
|
|
12537a |
@@ -749,7 +745,7 @@ unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height,
|
|
|
12537a |
|
|
|
12537a |
void XserverDesktop::grabRegion(const rfb::Region& region)
|
|
|
12537a |
{
|
|
|
12537a |
- if (directFbptr)
|
|
|
12537a |
+ if (shadowFramebuffer == NULL)
|
|
|
12537a |
return;
|
|
|
12537a |
|
|
|
12537a |
std::vector<rfb::Rect> rects;
|
|
|
12537a |
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
|
|
|
12537a |
index c766c26..22114a0 100644
|
|
|
12537a |
--- a/unix/xserver/hw/vnc/XserverDesktop.h
|
|
|
12537a |
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
|
|
|
12537a |
@@ -121,7 +121,7 @@ private:
|
|
|
12537a |
rfb::HTTPServer* httpServer;
|
|
|
12537a |
std::list<network::TcpListener*> listeners;
|
|
|
12537a |
std::list<network::TcpListener*> httpListeners;
|
|
|
12537a |
- bool directFbptr;
|
|
|
12537a |
+ rdr::U8* shadowFramebuffer;
|
|
|
12537a |
|
|
|
12537a |
uint32_t queryConnectId;
|
|
|
12537a |
network::Socket* queryConnectSocket;
|
|
|
12537a |
diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
|
|
|
12537a |
index 22e4f72..2b934c5 100644
|
|
|
12537a |
--- a/vncviewer/PlatformPixelBuffer.cxx
|
|
|
12537a |
+++ b/vncviewer/PlatformPixelBuffer.cxx
|
|
|
12537a |
@@ -36,7 +36,7 @@ static rfb::LogWriter vlog("PlatformPixelBuffer");
|
|
|
12537a |
PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
|
|
|
12537a |
FullFramePixelBuffer(rfb::PixelFormat(32, 24, false, true,
|
|
|
12537a |
255, 255, 255, 16, 8, 0),
|
|
|
12537a |
- width, height, 0, stride),
|
|
|
12537a |
+ 0, 0, NULL, 0),
|
|
|
12537a |
Surface(width, height)
|
|
|
12537a |
#if !defined(WIN32) && !defined(__APPLE__)
|
|
|
12537a |
, shminfo(NULL), xim(NULL)
|
|
|
12537a |
@@ -65,11 +65,10 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
|
|
|
12537a |
vlog.debug("Using standard XImage");
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
- data = (rdr::U8*)xim->data;
|
|
|
12537a |
- stride = xim->bytes_per_line / (getPF().bpp/8);
|
|
|
12537a |
+ setBuffer(width, height, (rdr::U8*)xim->data,
|
|
|
12537a |
+ xim->bytes_per_line / (getPF().bpp/8));
|
|
|
12537a |
#else
|
|
|
12537a |
- FullFramePixelBuffer::data = (rdr::U8*)Surface::data;
|
|
|
12537a |
- stride = width;
|
|
|
12537a |
+ setBuffer(width, height, (rdr::U8*)Surface::data, width);
|
|
|
12537a |
#endif
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
diff --git a/win/rfb_win32/DIBSectionBuffer.cxx b/win/rfb_win32/DIBSectionBuffer.cxx
|
|
|
12537a |
index e2b0d64..e00cf23 100644
|
|
|
12537a |
--- a/win/rfb_win32/DIBSectionBuffer.cxx
|
|
|
12537a |
+++ b/win/rfb_win32/DIBSectionBuffer.cxx
|
|
|
12537a |
@@ -52,39 +52,28 @@ void DIBSectionBuffer::setPF(const PixelFormat& pf) {
|
|
|
12537a |
if (!pf.trueColour)
|
|
|
12537a |
throw rfb::Exception("palette format not supported");
|
|
|
12537a |
format = pf;
|
|
|
12537a |
- recreateBuffer();
|
|
|
12537a |
+ setSize(width(), height());
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
-void DIBSectionBuffer::setSize(int w, int h) {
|
|
|
12537a |
- if (width_ == w && height_ == h) {
|
|
|
12537a |
- vlog.debug("size unchanged by setSize()");
|
|
|
12537a |
- return;
|
|
|
12537a |
- }
|
|
|
12537a |
- width_ = w;
|
|
|
12537a |
- height_ = h;
|
|
|
12537a |
- recreateBuffer();
|
|
|
12537a |
-}
|
|
|
12537a |
-
|
|
|
12537a |
-
|
|
|
12537a |
inline void initMaxAndShift(DWORD mask, int* max, int* shift) {
|
|
|
12537a |
for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1;
|
|
|
12537a |
(*max) = (rdr::U16)mask;
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
-void DIBSectionBuffer::recreateBuffer() {
|
|
|
12537a |
+void DIBSectionBuffer::setSize(int w, int h) {
|
|
|
12537a |
HBITMAP new_bitmap = 0;
|
|
|
12537a |
rdr::U8* new_data = 0;
|
|
|
12537a |
|
|
|
12537a |
- if (width_ && height_ && (format.depth != 0)) {
|
|
|
12537a |
+ if (w && h && (format.depth != 0)) {
|
|
|
12537a |
BitmapInfo bi;
|
|
|
12537a |
memset(&bi, 0, sizeof(bi));
|
|
|
12537a |
UINT iUsage = DIB_RGB_COLORS;
|
|
|
12537a |
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
12537a |
bi.bmiHeader.biBitCount = format.bpp;
|
|
|
12537a |
- bi.bmiHeader.biSizeImage = (format.bpp / 8) * width_ * height_;
|
|
|
12537a |
+ bi.bmiHeader.biSizeImage = (format.bpp / 8) * w * h;
|
|
|
12537a |
bi.bmiHeader.biPlanes = 1;
|
|
|
12537a |
- bi.bmiHeader.biWidth = width_;
|
|
|
12537a |
- bi.bmiHeader.biHeight = -height_;
|
|
|
12537a |
+ bi.bmiHeader.biWidth = w;
|
|
|
12537a |
+ bi.bmiHeader.biHeight = -h;
|
|
|
12537a |
bi.bmiHeader.biCompression = (format.bpp > 8) ? BI_BITFIELDS : BI_RGB;
|
|
|
12537a |
bi.mask.red = format.pixelFromRGB((rdr::U16)~0, 0, 0);
|
|
|
12537a |
bi.mask.green = format.pixelFromRGB(0, (rdr::U16)~0, 0);
|
|
|
12537a |
@@ -115,12 +104,12 @@ void DIBSectionBuffer::recreateBuffer() {
|
|
|
12537a |
if (device) {
|
|
|
12537a |
BitmapDC src_dev(device, bitmap);
|
|
|
12537a |
BitmapDC dest_dev(device, new_bitmap);
|
|
|
12537a |
- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
|
|
|
12537a |
+ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY);
|
|
|
12537a |
} else {
|
|
|
12537a |
WindowDC wndDC(window);
|
|
|
12537a |
BitmapDC src_dev(wndDC, bitmap);
|
|
|
12537a |
BitmapDC dest_dev(wndDC, new_bitmap);
|
|
|
12537a |
- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY);
|
|
|
12537a |
+ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY);
|
|
|
12537a |
}
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
@@ -128,17 +117,17 @@ void DIBSectionBuffer::recreateBuffer() {
|
|
|
12537a |
// Delete the old bitmap
|
|
|
12537a |
DeleteObject(bitmap);
|
|
|
12537a |
bitmap = 0;
|
|
|
12537a |
- data = 0;
|
|
|
12537a |
+ setBuffer(0, 0, NULL, 0);
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
if (new_bitmap) {
|
|
|
12537a |
int bpp, depth;
|
|
|
12537a |
int redMax, greenMax, blueMax;
|
|
|
12537a |
int redShift, greenShift, blueShift;
|
|
|
12537a |
+ int new_stride;
|
|
|
12537a |
|
|
|
12537a |
// Set up the new bitmap
|
|
|
12537a |
bitmap = new_bitmap;
|
|
|
12537a |
- data = new_data;
|
|
|
12537a |
|
|
|
12537a |
// Determine the *actual* DIBSection format
|
|
|
12537a |
DIBSECTION ds;
|
|
|
12537a |
@@ -147,14 +136,16 @@ void DIBSectionBuffer::recreateBuffer() {
|
|
|
12537a |
|
|
|
12537a |
// Correct the "stride" of the DIB
|
|
|
12537a |
// *** This code DWORD aligns each row - is that right???
|
|
|
12537a |
- stride = width_;
|
|
|
12537a |
- int bytesPerRow = stride * format.bpp/8;
|
|
|
12537a |
+ new_stride = w;
|
|
|
12537a |
+ int bytesPerRow = new_stride * format.bpp/8;
|
|
|
12537a |
if (bytesPerRow % 4) {
|
|
|
12537a |
bytesPerRow += 4 - (bytesPerRow % 4);
|
|
|
12537a |
- stride = (bytesPerRow * 8) / format.bpp;
|
|
|
12537a |
- vlog.info("adjusting DIB stride: %d to %d", width_, stride);
|
|
|
12537a |
+ new_stride = (bytesPerRow * 8) / format.bpp;
|
|
|
12537a |
+ vlog.info("adjusting DIB stride: %d to %d", w, new_stride);
|
|
|
12537a |
}
|
|
|
12537a |
|
|
|
12537a |
+ setBuffer(w, h, new_data, new_stride);
|
|
|
12537a |
+
|
|
|
12537a |
// Calculate the PixelFormat for the DIB
|
|
|
12537a |
bpp = depth = ds.dsBm.bmBitsPixel;
|
|
|
12537a |
|