From 6ea6e1aebcd29cd8b950179f0df52768d5ddbdaf Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 12 Feb 2014 16:33:43 +0100 Subject: [PATCH] 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. --- common/rfb/Cursor.cxx | 52 +++++++++++++++++++++++++++++++++ common/rfb/Cursor.h | 16 ++++++++++ common/rfb/VNCSConnectionST.cxx | 8 ++--- common/rfb/VNCServerST.cxx | 19 ++---------- common/rfb/VNCServerST.h | 4 +-- 5 files changed, 74 insertions(+), 25 deletions(-) diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx index 2d077c98..62b767fa 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 #include #include #include +#include using namespace rfb; @@ -174,3 +177,52 @@ void Cursor::crop() 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 7d94d705..5d4623d6 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 @@ namespace rfb { 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 fcb678ad..f8674dea 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -1050,8 +1050,8 @@ void VNCSConnectionST::writeFramebufferUpdate() 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 @@ void VNCSConnectionST::writeFramebufferUpdate() 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 f1e378ed..27eb605a 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -294,7 +294,7 @@ void VNCServerST::setPixelBuffer(PixelBuffer* pb_, const ScreenSet& layout) 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 @@ bool VNCServerST::checkUpdate() 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 @@ bool VNCServerST::checkUpdate() 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 ed7833ab..ede52236 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -224,9 +224,7 @@ namespace rfb { 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. -- 2.39.5