For now, I've chosen to have the client send a message immediately after the receipt of the server initialisation message. This is:
#define rfbClientWantsZlibs 10, which is a 2 octet message. The second octet in the message holds the level of zlib compression desired. Values 1 to 9 are legal, other values are illegal, and the server can choose to do anything with these illegal values like ignore them.
If the server supports zlib compression, it immediately returns a message:
#define rfbServerZlibsOn 10, which is just the one octet. Once this single octet message is sent, all further server -> client data is zlib compressed.
The main shortcoming in the new protocol is: if a client asks for zlib compression to a server which doesn't support it, the server closes the connection because it cannot understand client message #10.
z_streamp Zstream; /* Pointer to data structure used for */ /* zlib compression of server output */ Bool useCompression; /* If true, do compression in ZWriteExact */
Bool usingCompression; /* If true, server has turned compression on */and a new AppData field:
int zlibCompression; /* Holds the level of zlib compression */The read() call in ReadFromRFBServer() now calls Zread(), which performs exactly the same task as read(), but uncompresses the server's data stream if required.
On a localhost connection with a zlib level of 9, I get a subjective latency of less than 100ms when compared with no zlib compression. I can't guess the latencies over the 33.6K link; the link's latencies overwhelm the compression's latencies.