]> source.dussan.org Git - tigervnc.git/commitdiff
Abstract sending cursor and resizing the desktop
authorPierre Ossman <ossman@cendio.se>
Mon, 29 Oct 2018 09:03:37 +0000 (10:03 +0100)
committerPierre Ossman <ossman@cendio.se>
Mon, 10 Dec 2018 19:19:41 +0000 (20:19 +0100)
Avoid having the callers need to know about the different variants
of these functions and instead have the writer pick the most appropriate
extension.

common/rfb/ClientParams.cxx
common/rfb/ClientParams.h
common/rfb/SMsgWriter.cxx
common/rfb/SMsgWriter.h
common/rfb/VNCSConnectionST.cxx

index 78384073863ef58bbf3e726547290d3c9de3b6bd..2f8783bbd0b0390f58ab47417027fe263ec5e40c 100644 (file)
@@ -147,6 +147,15 @@ bool ClientParams::supportsLocalCursor() const
   return false;
 }
 
+bool ClientParams::supportsDesktopSize() const
+{
+  if (supportsEncoding(pseudoEncodingExtendedDesktopSize))
+    return true;
+  if (supportsEncoding(pseudoEncodingDesktopSize))
+    return true;
+  return false;
+}
+
 bool ClientParams::supportsLEDState() const
 {
   if (supportsEncoding(pseudoEncodingLEDState))
index 63d4e19208254037c37aa442c0ee38b5bba344f3..f7a7044b4f56b26d7abc0704f86336a852f89c33 100644 (file)
@@ -87,6 +87,7 @@ namespace rfb {
     // Wrappers to check for functionality rather than specific
     // encodings
     bool supportsLocalCursor() const;
+    bool supportsDesktopSize() const;
     bool supportsLEDState() const;
     bool supportsFence() const;
     bool supportsContinuousUpdates() const;
index 0ca198123a8883e83ee974ffc062bde5f26832d4..dacba8a5710a1273a91a022072d49e6c27e37d99 100644 (file)
@@ -36,9 +36,7 @@ static LogWriter vlog("SMsgWriter");
 SMsgWriter::SMsgWriter(ClientParams* client_, rdr::OutStream* os_)
   : client(client_), os(os_),
     nRectsInUpdate(0), nRectsInHeader(0),
-    needSetDesktopSize(false), needExtendedDesktopSize(false),
-    needSetDesktopName(false), needSetCursor(false),
-    needSetXCursor(false), needSetCursorWithAlpha(false),
+    needSetDesktopName(false), needCursor(false),
     needLEDState(false), needQEMUKeyEvent(false)
 {
 }
@@ -120,36 +118,18 @@ void SMsgWriter::writeEndOfContinuousUpdates()
   endMsg();
 }
 
-bool SMsgWriter::writeSetDesktopSize() {
-  if (!client->supportsEncoding(pseudoEncodingDesktopSize))
-    return false;
-
-  needSetDesktopSize = true;
-
-  return true;
-}
-
-bool SMsgWriter::writeExtendedDesktopSize() {
-  if (!client->supportsEncoding(pseudoEncodingExtendedDesktopSize))
-    return false;
-
-  needExtendedDesktopSize = true;
-
-  return true;
-}
-
-bool SMsgWriter::writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result) {
+void SMsgWriter::writeDesktopSize(rdr::U16 reason, rdr::U16 result)
+{
   ExtendedDesktopSizeMsg msg;
 
-  if (!client->supportsEncoding(pseudoEncodingExtendedDesktopSize))
-    return false;
+  if (!client->supportsEncoding(pseudoEncodingDesktopSize) &&
+      !client->supportsEncoding(pseudoEncodingExtendedDesktopSize))
+    throw Exception("Client does not support desktop size changes");
 
   msg.reason = reason;
   msg.result = result;
 
   extendedDesktopSizeMsgs.push_back(msg);
-
-  return true;
 }
 
 bool SMsgWriter::writeSetDesktopName() {
@@ -161,34 +141,14 @@ bool SMsgWriter::writeSetDesktopName() {
   return true;
 }
 
-bool SMsgWriter::writeSetCursor()
-{
-  if (!client->supportsEncoding(pseudoEncodingCursor))
-    return false;
-
-  needSetCursor = true;
-
-  return true;
-}
-
-bool SMsgWriter::writeSetXCursor()
-{
-  if (!client->supportsEncoding(pseudoEncodingXCursor))
-    return false;
-
-  needSetXCursor = true;
-
-  return true;
-}
-
-bool SMsgWriter::writeSetCursorWithAlpha()
+void SMsgWriter::writeCursor()
 {
-  if (!client->supportsEncoding(pseudoEncodingCursorWithAlpha))
-    return false;
+  if (!client->supportsEncoding(pseudoEncodingCursor) &&
+      !client->supportsEncoding(pseudoEncodingXCursor) &&
+      !client->supportsEncoding(pseudoEncodingCursorWithAlpha))
+    throw Exception("Client does not support local cursor");
 
-  needSetCursorWithAlpha = true;
-
-  return true;
+  needCursor = true;
 }
 
 bool SMsgWriter::writeLEDState()
@@ -217,7 +177,7 @@ bool SMsgWriter::needFakeUpdate()
 {
   if (needSetDesktopName)
     return true;
-  if (needSetCursor || needSetXCursor || needSetCursorWithAlpha)
+  if (needCursor)
     return true;
   if (needLEDState)
     return true;
@@ -231,9 +191,7 @@ bool SMsgWriter::needFakeUpdate()
 
 bool SMsgWriter::needNoDataUpdate()
 {
-  if (needSetDesktopSize)
-    return true;
-  if (needExtendedDesktopSize || !extendedDesktopSizeMsgs.empty())
+  if (!extendedDesktopSizeMsgs.empty())
     return true;
 
   return false;
@@ -245,12 +203,12 @@ void SMsgWriter::writeNoDataUpdate()
 
   nRects = 0;
 
-  if (needSetDesktopSize)
-    nRects++;
-  if (needExtendedDesktopSize)
-    nRects++;
-  if (!extendedDesktopSizeMsgs.empty())
-    nRects += extendedDesktopSizeMsgs.size();
+  if (!extendedDesktopSizeMsgs.empty()) {
+    if (client->supportsEncoding(pseudoEncodingExtendedDesktopSize))
+      nRects += extendedDesktopSizeMsgs.size();
+    else
+      nRects++;
+  }
 
   writeFramebufferUpdateStart(nRects);
   writeNoDataRects();
@@ -265,11 +223,7 @@ void SMsgWriter::writeFramebufferUpdateStart(int nRects)
   if (nRects != 0xFFFF) {
     if (needSetDesktopName)
       nRects++;
-    if (needSetCursor)
-      nRects++;
-    if (needSetXCursor)
-      nRects++;
-    if (needSetCursorWithAlpha)
+    if (needCursor)
       nRects++;
     if (needLEDState)
       nRects++;
@@ -343,47 +297,43 @@ void SMsgWriter::endMsg()
 
 void SMsgWriter::writePseudoRects()
 {
-  if (needSetCursor) {
+  if (needCursor) {
     const Cursor& cursor = client->cursor();
 
-    rdr::U8Array data(cursor.width()*cursor.height() * (client->pf().bpp/8));
-    rdr::U8Array mask(cursor.getMask());
-
-    const rdr::U8* in;
-    rdr::U8* out;
-
-    in = cursor.getBuffer();
-    out = data.buf;
-    for (int i = 0;i < cursor.width()*cursor.height();i++) {
-      client->pf().bufferFromRGB(out, in, 1);
-      in += 4;
-      out += client->pf().bpp/8;
+    if (client->supportsEncoding(pseudoEncodingCursorWithAlpha)) {
+      writeSetCursorWithAlphaRect(cursor.width(), cursor.height(),
+                                  cursor.hotspot().x, cursor.hotspot().y,
+                                  cursor.getBuffer());
+    } else if (client->supportsEncoding(pseudoEncodingCursor)) {
+      rdr::U8Array data(cursor.width()*cursor.height() * (client->pf().bpp/8));
+      rdr::U8Array mask(cursor.getMask());
+
+      const rdr::U8* in;
+      rdr::U8* out;
+
+      in = cursor.getBuffer();
+      out = data.buf;
+      for (int i = 0;i < cursor.width()*cursor.height();i++) {
+        client->pf().bufferFromRGB(out, in, 1);
+        in += 4;
+        out += client->pf().bpp/8;
+      }
+
+      writeSetCursorRect(cursor.width(), cursor.height(),
+                         cursor.hotspot().x, cursor.hotspot().y,
+                         data.buf, mask.buf);
+    } else if (client->supportsEncoding(pseudoEncodingXCursor)) {
+      rdr::U8Array bitmap(cursor.getBitmap());
+      rdr::U8Array mask(cursor.getMask());
+
+      writeSetXCursorRect(cursor.width(), cursor.height(),
+                          cursor.hotspot().x, cursor.hotspot().y,
+                          bitmap.buf, mask.buf);
+    } else {
+      throw Exception("Client does not support local cursor");
     }
 
-    writeSetCursorRect(cursor.width(), cursor.height(),
-                       cursor.hotspot().x, cursor.hotspot().y,
-                       data.buf, mask.buf);
-    needSetCursor = false;
-  }
-
-  if (needSetXCursor) {
-    const Cursor& cursor = client->cursor();
-    rdr::U8Array bitmap(cursor.getBitmap());
-    rdr::U8Array mask(cursor.getMask());
-
-    writeSetXCursorRect(cursor.width(), cursor.height(),
-                        cursor.hotspot().x, cursor.hotspot().y,
-                        bitmap.buf, mask.buf);
-    needSetXCursor = false;
-  }
-
-  if (needSetCursorWithAlpha) {
-    const Cursor& cursor = client->cursor();
-
-    writeSetCursorWithAlphaRect(cursor.width(), cursor.height(),
-                                cursor.hotspot().x, cursor.hotspot().y,
-                                cursor.getBuffer());
-    needSetCursorWithAlpha = false;
+    needCursor = false;
   }
 
   if (needSetDesktopName) {
@@ -404,32 +354,25 @@ void SMsgWriter::writePseudoRects()
 
 void SMsgWriter::writeNoDataRects()
 {
-  // Start with specific ExtendedDesktopSize messages
   if (!extendedDesktopSizeMsgs.empty()) {
-    std::list<ExtendedDesktopSizeMsg>::const_iterator ri;
-
-    for (ri = extendedDesktopSizeMsgs.begin();ri != extendedDesktopSizeMsgs.end();++ri) {
-      writeExtendedDesktopSizeRect(ri->reason, ri->result,
-                                   client->width(), client->height(),
-                                   client->screenLayout());
+    if (client->supportsEncoding(pseudoEncodingExtendedDesktopSize)) {
+      std::list<ExtendedDesktopSizeMsg>::const_iterator ri;
+      for (ri = extendedDesktopSizeMsgs.begin();ri != extendedDesktopSizeMsgs.end();++ri) {
+        // FIXME: We can probably skip multiple reasonServer entries
+        writeExtendedDesktopSizeRect(ri->reason, ri->result,
+                                     client->width(), client->height(),
+                                     client->screenLayout());
+      }
+    } else if (client->supportsEncoding(pseudoEncodingDesktopSize)) {
+      // Some clients assume this is the last rectangle so don't send anything
+      // more after this
+      writeSetDesktopSizeRect(client->width(), client->height());
+    } else {
+      throw Exception("Client does not support desktop size changes");
     }
 
     extendedDesktopSizeMsgs.clear();
   }
-
-  // Send this before SetDesktopSize to make life easier on the clients
-  if (needExtendedDesktopSize) {
-    writeExtendedDesktopSizeRect(0, 0, client->width(), client->height(),
-                                 client->screenLayout());
-    needExtendedDesktopSize = false;
-  }
-
-  // Some clients assume this is the last rectangle so don't send anything
-  // more after this
-  if (needSetDesktopSize) {
-    writeSetDesktopSizeRect(client->width(), client->height());
-    needSetDesktopSize = false;
-  }
 }
 
 void SMsgWriter::writeSetDesktopSizeRect(int width, int height)
index 1fe50434e3b89a535cf5803c43a3dca0fbc18452..19b013f6392d4fa6797aacde2d4cd1bf0d77ae1a 100644 (file)
@@ -65,22 +65,15 @@ namespace rfb {
     // updates mode.
     void writeEndOfContinuousUpdates();
 
-    // writeSetDesktopSize() won't actually write immediately, but will
+    // writeDesktopSize() won't actually write immediately, but will
     // write the relevant pseudo-rectangle as part of the next update.
-    bool writeSetDesktopSize();
-    // Same thing for the extended version. The first version queues up a
-    // generic update of the current server state, but the second queues a
-    // specific message.
-    bool writeExtendedDesktopSize();
-    bool writeExtendedDesktopSize(rdr::U16 reason, rdr::U16 result);
+    void writeDesktopSize(rdr::U16 reason, rdr::U16 result=0);
 
     bool writeSetDesktopName();
 
     // Like setDesktopSize, we can't just write out a cursor message
     // immediately. 
-    bool writeSetCursor();
-    bool writeSetXCursor();
-    bool writeSetCursorWithAlpha();
+    void writeCursor();
 
     // Same for LED state message
     bool writeLEDState();
@@ -146,12 +139,8 @@ namespace rfb {
     int nRectsInUpdate;
     int nRectsInHeader;
 
-    bool needSetDesktopSize;
-    bool needExtendedDesktopSize;
     bool needSetDesktopName;
-    bool needSetCursor;
-    bool needSetXCursor;
-    bool needSetCursorWithAlpha;
+    bool needCursor;
     bool needLEDState;
     bool needQEMUKeyEvent;
 
index e4e5ab3e604686a22fb344d7f74d3966b921c5e5..d936573df388e843d3da1ec5593c2a480f10bc5e 100644 (file)
@@ -216,13 +216,11 @@ void VNCSConnectionST::pixelBufferChange()
       client.setDimensions(server->pb->width(), server->pb->height(),
                            server->screenLayout);
       if (state() == RFBSTATE_NORMAL) {
-        // We should only send EDS to client asking for both
-        if (!writer()->writeExtendedDesktopSize()) {
-          if (!writer()->writeSetDesktopSize()) {
-            close("Client does not support desktop resize");
-            return;
-          }
+        if (!client.supportsDesktopSize()) {
+          close("Client does not support desktop resize");
+          return;
         }
+        writer()->writeDesktopSize(reasonServer);
       }
 
       // Drop any lossy tracking that is now outside the framebuffer
@@ -697,7 +695,8 @@ void VNCSConnectionST::framebufferUpdateRequest(const Rect& r,bool incremental)
 
     // And send the screen layout to the client (which, unlike the
     // framebuffer dimensions, the client doesn't get during init)
-    writer()->writeExtendedDesktopSize();
+    if (client.supportsEncoding(pseudoEncodingExtendedDesktopSize))
+      writer()->writeDesktopSize(reasonServer);
 
     // We do not send a DesktopSize since it only contains the
     // framebuffer size (which the client already should know) and
@@ -716,7 +715,7 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
 
   // Don't bother the desktop with an invalid configuration
   if (!layout.validate(fb_width, fb_height)) {
-    writer()->writeExtendedDesktopSize(reasonClient, resultInvalid);
+    writer()->writeDesktopSize(reasonClient, resultInvalid);
     return;
   }
 
@@ -725,7 +724,7 @@ void VNCSConnectionST::setDesktopSize(int fb_width, int fb_height,
   // protocol-wise, but unnecessary.
   result = server->desktop->setScreenLayout(fb_width, fb_height, layout);
 
-  writer()->writeExtendedDesktopSize(reasonClient, result);
+  writer()->writeDesktopSize(reasonClient, result);
 
   // Only notify other clients on success
   if (result == resultSuccess) {
@@ -1125,7 +1124,7 @@ void VNCSConnectionST::screenLayoutChange(rdr::U16 reason)
   if (state() != RFBSTATE_NORMAL)
     return;
 
-  writer()->writeExtendedDesktopSize(reason, 0);
+  writer()->writeDesktopSize(reason);
 }
 
 
@@ -1147,14 +1146,8 @@ void VNCSConnectionST::setCursor()
     clientHasCursor = true;
   }
 
-  if (!writer()->writeSetCursorWithAlpha()) {
-    if (!writer()->writeSetCursor()) {
-      if (!writer()->writeSetXCursor()) {
-        // No client support
-        return;
-      }
-    }
-  }
+  if (client.supportsLocalCursor())
+    writer()->writeCursor();
 }
 
 void VNCSConnectionST::setDesktopName(const char *name)