diff --git a/common/rfb/CMsgHandler.h b/common/rfb/CMsgHandler.h index 8e640f4..dc1d072 100644 --- a/common/rfb/CMsgHandler.h +++ b/common/rfb/CMsgHandler.h @@ -50,7 +50,7 @@ namespace rfb { int w, int h, const ScreenSet& layout); virtual void setCursor(int width, int height, const Point& hotspot, - const rdr::U8* data) = 0; + const rdr::U8* data, const bool resizing = false) = 0; virtual void setPixelFormat(const PixelFormat& pf); virtual void setName(const char* name); virtual void fence(rdr::U32 flags, unsigned len, const char data[]); diff --git a/common/rfb/VNCServer.h b/common/rfb/VNCServer.h index d2e0fa2..54e3504 100644 --- a/common/rfb/VNCServer.h +++ b/common/rfb/VNCServer.h @@ -79,7 +79,7 @@ namespace rfb { // cursorData argument contains width*height rgba quadruplets with // non-premultiplied alpha. virtual void setCursor(int width, int height, const Point& hotspot, - const rdr::U8* cursorData) = 0; + const rdr::U8* cursorData, const bool resizing = false) = 0; // setCursorPos() tells the server the current position of the cursor, and // whether the server initiated that change (e.g. through another X11 diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 96f970d..44f1a25 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -579,7 +579,7 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta) } void VNCServerST::setCursor(int width, int height, const Point& newHotspot, - const rdr::U8* data) + const rdr::U8* data, const bool resizing) { delete cursor; cursor = new Cursor(width, height, newHotspot, data); @@ -587,6 +587,13 @@ void VNCServerST::setCursor(int width, int height, const Point& newHotspot, renderedCursorInvalid = true; + // If an app has an animated cursor on the resized edge, X internals + // will call for it to be rendered. Unlucky for us, the VNC screen + // is currently pointing to freed memory, and a cursor change + // would want to send a screen update. So, don't do that. + if (resizing) + return; + std::list::iterator ci, ci_next; for (ci = clients.begin(); ci != clients.end(); ci = ci_next) { ci_next = ci; ci_next++; diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 285c4fd..97d43f7 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -102,7 +102,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, - const rdr::U8* data); + const rdr::U8* data, const bool resizing = false); virtual void setCursorPos(const Point& p, bool warped); virtual void setLEDState(unsigned state); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 872b2ec..1e9d663 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -74,7 +74,7 @@ XserverDesktop::XserverDesktop(int screenIndex_, : screenIndex(screenIndex_), server(0), listeners(listeners_), directFbptr(true), - queryConnectId(0), queryConnectTimer(this) + queryConnectId(0), queryConnectTimer(this), resizing(false) { format = pf; @@ -251,7 +251,7 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY, } try { - server->setCursor(width, height, Point(hotX, hotY), cursorData); + server->setCursor(width, height, Point(hotX, hotY), cursorData, resizing); } catch (rdr::Exception& e) { vlog.error("XserverDesktop::setCursor: %s",e.str()); } @@ -462,8 +462,11 @@ unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, layout.print(buffer, sizeof(buffer)); vlog.debug("%s", buffer); + resizing = true; vncSetGlueContext(screenIndex); - return ::setScreenLayout(fb_width, fb_height, layout, &outputIdMap); + const unsigned int ret = ::setScreenLayout(fb_width, fb_height, layout, &outputIdMap); + resizing = false; + return ret; } void XserverDesktop::handleClipboardRequest() diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index e35f015..014a48e 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -132,5 +132,7 @@ private: OutputIdMap outputIdMap; rfb::Point oldCursorPos; + + bool resizing; }; #endif