Add helper class for a rendered cursor
Add a magical cursor framebuffer class for handling when you
want to render the cursor on the server side. Keeps the cursor
specific magic in one contained place.
diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx
index 2d077c9..62b767f 100644
--- a/common/rfb/Cursor.cxx
+++ b/common/rfb/Cursor.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
@@ -15,9 +16,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
+#include <assert.h>
#include <string.h>
#include <rfb/Cursor.h>
#include <rfb/LogWriter.h>
+#include <rfb/Exception.h>
using namespace rfb;
@@ -174,3 +177,52 @@
data = newData;
mask.buf = newMask;
}
+
+RenderedCursor::RenderedCursor()
+{
+}
+
+const rdr::U8* RenderedCursor::getBuffer(const Rect& _r, int* stride)
+{
+ Rect r;
+
+ r = _r.translate(offset.negate());
+ if (!r.enclosed_by(buffer.getRect()))
+ throw Exception("RenderedCursor: Invalid area requested");
+
+ return buffer.getBuffer(r, stride);
+}
+
+void RenderedCursor::update(PixelBuffer* framebuffer,
+ Cursor* cursor, const Point& pos)
+{
+ Point rawOffset;
+ Rect clippedRect;
+
+ const rdr::U8* data;
+ int stride;
+
+ assert(framebuffer);
+ assert(cursor);
+
+ if (!framebuffer->getPF().equal(cursor->getPF()))
+ throw Exception("RenderedCursor: Trying to render cursor on incompatible frame buffer");
+
+ format = framebuffer->getPF();
+ width_ = framebuffer->width();
+ height_ = framebuffer->height();
+
+ rawOffset = pos.subtract(cursor->hotspot);
+ clippedRect = cursor->getRect(rawOffset).intersect(framebuffer->getRect());
+ offset = clippedRect.tl;
+
+ buffer.setPF(cursor->getPF());
+ buffer.setSize(clippedRect.width(), clippedRect.height());
+
+ data = framebuffer->getBuffer(buffer.getRect(offset), &stride);
+ buffer.imageRect(buffer.getRect(), data, stride);
+
+ data = cursor->getBuffer(cursor->getRect(), &stride);
+ buffer.maskRect(cursor->getRect(rawOffset.subtract(offset)),
+ data, cursor->mask.buf);
+}
diff --git a/common/rfb/Cursor.h b/common/rfb/Cursor.h
index 7d94d70..5d4623d 100644
--- a/common/rfb/Cursor.h
+++ b/common/rfb/Cursor.h
@@ -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
@@ -52,5 +53,20 @@
void crop();
};
+ class RenderedCursor : public PixelBuffer {
+ public:
+ RenderedCursor();
+
+ Rect getEffectiveRect() const { return buffer.getRect(offset); }
+
+ virtual const rdr::U8* getBuffer(const Rect& r, int* stride);
+
+ void update(PixelBuffer* framebuffer, Cursor* cursor, const Point& pos);
+
+ protected:
+ ManagedPixelBuffer buffer;
+ Point offset;
+ };
+
}
#endif
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index fcb678a..f8674de 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -1050,8 +1050,8 @@
if (needRenderedCursor()) {
renderedCursorRect
- = (server->renderedCursor.getRect(server->renderedCursorTL)
- .intersect(req.get_bounding_rect()));
+ = server->renderedCursor.getEffectiveRect()
+ .intersect(req.get_bounding_rect());
if (renderedCursorRect.is_empty()) {
drawRenderedCursor = false;
@@ -1123,12 +1123,8 @@
if (drawRenderedCursor) {
image_getter.setPixelBuffer(&server->renderedCursor);
- image_getter.setOffset(server->renderedCursorTL);
-
encoders[encoding]->writeRect(renderedCursorRect, &image_getter);
-
image_getter.setPixelBuffer(server->pb);
- image_getter.setOffset(Point(0,0));
drawRenderedCursor = false;
}
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index f1e378e..27eb605 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -294,7 +294,7 @@
comparer = new ComparingUpdateTracker(pb);
cursor.setPF(pb->getPF());
- renderedCursor.setPF(pb->getPF());
+ renderedCursorInvalid = true;
// Make sure that we have at least one screen
if (screenLayout.num_screens() == 0)
@@ -598,15 +598,12 @@
if (renderCursor) {
Rect clippedCursorRect
- = cursor.getRect(cursorTL()).intersect(pb->getRect());
+ = cursor.getRect(cursorPos.subtract(cursor.hotspot)).intersect(pb->getRect());
if (!renderedCursorInvalid && (toCheck.intersect(clippedCursorRect)
.is_empty())) {
renderCursor = false;
} else {
- renderedCursorTL = clippedCursorRect.tl;
- renderedCursor.setSize(clippedCursorRect.width(),
- clippedCursorRect.height());
toCheck.assign_union(clippedCursorRect);
}
}
@@ -622,17 +619,7 @@
comparer->getUpdateInfo(&ui, pb->getRect());
if (renderCursor) {
- 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)),
- buffer, cursor.mask.buf);
-
+ renderedCursor.update(pb, &cursor, cursorPos);
renderedCursorInvalid = false;
}
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index ed7833a..ede5223 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -224,9 +224,7 @@
Point cursorPos;
Cursor cursor;
- Point cursorTL() { return cursorPos.subtract(cursor.hotspot); }
- Point renderedCursorTL;
- ManagedPixelBuffer renderedCursor;
+ RenderedCursor renderedCursor;
bool renderedCursorInvalid;
// - Check how many of the clients are authenticated.