Require all SMsgWriter caller to check capabilities

Make the API consisitent by requiring the caller to check what the client
supports before calling any of the write* functions. This avoids the
confusion that the functions might not always do anything.
diff --git a/common/rfb/SMsgWriter.cxx b/common/rfb/SMsgWriter.cxx
index dacba8a..a12a6d4 100644
--- a/common/rfb/SMsgWriter.cxx
+++ b/common/rfb/SMsgWriter.cxx
@@ -132,13 +132,12 @@
   extendedDesktopSizeMsgs.push_back(msg);
 }
 
-bool SMsgWriter::writeSetDesktopName() {
+void SMsgWriter::writeSetDesktopName()
+{
   if (!client->supportsEncoding(pseudoEncodingDesktopName))
-    return false;
+    throw Exception("Client does not support desktop name changes");
 
   needSetDesktopName = true;
-
-  return true;
 }
 
 void SMsgWriter::writeCursor()
@@ -151,26 +150,22 @@
   needCursor = true;
 }
 
-bool SMsgWriter::writeLEDState()
+void SMsgWriter::writeLEDState()
 {
   if (!client->supportsEncoding(pseudoEncodingLEDState))
-    return false;
+    throw Exception("Client does not support LED state");
   if (client->ledState() == ledUnknown)
-    return false;
+    throw Exception("Server has not specified LED state");
 
   needLEDState = true;
-
-  return true;
 }
 
-bool SMsgWriter::writeQEMUKeyEvent()
+void SMsgWriter::writeQEMUKeyEvent()
 {
   if (!client->supportsEncoding(pseudoEncodingQEMUKeyEvent))
-    return false;
+    throw Exception("Client does not support QEMU key events");
 
   needQEMUKeyEvent = true;
-
-  return true;
 }
 
 bool SMsgWriter::needFakeUpdate()
diff --git a/common/rfb/SMsgWriter.h b/common/rfb/SMsgWriter.h
index 19b013f..80f6de9 100644
--- a/common/rfb/SMsgWriter.h
+++ b/common/rfb/SMsgWriter.h
@@ -69,17 +69,17 @@
     // write the relevant pseudo-rectangle as part of the next update.
     void writeDesktopSize(rdr::U16 reason, rdr::U16 result=0);
 
-    bool writeSetDesktopName();
+    void writeSetDesktopName();
 
     // Like setDesktopSize, we can't just write out a cursor message
     // immediately. 
     void writeCursor();
 
     // Same for LED state message
-    bool writeLEDState();
+    void writeLEDState();
 
     // And QEMU keyboard event handshake
-    bool writeQEMUKeyEvent();
+    void writeQEMUKeyEvent();
 
     // needFakeUpdate() returns true when an immediate update is needed in
     // order to flush out pseudo-rectangles to the client.
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index d936573..a58fd09 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -829,6 +829,9 @@
 
 void VNCSConnectionST::supportsLEDState()
 {
+  if (client.ledState() == ledUnknown)
+    return;
+
   writer()->writeLEDState();
 }
 
@@ -1157,10 +1160,8 @@
   if (state() != RFBSTATE_NORMAL)
     return;
 
-  if (!writer()->writeSetDesktopName()) {
-    fprintf(stderr, "Client does not support desktop rename\n");
-    return;
-  }
+  if (client.supportsEncoding(pseudoEncodingDesktopName))
+    writer()->writeSetDesktopName();
 }
 
 void VNCSConnectionST::setLEDState(unsigned int ledstate)
@@ -1170,7 +1171,8 @@
 
   client.setLEDState(ledstate);
 
-  writer()->writeLEDState();
+  if (client.supportsLEDState())
+    writer()->writeLEDState();
 }
 
 void VNCSConnectionST::setSocketTimeouts()