summaryrefslogtreecommitdiffstats
path: root/vncviewer
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2014-07-09 16:44:11 +0200
committerPierre Ossman <ossman@cendio.se>2014-07-14 16:03:41 +0200
commit0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8 (patch)
tree500f61ee230d30fa1f8e955214c698e86b69e2f4 /vncviewer
parent126e56420e47d72cc950d03976ee57d1efda436e (diff)
downloadtigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.tar.gz
tigervnc-0c9bd4b0ba28f5aab8b1f3e2eb8d83e01915e2b8.zip
Use PixelBuffer objects as the interface for encoders and decoders
This avoid a lot of unnecessary middle men. This also pushes the responsibility for pixel format conversion into the encoders and decoders. The new bufferFromBuffer() is used for direct conversion, rather than PixelTransformer/TransImageGetter.
Diffstat (limited to 'vncviewer')
-rw-r--r--vncviewer/CConn.cxx27
-rw-r--r--vncviewer/CConn.h10
-rw-r--r--vncviewer/DesktopWindow.cxx27
-rw-r--r--vncviewer/DesktopWindow.h16
-rw-r--r--vncviewer/PlatformPixelBuffer.cxx16
-rw-r--r--vncviewer/PlatformPixelBuffer.h6
-rw-r--r--vncviewer/Viewport.cxx114
-rw-r--r--vncviewer/Viewport.h24
8 files changed, 46 insertions, 194 deletions
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index c78bb891..305eddce 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -263,7 +263,6 @@ void CConn::serverInit()
// This initial update request is a bit of a corner case, so we need
// to help out setting the correct format here.
assert(pendingPFChange);
- desktop->setServerPF(pendingPF);
cp.setPF(pendingPF);
pendingPFChange = false;
}
@@ -330,7 +329,6 @@ void CConn::framebufferUpdateEnd()
// A format change has been scheduled and we are now past the update
// with the old format. Time to active the new one.
if (pendingPFChange) {
- desktop->setServerPF(pendingPF);
cp.setPF(pendingPF);
pendingPFChange = false;
}
@@ -405,26 +403,11 @@ void CConn::dataRect(const Rect& r, int encoding)
throw Exception("Unknown rect encoding");
}
}
- decoders[encoding]->readRect(r, this);
+ decoders[encoding]->readRect(r, desktop->getFramebuffer());
sock->inStream().stopTiming();
}
-void CConn::fillRect(const rfb::Rect& r, rfb::Pixel p)
-{
- desktop->fillRect(r,p);
-}
-
-void CConn::imageRect(const rfb::Rect& r, void* p)
-{
- desktop->imageRect(r,p);
-}
-
-void CConn::copyRect(const rfb::Rect& r, int sx, int sy)
-{
- desktop->copyRect(r,sx,sy);
-}
-
void CConn::setCursor(int width, int height, const Point& hotspot,
void* data, void* mask)
{
@@ -461,18 +444,10 @@ void CConn::fence(rdr::U32 flags, unsigned len, const char data[])
pf.read(&memStream);
- desktop->setServerPF(pf);
cp.setPF(pf);
}
}
-rdr::U8* CConn::getRawBufferRW(const rfb::Rect& r, int* stride) {
- return desktop->getBufferRW(r, stride);
-}
-void CConn::releaseRawBuffer(const rfb::Rect& r) {
- desktop->commitBufferRW(r);
-}
-
////////////////////// Internal methods //////////////////////
diff --git a/vncviewer/CConn.h b/vncviewer/CConn.h
index f7f560bc..709ca2f8 100644
--- a/vncviewer/CConn.h
+++ b/vncviewer/CConn.h
@@ -64,18 +64,8 @@ public:
void framebufferUpdateStart();
void framebufferUpdateEnd();
-
void dataRect(const rfb::Rect& r, int encoding);
- void fillRect(const rfb::Rect& r, rfb::Pixel p);
- void imageRect(const rfb::Rect& r, void* p);
- void copyRect(const rfb::Rect& r, int sx, int sy);
-
- rdr::U8* getRawBufferRW(const rfb::Rect& r, int* stride);
- void releaseRawBuffer(const rfb::Rect& r);
-
- const rfb::PixelFormat &getPreferredPF() { return fullColourPF; }
-
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index a64f02a2..d57d57ad 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -193,12 +193,6 @@ DesktopWindow::~DesktopWindow()
}
-void DesktopWindow::setServerPF(const rfb::PixelFormat& pf)
-{
- viewport->setServerPF(pf);
-}
-
-
const rfb::PixelFormat &DesktopWindow::getPreferredPF()
{
return viewport->getPreferredPF();
@@ -216,24 +210,9 @@ void DesktopWindow::setName(const char *name)
}
-void DesktopWindow::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
- viewport->fillRect(r, pix);
-}
-
-void DesktopWindow::imageRect(const rfb::Rect& r, void* pixels) {
- viewport->imageRect(r, pixels);
-}
-
-void DesktopWindow::copyRect(const rfb::Rect& r, int srcX, int srcY) {
- viewport->copyRect(r, srcX, srcY);
-}
-
-rdr::U8* DesktopWindow::getBufferRW(const rfb::Rect& r, int* stride) {
- return viewport->getBufferRW(r, stride);
-}
-
-void DesktopWindow::commitBufferRW(const rfb::Rect& r) {
- viewport->commitBufferRW(r);
+rfb::ModifiablePixelBuffer* DesktopWindow::getFramebuffer(void)
+{
+ return viewport->getFramebuffer();
}
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index 83a8c767..8b91450f 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -27,6 +27,8 @@
#include <FL/Fl_Window.H>
+namespace rfb { class ModifiablePixelBuffer; }
+
class CConn;
class Viewport;
@@ -39,26 +41,22 @@ public:
const rfb::PixelFormat& serverPF, CConn* cc_);
~DesktopWindow();
- // PixelFormat of incoming write operations
- void setServerPF(const rfb::PixelFormat& pf);
// Most efficient format (from DesktopWindow's point of view)
const rfb::PixelFormat &getPreferredPF();
// Flush updates to screen
void updateWindow();
- // Methods forwarded from CConn
+ // Updated session title
void setName(const char *name);
- void fillRect(const rfb::Rect& r, rfb::Pixel pix);
- void imageRect(const rfb::Rect& r, void* pixels);
- void copyRect(const rfb::Rect& r, int srcX, int srcY);
-
- rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
- void commitBufferRW(const rfb::Rect& r);
+ // Return a pointer to the framebuffer for decoders to write into
+ rfb::ModifiablePixelBuffer* getFramebuffer(void);
+ // Resize the current framebuffer, but retain the contents
void resizeFramebuffer(int new_w, int new_h);
+ // New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
index ced04467..5bd50d2c 100644
--- a/vncviewer/PlatformPixelBuffer.cxx
+++ b/vncviewer/PlatformPixelBuffer.cxx
@@ -24,3 +24,19 @@ PlatformPixelBuffer::PlatformPixelBuffer(const rfb::PixelFormat& pf,
FullFramePixelBuffer(pf, width, height, data, stride)
{
}
+
+void PlatformPixelBuffer::commitBufferRW(const rfb::Rect& r)
+{
+ FullFramePixelBuffer::commitBufferRW(r);
+ damage.assign_union(rfb::Region(r));
+}
+
+rfb::Rect PlatformPixelBuffer::getDamage(void)
+{
+ rfb::Rect r;
+
+ r = damage.get_bounding_rect();
+ damage.clear();
+
+ return r;
+}
diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h
index 03842ac8..21b93be4 100644
--- a/vncviewer/PlatformPixelBuffer.h
+++ b/vncviewer/PlatformPixelBuffer.h
@@ -20,14 +20,20 @@
#define __PLATFORMPIXELBUFFER_H__
#include <rfb/PixelBuffer.h>
+#include <rfb/Region.h>
class PlatformPixelBuffer: public rfb::FullFramePixelBuffer {
public:
PlatformPixelBuffer(const rfb::PixelFormat& pf, int width, int height,
rdr::U8* data, int stride);
+ virtual void commitBufferRW(const rfb::Rect& r);
+
virtual void draw(int src_x, int src_y, int x, int y, int w, int h) = 0;
+ rfb::Rect getDamage(void);
+protected:
+ rfb::Region damage;
};
#endif
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 70964b76..cd8b1bc3 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -27,7 +27,6 @@
#include <rfb/CMsgWriter.h>
#include <rfb/LogWriter.h>
-#include <rfb/PixelTransformer.h>
// FLTK can pull in the X11 headers on some systems
#ifndef XK_VoidSymbol
@@ -84,7 +83,7 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_RESIZE,
ID_REFRESH, ID_OPTIONS, ID_INFO, ID_ABOUT, ID_DISMISS };
Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
- : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
+ : Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL),
lastPointerPos(0, 0), lastButtonMask(0),
cursor(NULL), menuCtrlKey(false), menuAltKey(false)
{
@@ -101,8 +100,6 @@ Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
frameBuffer = createFramebuffer(w, h);
assert(frameBuffer);
- setServerPF(serverPF);
-
contextMenu = new Fl_Menu_Button(0, 0, 0, 0);
// Setting box type to FL_NO_BOX prevents it from trying to draw the
// button component (which we don't want)
@@ -130,7 +127,6 @@ Viewport::~Viewport()
{
// Unregister all timeouts in case they get a change tro trigger
// again later when this object is already gone.
- Fl::remove_timeout(handleUpdateTimeout, this);
Fl::remove_timeout(handlePointerTimeout, this);
#ifdef HAVE_FLTK_CLIPBOARD
@@ -141,9 +137,6 @@ Viewport::~Viewport()
delete frameBuffer;
- if (pixelTrans)
- delete pixelTrans;
-
if (cursor) {
if (!cursor->alloc_array)
delete [] cursor->array;
@@ -155,40 +148,6 @@ Viewport::~Viewport()
}
-void Viewport::setServerPF(const rfb::PixelFormat& pf)
-{
- if (pixelTrans)
- delete pixelTrans;
- pixelTrans = NULL;
-
- if (pf.equal(getPreferredPF()))
- return;
-
- pixelTrans = new PixelTransformer();
-
- // FIXME: This is an ugly (temporary) hack to get around a corner
- // case during startup. The conversion routines cannot handle
- // non-native source formats, and we can sometimes get that
- // as the initial format. We will switch to a better format
- // before getting any updates, but we need something for now.
- // Our old client used something completely bogus and just
- // hoped nothing would ever go wrong. We try to at least match
- // the pixel size so that we don't get any memory access issues
- // should a stray update appear.
- static rdr::U32 endianTest = 1;
- static bool nativeBigEndian = *(rdr::U8*)(&endianTest) != 1;
- if ((pf.bpp > 8) && (pf.bigEndian != nativeBigEndian)) {
- PixelFormat fake_pf(pf.bpp, pf.depth, nativeBigEndian, pf.trueColour,
- pf.redMax, pf.greenMax, pf.blueMax,
- pf.redShift, pf.greenShift, pf.blueShift);
- pixelTrans->init(fake_pf, getPreferredPF());
- return;
- }
-
- pixelTrans->init(pf, getPreferredPF());
-}
-
-
const rfb::PixelFormat &Viewport::getPreferredPF()
{
return frameBuffer->getPF();
@@ -197,65 +156,21 @@ const rfb::PixelFormat &Viewport::getPreferredPF()
// Copy the areas of the framebuffer that have been changed (damaged)
// to the displayed window.
+// FIXME: Make sure this gets called on slow updates
void Viewport::updateWindow()
{
Rect r;
- Fl::remove_timeout(handleUpdateTimeout, this);
-
- r = damage.get_bounding_rect();
- Fl_Widget::damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
-
- damage.clear();
-}
-
-void Viewport::fillRect(const rfb::Rect& r, rfb::Pixel pix) {
- if (pixelTrans) {
- rfb::Pixel pix2;
- pixelTrans->translatePixels(&pix, &pix2, 1);
- pix = pix2;
- }
-
- frameBuffer->fillRect(r, pix);
- damageRect(r);
+ r = frameBuffer->getDamage();
+ damage(FL_DAMAGE_USER1, r.tl.x + x(), r.tl.y + y(), r.width(), r.height());
}
-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()),
- buffer, stride, rfb::Point(0, 0));
- frameBuffer->commitBufferRW(r);
- } else {
- frameBuffer->imageRect(r, pixels);
- }
- damageRect(r);
-}
-
-void Viewport::copyRect(const rfb::Rect& r, int srcX, int srcY) {
- frameBuffer->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY));
- damageRect(r);
-}
-
-rdr::U8* Viewport::getBufferRW(const rfb::Rect& r, int* stride) {
- return frameBuffer->getBufferRW(r, stride);
-}
-
-void Viewport::commitBufferRW(const rfb::Rect& r) {
- frameBuffer->commitBufferRW(r);
- damageRect(r);
+rfb::ModifiablePixelBuffer* Viewport::getFramebuffer(void)
+{
+ return frameBuffer;
}
-void Viewport::damageRect(const rfb::Rect& r) {
- damage.assign_union(rfb::Region(r));
- if (!Fl::has_timeout(handleUpdateTimeout, this))
- Fl::add_timeout(0.500, handleUpdateTimeout, this);
-};
-
#ifdef HAVE_FLTK_CURSOR
static const char * dotcursor_xpm[] = {
"5 5 2 1",
@@ -303,10 +218,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot,
const PixelFormat *pf;
- if (pixelTrans)
- pf = &pixelTrans->getInPF();
- else
- pf = &frameBuffer->getPF();
+ pf = &cc->cp.pf();
i = (U8*)data;
o = buffer;
@@ -530,16 +442,6 @@ PlatformPixelBuffer* Viewport::createFramebuffer(int w, int h)
}
-void Viewport::handleUpdateTimeout(void *data)
-{
- Viewport *self = (Viewport *)data;
-
- assert(self);
-
- self->updateWindow();
-}
-
-
void Viewport::handleClipboardChange(int source, void *data)
{
Viewport *self = (Viewport *)data;
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index e112efda..0523cd14 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -22,10 +22,9 @@
#include <map>
-#include <FL/Fl_Widget.H>
+namespace rfb { class ModifiablePixelBuffer; }
-#include <rfb/Region.h>
-#include <rfb/Pixel.h>
+#include <FL/Fl_Widget.H>
class Fl_Menu_Button;
class Fl_RGB_Image;
@@ -41,23 +40,16 @@ public:
Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_);
~Viewport();
- // PixelFormat of incoming write operations
- void setServerPF(const rfb::PixelFormat& pf);
// Most efficient format (from Viewport's point of view)
const rfb::PixelFormat &getPreferredPF();
// Flush updates to screen
void updateWindow();
- // Methods forwarded from CConn
-
- void fillRect(const rfb::Rect& r, rfb::Pixel pix);
- void imageRect(const rfb::Rect& r, void* pixels);
- void copyRect(const rfb::Rect& r, int srcX, int srcY);
-
- rdr::U8* getBufferRW(const rfb::Rect& r, int* stride);
- void commitBufferRW(const rfb::Rect& r);
+ // Return a pointer to the framebuffer for decoders to write into
+ rfb::ModifiablePixelBuffer* getFramebuffer(void);
+ // New image for the locally rendered cursor
void setCursor(int width, int height, const rfb::Point& hotspot,
void* data, void* mask);
@@ -71,12 +63,8 @@ public:
private:
- void damageRect(const rfb::Rect& r);
-
PlatformPixelBuffer* createFramebuffer(int w, int h);
- static void handleUpdateTimeout(void *data);
-
static void handleClipboardChange(int source, void *data);
void handlePointerEvent(const rfb::Point& pos, int buttonMask);
@@ -96,8 +84,6 @@ private:
CConn* cc;
PlatformPixelBuffer* frameBuffer;
- rfb::PixelTransformer *pixelTrans;
- rfb::Region damage;
rfb::Point lastPointerPos;
int lastButtonMask;