Fix animated cursor resize crash

This commit is contained in:
Lauri Kasanen 2021-06-15 15:39:48 +03:00
parent 9144045718
commit 29e0e2bd2e
6 changed files with 19 additions and 7 deletions

View File

@ -50,7 +50,7 @@ namespace rfb {
int w, int h, int w, int h,
const ScreenSet& layout); const ScreenSet& layout);
virtual void setCursor(int width, int height, const Point& hotspot, 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 setPixelFormat(const PixelFormat& pf);
virtual void setName(const char* name); virtual void setName(const char* name);
virtual void fence(rdr::U32 flags, unsigned len, const char data[]); virtual void fence(rdr::U32 flags, unsigned len, const char data[]);

View File

@ -79,7 +79,7 @@ namespace rfb {
// cursorData argument contains width*height rgba quadruplets with // cursorData argument contains width*height rgba quadruplets with
// non-premultiplied alpha. // non-premultiplied alpha.
virtual void setCursor(int width, int height, const Point& hotspot, 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 // setCursorPos() tells the server the current position of the cursor, and
// whether the server initiated that change (e.g. through another X11 // whether the server initiated that change (e.g. through another X11

View File

@ -579,7 +579,7 @@ void VNCServerST::add_copied(const Region& dest, const Point& delta)
} }
void VNCServerST::setCursor(int width, int height, const Point& newHotspot, void VNCServerST::setCursor(int width, int height, const Point& newHotspot,
const rdr::U8* data) const rdr::U8* data, const bool resizing)
{ {
delete cursor; delete cursor;
cursor = new Cursor(width, height, newHotspot, data); cursor = new Cursor(width, height, newHotspot, data);
@ -587,6 +587,13 @@ void VNCServerST::setCursor(int width, int height, const Point& newHotspot,
renderedCursorInvalid = true; 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<VNCSConnectionST*>::iterator ci, ci_next; std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) { for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++; ci_next = ci; ci_next++;

View File

@ -102,7 +102,7 @@ namespace rfb {
virtual void add_changed(const Region &region); virtual void add_changed(const Region &region);
virtual void add_copied(const Region &dest, const Point &delta); virtual void add_copied(const Region &dest, const Point &delta);
virtual void setCursor(int width, int height, const Point& hotspot, 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 setCursorPos(const Point& p, bool warped);
virtual void setLEDState(unsigned state); virtual void setLEDState(unsigned state);

View File

@ -74,7 +74,7 @@ XserverDesktop::XserverDesktop(int screenIndex_,
: screenIndex(screenIndex_), : screenIndex(screenIndex_),
server(0), listeners(listeners_), server(0), listeners(listeners_),
directFbptr(true), directFbptr(true),
queryConnectId(0), queryConnectTimer(this) queryConnectId(0), queryConnectTimer(this), resizing(false)
{ {
format = pf; format = pf;
@ -251,7 +251,7 @@ void XserverDesktop::setCursor(int width, int height, int hotX, int hotY,
} }
try { try {
server->setCursor(width, height, Point(hotX, hotY), cursorData); server->setCursor(width, height, Point(hotX, hotY), cursorData, resizing);
} catch (rdr::Exception& e) { } catch (rdr::Exception& e) {
vlog.error("XserverDesktop::setCursor: %s",e.str()); 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)); layout.print(buffer, sizeof(buffer));
vlog.debug("%s", buffer); vlog.debug("%s", buffer);
resizing = true;
vncSetGlueContext(screenIndex); 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() void XserverDesktop::handleClipboardRequest()

View File

@ -132,5 +132,7 @@ private:
OutputIdMap outputIdMap; OutputIdMap outputIdMap;
rfb::Point oldCursorPos; rfb::Point oldCursorPos;
bool resizing;
}; };
#endif #endif