Keep zlib streams when switching encodings

Both RealVNC and TigerVNC clients expect zlib streams to remain when
switching encodings, so when they switch back, inflate fails if the
encoder is discared.

fixes #109
v0.7
Andri Yngvason 2024-02-02 22:09:57 +00:00
parent 4148503d0c
commit a77ff634f0
2 changed files with 30 additions and 1 deletions

View File

@ -105,6 +105,8 @@ struct nvnc_client {
struct cut_text cut_text; struct cut_text cut_text;
bool is_ext_notified; bool is_ext_notified;
struct encoder* encoder; struct encoder* encoder;
struct encoder* zrle_encoder;
struct encoder* tight_encoder;
uint32_t cursor_seq; uint32_t cursor_seq;
int quality; int quality;

View File

@ -143,6 +143,8 @@ static void client_close(struct nvnc_client* client)
client->encoder->on_done = NULL; client->encoder->on_done = NULL;
} }
encoder_unref(client->encoder); encoder_unref(client->encoder);
encoder_unref(client->zrle_encoder);
encoder_unref(client->tight_encoder);
pixman_region_fini(&client->damage); pixman_region_fini(&client->damage);
free(client->cut_text.buffer); free(client->cut_text.buffer);
free(client); free(client);
@ -1111,7 +1113,32 @@ static void process_fb_update_requests(struct nvnc_client* client)
client->encoder->on_done = NULL; client->encoder->on_done = NULL;
} }
encoder_unref(client->encoder); encoder_unref(client->encoder);
/* Zlib streams need to be saved so we keep encoders around that
* use them.
*/
switch (encoding) {
case RFB_ENCODING_ZRLE:
if (!client->zrle_encoder) {
client->zrle_encoder = encoder_new(encoding,
width, height);
}
client->encoder = client->zrle_encoder;
encoder_ref(client->encoder);
break;
case RFB_ENCODING_TIGHT:
if (!client->tight_encoder) {
client->tight_encoder = encoder_new(encoding,
width, height);
}
client->encoder = client->tight_encoder;
encoder_ref(client->encoder);
break;
default:
client->encoder = encoder_new(encoding, width, height); client->encoder = encoder_new(encoding, width, height);
break;
}
if (!client->encoder) { if (!client->encoder) {
nvnc_log(NVNC_LOG_ERROR, "Failed to allocate new encoder"); nvnc_log(NVNC_LOG_ERROR, "Failed to allocate new encoder");
return; return;