summaryrefslogtreecommitdiffstats
path: root/libvncclient
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2017-10-14 18:50:54 +0200
committerSlávek Banko <slavek.banko@axis.cz>2017-10-14 18:50:54 +0200
commit68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5 (patch)
treeb1a8739116bd994e85cfa4ac8a275b49678ba00b /libvncclient
parent27bc3dba7089268b0247e91957fff498a43d08dc (diff)
parent8415ff4c3517c6697d53e1a17bba35284f480891 (diff)
downloadlibtdevnc-68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5.tar.gz
libtdevnc-68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5.zip
Merge tag 'LibVNCServer-0.9.11' of https://github.com/LibVNC/libvncserver
Conflicts: CMakeLists.txt libvncserver/main.c
Diffstat (limited to 'libvncclient')
-rw-r--r--libvncclient/Makefile.am6
-rw-r--r--libvncclient/cursor.c6
-rw-r--r--libvncclient/h264.c648
-rw-r--r--libvncclient/listen.c11
-rw-r--r--libvncclient/rfbproto.c63
-rw-r--r--libvncclient/sockets.c2
-rw-r--r--libvncclient/tls_gnutls.c40
-rw-r--r--libvncclient/ultra.c8
-rw-r--r--libvncclient/vncviewer.c6
9 files changed, 90 insertions, 700 deletions
diff --git a/libvncclient/Makefile.am b/libvncclient/Makefile.am
index 76bed21..bc2420b 100644
--- a/libvncclient/Makefile.am
+++ b/libvncclient/Makefile.am
@@ -14,16 +14,16 @@ endif
libvncclient_la_SOURCES=cursor.c listen.c rfbproto.c sockets.c vncviewer.c ../common/minilzo.c $(TLSSRCS)
-libvncclient_la_LIBADD=$(TLSLIBS) $(VA_LIBS)
+libvncclient_la_LIBADD=$(TLSLIBS)
noinst_HEADERS=../common/lzodefs.h ../common/lzoconf.h ../common/minilzo.h tls.h
rfbproto.o: rfbproto.c corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c
-EXTRA_DIST=corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c tls_gnutls.c tls_openssl.c tls_none.c h264.c
+EXTRA_DIST=corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c tls_gnutls.c tls_openssl.c tls_none.c
$(libvncclient_la_OBJECTS): ../rfb/rfbclient.h
lib_LTLIBRARIES=libvncclient.la
-
+libvncclient_la_LDFLAGS = -version-info 1:0:0
diff --git a/libvncclient/cursor.c b/libvncclient/cursor.c
index a48d7c5..67f4572 100644
--- a/libvncclient/cursor.c
+++ b/libvncclient/cursor.c
@@ -37,12 +37,6 @@
<< client->format.blueShift)
-/*********************************************************************
- * HandleCursorShape(). Support for XCursor and RichCursor shape
- * updates. We emulate cursor operating on the frame buffer (that is
- * why we call it "software cursor").
- ********************************************************************/
-
rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc)
{
int bytesPerPixel;
diff --git a/libvncclient/h264.c b/libvncclient/h264.c
deleted file mode 100644
index c63a713..0000000
--- a/libvncclient/h264.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Copyright (C) 2012 Intel Corporation. All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
-
-#include <X11/Xlib.h>
-#include <va/va_version.h>
-#if VA_CHECK_VERSION(0,34,0)
-#include <va/va_compat.h>
-#endif
-#include <va/va_x11.h>
-
-enum _slice_types {
- SLICE_TYPE_P = 0, /* Predicted */
- SLICE_TYPE_B = 1, /* Bi-predicted */
- SLICE_TYPE_I = 2, /* Intra coded */
-};
-
-#define SURFACE_NUM 7
-
-VADisplay va_dpy = NULL;
-VAConfigID va_config_id;
-VASurfaceID va_surface_id[SURFACE_NUM];
-VAContextID va_context_id = 0;
-
-VABufferID va_pic_param_buf_id[SURFACE_NUM];
-VABufferID va_mat_param_buf_id[SURFACE_NUM];
-VABufferID va_sp_param_buf_id[SURFACE_NUM];
-VABufferID va_d_param_buf_id[SURFACE_NUM];
-
-static int cur_height = 0;
-static int cur_width = 0;
-static unsigned int num_frames = 0;
-static int sid = 0;
-static unsigned int frame_id = 0;
-static int field_order_count = 0;
-static VASurfaceID curr_surface = VA_INVALID_ID;
-
-VAStatus gva_status;
-VASurfaceStatus gsurface_status;
-#define CHECK_SURF(X) \
- gva_status = vaQuerySurfaceStatus(va_dpy, X, &gsurface_status); \
- if (gsurface_status != 4) printf("ss: %d\n", gsurface_status);
-
-#ifdef _DEBUG
-#define DebugLog(A) rfbClientLog A
-#else
-#define DebugLog(A)
-#endif
-
-#define CHECK_VASTATUS(va_status,func) \
- if (va_status != VA_STATUS_SUCCESS) { \
- /*fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__);*/ \
- rfbClientErr("%s:%s:%d failed (0x%x),exit\n", __func__, func, __LINE__, va_status); \
- exit(1); \
- } else { \
- /*fprintf(stderr,">> SUCCESS for: %s:%s (%d)\n", __func__, func, __LINE__);*/ \
- DebugLog(("%s:%s:%d success\n", __func__, func, __LINE__)); \
- }
-
-/*
- * Forward declarations
- */
-static void h264_decode_frame(int f_width, int f_height, char *framedata, int framesize, int slice_type);
-static void SetVAPictureParameterBufferH264(VAPictureParameterBufferH264 *p, int width, int height);
-static void SetVASliceParameterBufferH264(VASliceParameterBufferH264 *p);
-static void SetVASliceParameterBufferH264_Intra(VASliceParameterBufferH264 *p, int first);
-
-static void put_updated_rectangle(rfbClient *client, int x, int y, int width, int height, int f_width, int f_height, int first_for_frame);
-static void nv12_to_rgba(const VAImage vaImage, rfbClient *client, int ch_x, int ch_y, int ch_w, int ch_h);
-
-
-/* FIXME: get this value from the server instead of hardcoding 32bit pixels */
-#define BPP (4 * 8)
-
-static const char *string_of_FOURCC(uint32_t fourcc)
-{
- static int buf;
- static char str[2][5];
-
- buf ^= 1;
- str[buf][0] = fourcc;
- str[buf][1] = fourcc >> 8;
- str[buf][2] = fourcc >> 16;
- str[buf][3] = fourcc >> 24;
- str[buf][4] = '\0';
- return str[buf];
-}
-
-static inline const char *string_of_VAImageFormat(VAImageFormat *imgfmt)
-{
- return string_of_FOURCC(imgfmt->fourcc);
-}
-
-
-static rfbBool
-HandleH264 (rfbClient* client, int rx, int ry, int rw, int rh)
-{
- rfbH264Header hdr;
- char *framedata;
-
- DebugLog(("Framebuffer update with H264 (x: %d, y: %d, w: %d, h: %d)\n", rx, ry, rw, rh));
-
- /* First, read the frame size and allocate buffer to store the data */
- if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbH264Header))
- return FALSE;
-
- hdr.slice_type = rfbClientSwap32IfLE(hdr.slice_type);
- hdr.nBytes = rfbClientSwap32IfLE(hdr.nBytes);
- hdr.width = rfbClientSwap32IfLE(hdr.width);
- hdr.height = rfbClientSwap32IfLE(hdr.height);
-
- framedata = (char*) malloc(hdr.nBytes);
-
- /* Obtain frame data from the server */
- DebugLog(("Reading %d bytes of frame data (type: %d)\n", hdr.nBytes, hdr.slice_type));
- if (!ReadFromRFBServer(client, framedata, hdr.nBytes))
- return FALSE;
-
- /* First make sure we have a large enough raw buffer to hold the
- * decompressed data. In practice, with a fixed BPP, fixed frame
- * buffer size and the first update containing the entire frame
- * buffer, this buffer allocation should only happen once, on the
- * first update.
- */
- if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) {
- if ( client->raw_buffer != NULL ) {
- free( client->raw_buffer );
- }
-
- client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 ));
- client->raw_buffer = (char*) malloc( client->raw_buffer_size );
- rfbClientLog("Allocated raw buffer of %d bytes (%dx%dx%d BPP)\n", client->raw_buffer_size, rw, rh, BPP);
- }
-
- /* Decode frame if frame data was sent. Server only sends frame data for the first
- * framebuffer update message for a particular frame buffer contents.
- * If more than 1 rectangle is updated, the messages after the first one (with
- * the H.264 frame) have nBytes == 0.
- */
- if (hdr.nBytes > 0) {
- DebugLog((" decoding %d bytes of H.264 data\n", hdr.nBytes));
- h264_decode_frame(hdr.width, hdr.height, framedata, hdr.nBytes, hdr.slice_type);
- }
-
- DebugLog((" updating rectangle (%d, %d)-(%d, %d)\n", rx, ry, rw, rh));
- put_updated_rectangle(client, rx, ry, rw, rh, hdr.width, hdr.height, hdr.nBytes != 0);
-
- free(framedata);
-
- return TRUE;
-}
-
-static void h264_cleanup_decoder()
-{
- VAStatus va_status;
-
- rfbClientLog("%s()\n", __FUNCTION__);
-
- if (va_surface_id[0] != VA_INVALID_ID) {
- va_status = vaDestroySurfaces(va_dpy, &va_surface_id[0], SURFACE_NUM);
- CHECK_VASTATUS(va_status, "vaDestroySurfaces");
- }
-
- if (va_context_id) {
- va_status = vaDestroyContext(va_dpy, va_context_id);
- CHECK_VASTATUS(va_status, "vaDestroyContext");
- va_context_id = 0;
- }
-
- num_frames = 0;
- sid = 0;
- frame_id = 0;
- field_order_count = 0;
-}
-
-static void h264_init_decoder(int width, int height)
-{
- VAStatus va_status;
-
- if (va_context_id) {
- rfbClientLog("%s: va_dpy already initialized\n", __FUNCTION__);
- }
-
- if (va_dpy != NULL) {
- rfbClientLog("%s: Re-initializing H.264 decoder\n", __FUNCTION__);
- }
- else {
- rfbClientLog("%s: initializing H.264 decoder\n", __FUNCTION__);
-
- /* Attach VA display to local X display */
- Display *win_display = (Display *)XOpenDisplay(":0.0");
- if (win_display == NULL) {
- rfbClientErr("Can't connect to local display\n");
- exit(-1);
- }
-
- int major_ver, minor_ver;
- va_dpy = vaGetDisplay(win_display);
- va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
- CHECK_VASTATUS(va_status, "vaInitialize");
- rfbClientLog("%s: libva version %d.%d found\n", __FUNCTION__, major_ver, minor_ver);
- }
-
- /* Check for VLD entrypoint */
- int num_entrypoints;
- VAEntrypoint entrypoints[5];
- int vld_entrypoint_found = 0;
-
- /* Change VAProfileH264High if needed */
- VAProfile profile = VAProfileH264High;
- va_status = vaQueryConfigEntrypoints(va_dpy, profile, entrypoints, &num_entrypoints);
- CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
- int i;
- for (i = 0; i < num_entrypoints; ++i) {
- if (entrypoints[i] == VAEntrypointVLD) {
- vld_entrypoint_found = 1;
- break;
- }
- }
-
- if (vld_entrypoint_found == 0) {
- rfbClientErr("VLD entrypoint not found\n");
- exit(1);
- }
-
- /* Create configuration for the decode pipeline */
- VAConfigAttrib attrib;
- attrib.type = VAConfigAttribRTFormat;
- va_status = vaCreateConfig(va_dpy, profile, VAEntrypointVLD, &attrib, 1, &va_config_id);
- CHECK_VASTATUS(va_status, "vaCreateConfig");
-
- /* Create VA surfaces */
- for (i = 0; i < SURFACE_NUM; ++i) {
- va_surface_id[i] = VA_INVALID_ID;
- va_pic_param_buf_id[i] = VA_INVALID_ID;
- va_mat_param_buf_id[i] = VA_INVALID_ID;
- va_sp_param_buf_id[i] = VA_INVALID_ID;
- va_d_param_buf_id[i] = VA_INVALID_ID;
- }
- va_status = vaCreateSurfaces(va_dpy, width, height, VA_RT_FORMAT_YUV420, SURFACE_NUM, &va_surface_id[0]);
- CHECK_VASTATUS(va_status, "vaCreateSurfaces");
- for (i = 0; i < SURFACE_NUM; ++i) {
- DebugLog(("%s: va_surface_id[%d] = %p\n", __FUNCTION__, i, va_surface_id[i]));
- }
-
- /* Create VA context */
- va_status = vaCreateContext(va_dpy, va_config_id, width, height, 0/*VA_PROGRESSIVE*/, &va_surface_id[0], SURFACE_NUM, &va_context_id);
- CHECK_VASTATUS(va_status, "vaCreateContext");
- DebugLog(("%s: VA context created (id: %d)\n", __FUNCTION__, va_context_id));
-
-
- /* Instantiate decode pipeline */
- va_status = vaBeginPicture(va_dpy, va_context_id, va_surface_id[0]);
- CHECK_VASTATUS(va_status, "vaBeginPicture");
-
- rfbClientLog("%s: H.264 decoder initialized\n", __FUNCTION__);
-}
-
-static void h264_decode_frame(int f_width, int f_height, char *framedata, int framesize, int slice_type)
-{
- VAStatus va_status;
-
- DebugLog(("%s: called for frame of %d bytes (%dx%d) slice_type=%d\n", __FUNCTION__, framesize, width, height, slice_type));
-
- /* Initialize decode pipeline if necessary */
- if ( (f_width > cur_width) || (f_height > cur_height) ) {
- if (va_dpy != NULL)
- h264_cleanup_decoder();
- cur_width = f_width;
- cur_height = f_height;
-
- h264_init_decoder(f_width, f_height);
- rfbClientLog("%s: decoder initialized\n", __FUNCTION__);
- }
-
- /* Decode frame */
- static VAPictureH264 va_picture_h264, va_old_picture_h264;
-
- /* The server should always send an I-frame when a new client connects
- * or when the resolution of the framebuffer changes, but we check
- * just in case.
- */
- if ( (slice_type != SLICE_TYPE_I) && (num_frames == 0) ) {
- rfbClientLog("First frame is not an I frame !!! Skipping!!!\n");
- return;
- }
-
- DebugLog(("%s: frame_id=%d va_surface_id[%d]=0x%x field_order_count=%d\n", __FUNCTION__, frame_id, sid, va_surface_id[sid], field_order_count));
-
- va_picture_h264.picture_id = va_surface_id[sid];
- va_picture_h264.frame_idx = frame_id;
- va_picture_h264.flags = 0;
- va_picture_h264.BottomFieldOrderCnt = field_order_count;
- va_picture_h264.TopFieldOrderCnt = field_order_count;
-
- /* Set up picture parameter buffer */
- if (va_pic_param_buf_id[sid] == VA_INVALID_ID) {
- va_status = vaCreateBuffer(va_dpy, va_context_id, VAPictureParameterBufferType, sizeof(VAPictureParameterBufferH264), 1, NULL, &va_pic_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaCreateBuffer(PicParam)");
- }
- CHECK_SURF(va_surface_id[sid]);
-
- VAPictureParameterBufferH264 *pic_param_buf = NULL;
- va_status = vaMapBuffer(va_dpy, va_pic_param_buf_id[sid], (void **)&pic_param_buf);
- CHECK_VASTATUS(va_status, "vaMapBuffer(PicParam)");
-
- SetVAPictureParameterBufferH264(pic_param_buf, f_width, f_height);
- memcpy(&pic_param_buf->CurrPic, &va_picture_h264, sizeof(VAPictureH264));
-
- if (slice_type == SLICE_TYPE_P) {
- memcpy(&pic_param_buf->ReferenceFrames[0], &va_old_picture_h264, sizeof(VAPictureH264));
- pic_param_buf->ReferenceFrames[0].flags = 0;
- }
- else if (slice_type != SLICE_TYPE_I) {
- rfbClientLog("Frame type %d not supported!!!\n");
- return;
- }
- pic_param_buf->frame_num = frame_id;
-
- va_status = vaUnmapBuffer(va_dpy, va_pic_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaUnmapBuffer(PicParam)");
-
- /* Set up IQ matrix buffer */
- if (va_mat_param_buf_id[sid] == VA_INVALID_ID) {
- va_status = vaCreateBuffer(va_dpy, va_context_id, VAIQMatrixBufferType, sizeof(VAIQMatrixBufferH264), 1, NULL, &va_mat_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaCreateBuffer(IQMatrix)");
- }
- CHECK_SURF(va_surface_id[sid]);
-
- VAIQMatrixBufferH264 *iq_matrix_buf = NULL;
- va_status = vaMapBuffer(va_dpy, va_mat_param_buf_id[sid], (void **)&iq_matrix_buf);
- CHECK_VASTATUS(va_status, "vaMapBuffer(IQMatrix)");
-
- static const unsigned char m_MatrixBufferH264[]= {
- /* ScalingList4x4[6][16] */
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- /* ScalingList8x8[2][64] */
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- };
-
- memcpy(iq_matrix_buf, m_MatrixBufferH264, 224);
- va_status = vaUnmapBuffer(va_dpy, va_mat_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaUnmapBuffer(IQMatrix)");
-
- VABufferID buffer_ids[2];
- buffer_ids[0] = va_pic_param_buf_id[sid];
- buffer_ids[1] = va_mat_param_buf_id[sid];
-
- CHECK_SURF(va_surface_id[sid]);
- va_status = vaRenderPicture(va_dpy, va_context_id, buffer_ids, 2);
- CHECK_VASTATUS(va_status, "vaRenderPicture");
-
- /* Set up slice parameter buffer */
- if (va_sp_param_buf_id[sid] == VA_INVALID_ID) {
- va_status = vaCreateBuffer(va_dpy, va_context_id, VASliceParameterBufferType, sizeof(VASliceParameterBufferH264), 1, NULL, &va_sp_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaCreateBuffer(SliceParam)");
- }
- CHECK_SURF(va_surface_id[sid]);
-
- VASliceParameterBufferH264 *slice_param_buf = NULL;
- va_status = vaMapBuffer(va_dpy, va_sp_param_buf_id[sid], (void **)&slice_param_buf);
- CHECK_VASTATUS(va_status, "vaMapBuffer(SliceParam)");
-
- static int t2_first = 1;
- if (slice_type == SLICE_TYPE_I) {
- SetVASliceParameterBufferH264_Intra(slice_param_buf, t2_first);
- t2_first = 0;
- } else {
- SetVASliceParameterBufferH264(slice_param_buf);
- memcpy(&slice_param_buf->RefPicList0[0], &va_old_picture_h264, sizeof(VAPictureH264));
- slice_param_buf->RefPicList0[0].flags = 0;
- }
- slice_param_buf->slice_data_bit_offset = 0;
- slice_param_buf->slice_data_size = framesize;
-
- va_status = vaUnmapBuffer(va_dpy, va_sp_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaUnmapBuffer(SliceParam)");
- CHECK_SURF(va_surface_id[sid]);
-
- /* Set up slice data buffer and copy H.264 encoded data */
- if (va_d_param_buf_id[sid] == VA_INVALID_ID) {
- /* TODO use estimation matching framebuffer dimensions instead of this large value */
- va_status = vaCreateBuffer(va_dpy, va_context_id, VASliceDataBufferType, 4177920, 1, NULL, &va_d_param_buf_id[sid]); /* 1080p size */
- CHECK_VASTATUS(va_status, "vaCreateBuffer(SliceData)");
- }
-
- char *slice_data_buf;
- va_status = vaMapBuffer(va_dpy, va_d_param_buf_id[sid], (void **)&slice_data_buf);
- CHECK_VASTATUS(va_status, "vaMapBuffer(SliceData)");
- memcpy(slice_data_buf, framedata, framesize);
-
- CHECK_SURF(va_surface_id[sid]);
- va_status = vaUnmapBuffer(va_dpy, va_d_param_buf_id[sid]);
- CHECK_VASTATUS(va_status, "vaUnmapBuffer(SliceData)");
-
- buffer_ids[0] = va_sp_param_buf_id[sid];
- buffer_ids[1] = va_d_param_buf_id[sid];
-
- CHECK_SURF(va_surface_id[sid]);
- va_status = vaRenderPicture(va_dpy, va_context_id, buffer_ids, 2);
- CHECK_VASTATUS(va_status, "vaRenderPicture");
-
- va_status = vaEndPicture(va_dpy, va_context_id);
- CHECK_VASTATUS(va_status, "vaEndPicture");
-
- /* Prepare next one... */
- int sid_new = (sid + 1) % SURFACE_NUM;
- DebugLog(("%s: new Surface ID = %d\n", __FUNCTION__, sid_new));
- va_status = vaBeginPicture(va_dpy, va_context_id, va_surface_id[sid_new]);
- CHECK_VASTATUS(va_status, "vaBeginPicture");
-
- /* Get decoded data */
- va_status = vaSyncSurface(va_dpy, va_surface_id[sid]);
- CHECK_VASTATUS(va_status, "vaSyncSurface");
- CHECK_SURF(va_surface_id[sid]);
-
- curr_surface = va_surface_id[sid];
-
- sid = sid_new;
-
- field_order_count += 2;
- ++frame_id;
- if (frame_id > 15) {
- frame_id = 0;
- }
-
- ++num_frames;
-
- memcpy(&va_old_picture_h264, &va_picture_h264, sizeof(VAPictureH264));
-}
-
-static void put_updated_rectangle(rfbClient *client, int x, int y, int width, int height, int f_width, int f_height, int first_for_frame)
-{
- if (curr_surface == VA_INVALID_ID) {
- rfbClientErr("%s: called, but current surface is invalid\n", __FUNCTION__);
- return;
- }
-
- VAStatus va_status;
-
- if (client->outputWindow) {
- /* use efficient vaPutSurface() method of putting the framebuffer on the screen */
- if (first_for_frame) {
- /* vaPutSurface() clears window contents outside the given destination rectangle => always update full screen. */
- va_status = vaPutSurface(va_dpy, curr_surface, client->outputWindow, 0, 0, f_width, f_height, 0, 0, f_width, f_height, NULL, 0, VA_FRAME_PICTURE);
- CHECK_VASTATUS(va_status, "vaPutSurface");
- }
- }
- else if (client->frameBuffer) {
- /* ... or copy the changed framebuffer region manually as a fallback */
- VAImage decoded_image;
- decoded_image.image_id = VA_INVALID_ID;
- decoded_image.buf = VA_INVALID_ID;
- va_status = vaDeriveImage(va_dpy, curr_surface, &decoded_image);
- CHECK_VASTATUS(va_status, "vaDeriveImage");
-
- if ((decoded_image.image_id == VA_INVALID_ID) || (decoded_image.buf == VA_INVALID_ID)) {
- rfbClientErr("%s: vaDeriveImage() returned success but VA image is invalid (id: %d, buf: %d)\n", __FUNCTION__, decoded_image.image_id, decoded_image.buf);
- }
-
- nv12_to_rgba(decoded_image, client, x, y, width, height);
-
- va_status = vaDestroyImage(va_dpy, decoded_image.image_id);
- CHECK_VASTATUS(va_status, "vaDestroyImage");
- }
-}
-
-static void SetVAPictureParameterBufferH264(VAPictureParameterBufferH264 *p, int width, int height)
-{
- int i;
- unsigned int width_in_mbs = (width + 15) / 16;
- unsigned int height_in_mbs = (height + 15) / 16;
-
- memset(p, 0, sizeof(VAPictureParameterBufferH264));
- p->picture_width_in_mbs_minus1 = width_in_mbs - 1;
- p->picture_height_in_mbs_minus1 = height_in_mbs - 1;
- p->num_ref_frames = 1;
- p->seq_fields.value = 145;
- p->pic_fields.value = 0x501;
- for (i = 0; i < 16; i++) {
- p->ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
- p->ReferenceFrames[i].picture_id = 0xffffffff;
- }
-}
-
-static void SetVASliceParameterBufferH264(VASliceParameterBufferH264 *p)
-{
- int i;
- memset(p, 0, sizeof(VASliceParameterBufferH264));
- p->slice_data_size = 0;
- p->slice_data_bit_offset = 64;
- p->slice_alpha_c0_offset_div2 = 2;
- p->slice_beta_offset_div2 = 2;
- p->chroma_weight_l0_flag = 1;
- p->chroma_weight_l0[0][0]=1;
- p->chroma_offset_l0[0][0]=0;
- p->chroma_weight_l0[0][1]=1;
- p->chroma_offset_l0[0][1]=0;
- p->luma_weight_l1_flag = 1;
- p->chroma_weight_l1_flag = 1;
- p->luma_weight_l0[0]=0x01;
- for (i = 0; i < 32; i++) {
- p->RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
- p->RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
- }
- p->RefPicList1[0].picture_id = 0xffffffff;
-}
-
-static void SetVASliceParameterBufferH264_Intra(VASliceParameterBufferH264 *p, int first)
-{
- int i;
- memset(p, 0, sizeof(VASliceParameterBufferH264));
- p->slice_data_size = 0;
- p->slice_data_bit_offset = 64;
- p->slice_alpha_c0_offset_div2 = 2;
- p->slice_beta_offset_div2 = 2;
- p->slice_type = 2;
- if (first) {
- p->luma_weight_l0_flag = 1;
- p->chroma_weight_l0_flag = 1;
- p->luma_weight_l1_flag = 1;
- p->chroma_weight_l1_flag = 1;
- } else {
- p->chroma_weight_l0_flag = 1;
- p->chroma_weight_l0[0][0]=1;
- p->chroma_offset_l0[0][0]=0;
- p->chroma_weight_l0[0][1]=1;
- p->chroma_offset_l0[0][1]=0;
- p->luma_weight_l1_flag = 1;
- p->chroma_weight_l1_flag = 1;
- p->luma_weight_l0[0]=0x01;
- }
- for (i = 0; i < 32; i++) {
- p->RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
- p->RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
- }
- p->RefPicList1[0].picture_id = 0xffffffff;
- p->RefPicList0[0].picture_id = 0xffffffff;
-}
-
-static void nv12_to_rgba(const VAImage vaImage, rfbClient *client, int ch_x, int ch_y, int ch_w, int ch_h)
-{
- DebugLog(("%s: converting region (%d, %d)-(%d, %d) from NV12->RGBA\n", __FUNCTION__, ch_x, ch_y, ch_w, ch_h));
-
- VAStatus va_status;
- uint8_t *nv12_buf;
- va_status = vaMapBuffer(va_dpy, vaImage.buf, (void **)&nv12_buf);
- CHECK_VASTATUS(va_status, "vaMapBuffer(DecodedData)");
-
- /* adjust x, y, width, height of the affected area so
- * x, y, width and height are always even.
- */
- if (ch_x % 2) { --ch_x; ++ch_w; }
- if (ch_y % 2) { --ch_y; ++ch_h; }
- if ((ch_x + ch_w) % 2) { ++ch_w; }
- if ((ch_y + ch_h) % 2) { ++ch_h; }
-
- /* point nv12_buf and dst to upper left corner of changed area */
- uint8_t *nv12_y = &nv12_buf[vaImage.offsets[0] + vaImage.pitches[0] * ch_y + ch_x];
- uint8_t *nv12_uv = &nv12_buf[vaImage.offsets[1] + vaImage.pitches[1] * (ch_y / 2) + ch_x];
- uint32_t *dst = &((uint32_t*)client->frameBuffer)[client->width * ch_y + ch_x];
-
- /* TODO: optimize R, G, B calculation. Possible ways to do this:
- * - use lookup tables
- * - convert from floating point to integer arithmetic
- * - use MMX/SSE to vectorize calculations
- * - use GPU (VA VPP, shader...)
- */
- int src_x, src_y;
- for (src_y = 0; src_y < ch_h; src_y += 2) {
- for (src_x = 0; src_x < ch_w; src_x += 2) {
- uint8_t nv_u = nv12_uv[src_x];
- uint8_t nv_v = nv12_uv[src_x + 1];
- uint8_t nv_y[4] = { nv12_y[ src_x], nv12_y[ src_x + 1],
- nv12_y[vaImage.pitches[0] + src_x], nv12_y[vaImage.pitches[0] + src_x + 1] };
-
- int i;
- for (i = 0; i < 4; ++i) {
- double R = 1.164 * (nv_y[i] - 16) + 1.596 * (nv_v - 128);
- double G = 1.164 * (nv_y[i] - 16) - 0.391 * (nv_u - 128) - 0.813 * (nv_v - 128);
- double B = 1.164 * (nv_y[i] - 16) + 2.018 * (nv_u - 128);
-
- /* clamp R, G, B values. For some Y, U, V combinations,
- * the results of the above calculations fall outside of
- * the range 0-255.
- */
- if (R < 0.0) R = 0.0;
- if (G < 0.0) G = 0.0;
- if (B < 0.0) B = 0.0;
- if (R > 255.0) R = 255.0;
- if (G > 255.0) G = 255.0;
- if (B > 255.0) B = 255.0;
-
- dst[client->width * (i / 2) + src_x + (i % 2)] = 0
- | ((unsigned int)(R + 0.5) << client->format.redShift)
- | ((unsigned int)(G + 0.5) << client->format.greenShift)
- | ((unsigned int)(B + 0.5) << client->format.blueShift);
- }
- }
-
- nv12_y += 2 * vaImage.pitches[0];
- nv12_uv += vaImage.pitches[1];
- dst += 2 * client->width;
- }
-
- CHECK_SURF(va_surface_id[sid]);
- va_status = vaUnmapBuffer(va_dpy, vaImage.buf);
- CHECK_VASTATUS(va_status, "vaUnmapBuffer(DecodedData)");
-}
-
-#endif /* LIBVNCSERVER_CONFIG_LIBVA */
diff --git a/libvncclient/listen.c b/libvncclient/listen.c
index 6d4ad54..e989d6a 100644
--- a/libvncclient/listen.c
+++ b/libvncclient/listen.c
@@ -30,9 +30,6 @@
#ifdef WIN32
#define close closesocket
#include <winsock2.h>
-#ifdef _MINGW32
-#undef max
-#endif // #ifdef _MINGW32
#else // #ifdef WIN32
#include <sys/wait.h>
#include <sys/utsname.h>
@@ -99,7 +96,7 @@ listenForIncomingConnections(rfbClient* client)
if(listen6Socket >= 0)
FD_SET(listen6Socket, &fds);
- r = select(max(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL);
+ r = select(rfbMax(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL);
if (r > 0) {
if (FD_ISSET(listenSocket, &fds))
@@ -141,7 +138,7 @@ listenForIncomingConnections(rfbClient* client)
/*
* listenForIncomingConnectionsNoFork() - listen for incoming connections
* from servers, but DON'T fork, instead just wait timeout microseconds.
- * If timeout is negative, block indefinitly.
+ * If timeout is negative, block indefinitely.
* Returns 1 on success (there was an incoming connection on the listen socket
* and we accepted it successfully), -1 on error, 0 on timeout.
*/
@@ -195,9 +192,9 @@ listenForIncomingConnectionsNoFork(rfbClient* client, int timeout)
FD_SET(client->listen6Sock, &fds);
if (timeout < 0)
- r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL);
+ r = select(rfbMax(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL);
else
- r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to);
+ r = select(rfbMax(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to);
if (r > 0)
{
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index 8ac0028..1f4b646 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -147,9 +147,22 @@ void* rfbClientGetClientData(rfbClient* client, void* tag)
/* messages */
+static rfbBool CheckRect(rfbClient* client, int x, int y, int w, int h) {
+ return x + w <= client->width && y + h <= client->height;
+}
+
static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
int i,j;
+ if (client->frameBuffer == NULL) {
+ return;
+ }
+
+ if (!CheckRect(client, x, y, w, h)) {
+ rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h);
+ return;
+ }
+
#define FILL_RECT(BPP) \
for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
for(i=x;i<x+w;i++) \
@@ -171,6 +184,11 @@ static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int
return;
}
+ if (!CheckRect(client, x, y, w, h)) {
+ rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h);
+ return;
+ }
+
#define COPY_RECT(BPP) \
{ \
int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
@@ -193,6 +211,20 @@ static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int
static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
int i,j;
+ if (client->frameBuffer == NULL) {
+ return;
+ }
+
+ if (!CheckRect(client, src_x, src_y, w, h)) {
+ rfbClientLog("Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h);
+ return;
+ }
+
+ if (!CheckRect(client, dest_x, dest_y, w, h)) {
+ rfbClientLog("Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h);
+ return;
+ }
+
#define COPY_RECT_FROM_RECT(BPP) \
{ \
uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
@@ -273,9 +305,6 @@ static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh)
static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
#endif
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
-static rfbBool HandleH264 (rfbClient* client, int rx, int ry, int rw, int rh);
-#endif
/*
* Server Capability Functions
@@ -1411,10 +1440,6 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
} else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
- } else if (strncasecmp(encStr,"h264",encStrLen) == 0) {
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingH264);
-#endif
} else {
rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
}
@@ -1483,10 +1508,6 @@ SetFormatAndEncodings(rfbClient* client)
encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
rfbEncodingQualityLevel0);
}
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
- encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingH264);
- rfbClientLog("h264 encoding added\n");
-#endif
}
@@ -1530,7 +1551,8 @@ SetFormatAndEncodings(rfbClient* client)
if(e->encodings) {
int* enc;
for(enc = e->encodings; *enc; enc++)
- encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
+ if(se->nEncodings < MAX_ENCODINGS)
+ encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
}
len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
@@ -1981,7 +2003,10 @@ HandleRFBServerMessage(rfbClient* client)
int y=rect.r.y, h=rect.r.h;
bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
- linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
+ /* RealVNC 4.x-5.x on OSX can induce bytesPerLine==0,
+ usually during GPU accel. */
+ /* Regardless of cause, do not divide by zero. */
+ linesToRead = bytesPerLine ? (RFB_BUFFER_SIZE / bytesPerLine) : 0;
while (h > 0) {
if (linesToRead > h)
@@ -1997,7 +2022,8 @@ HandleRFBServerMessage(rfbClient* client)
y += linesToRead;
}
- } break;
+ break;
+ }
case rfbEncodingCopyRect:
{
@@ -2204,14 +2230,6 @@ HandleRFBServerMessage(rfbClient* client)
}
#endif
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
- case rfbEncodingH264:
- {
- if (!HandleH264(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h))
- return FALSE;
- break;
- }
-#endif
default:
{
@@ -2448,7 +2466,6 @@ HandleRFBServerMessage(rfbClient* client)
#define UNCOMP -8
#include "zrle.c"
#undef BPP
-#include "h264.c"
/*
diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c
index 225450c..2963432 100644
--- a/libvncclient/sockets.c
+++ b/libvncclient/sockets.c
@@ -567,7 +567,7 @@ ListenAtTcpPortAndAddress(int port, const char *address)
}
#ifdef IPV6_V6ONLY
- /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
+ /* we have separate IPv4 and IPv6 sockets since some OS's do not support dual binding */
if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno));
close(sock);
diff --git a/libvncclient/tls_gnutls.c b/libvncclient/tls_gnutls.c
index 3daa416..b9ffe89 100644
--- a/libvncclient/tls_gnutls.c
+++ b/libvncclient/tls_gnutls.c
@@ -67,9 +67,20 @@ InitializeTLS(void)
* libvncclient are linked to different versions of msvcrt.dll.
*/
#ifdef WIN32
-static void WSAtoTLSErrno()
+static void WSAtoTLSErrno(gnutls_session_t* session)
{
switch(WSAGetLastError()) {
+#if (GNUTLS_VERSION_NUMBER >= 0x029901)
+ case WSAEWOULDBLOCK:
+ gnutls_transport_set_errno(session, EAGAIN);
+ break;
+ case WSAEINTR:
+ gnutls_transport_set_errno(session, EINTR);
+ break;
+ default:
+ gnutls_transport_set_errno(session, EIO);
+ break;
+#else
case WSAEWOULDBLOCK:
gnutls_transport_set_global_errno(EAGAIN);
break;
@@ -79,11 +90,11 @@ static void WSAtoTLSErrno()
default:
gnutls_transport_set_global_errno(EIO);
break;
+#endif
}
}
#endif
-
static ssize_t
PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len)
{
@@ -96,7 +107,7 @@ PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len)
if (ret < 0)
{
#ifdef WIN32
- WSAtoTLSErrno();
+ WSAtoTLSErrno((gnutls_session_t*)&client->tlsSession);
#endif
if (errno == EINTR) continue;
return -1;
@@ -118,7 +129,7 @@ PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len)
if (ret < 0)
{
#ifdef WIN32
- WSAtoTLSErrno();
+ WSAtoTLSErrno((gnutls_session_t*)&client->tlsSession);
#endif
if (errno == EINTR) continue;
return -1;
@@ -480,6 +491,14 @@ WriteToTLS(rfbClient* client, char *buf, unsigned int n)
unsigned int offset = 0;
ssize_t ret;
+ if (client->LockWriteToTLS)
+ {
+ if (!client->LockWriteToTLS(client))
+ {
+ rfbClientLog("Callback to get lock in WriteToTLS() failed\n");
+ return -1;
+ }
+ }
while (offset < n)
{
ret = gnutls_record_send((gnutls_session_t)client->tlsSession, buf+offset, (size_t)(n-offset));
@@ -488,10 +507,23 @@ WriteToTLS(rfbClient* client, char *buf, unsigned int n)
{
if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) continue;
rfbClientLog("Error writing to TLS: %s.\n", gnutls_strerror(ret));
+ if (client->UnlockWriteToTLS)
+ {
+ if (!client->UnlockWriteToTLS(client))
+ rfbClientLog("Callback to unlock WriteToTLS() failed\n");
+ }
return -1;
}
offset += (unsigned int)ret;
}
+ if (client->UnlockWriteToTLS)
+ {
+ if (!client->UnlockWriteToTLS(client))
+ {
+ rfbClientLog("Callback to unlock WriteToTLS() failed\n");
+ return -1;
+ }
+ }
return offset;
}
diff --git a/libvncclient/ultra.c b/libvncclient/ultra.c
index dac89b5..32a1b2b 100644
--- a/libvncclient/ultra.c
+++ b/libvncclient/ultra.c
@@ -86,14 +86,14 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh)
/* uncompress the data */
uncompressedBytes = client->raw_buffer_size;
- inflateResult = lzo1x_decompress(
+ inflateResult = lzo1x_decompress_safe(
(lzo_byte *)client->ultra_buffer, toRead,
(lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes,
NULL);
-
+ /* Note that uncompressedBytes will be 0 on output overrun */
if ((rw * rh * (BPP / 8)) != uncompressedBytes)
- rfbClientLog("Ultra decompressed too little (%d < %d)", (rw * rh * (BPP / 8)), uncompressedBytes);
+ rfbClientLog("Ultra decompressed unexpected amount of data (%d != %d)\n", (rw * rh * (BPP / 8)), uncompressedBytes);
/* Put the uncompressed contents of the update on the screen. */
if ( inflateResult == LZO_E_OK )
@@ -168,7 +168,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh)
/* uncompress the data */
uncompressedBytes = client->raw_buffer_size;
- inflateResult = lzo1x_decompress(
+ inflateResult = lzo1x_decompress_safe(
(lzo_byte *)client->ultra_buffer, toRead,
(lzo_byte *)client->raw_buffer, &uncompressedBytes, NULL);
if ( inflateResult != LZO_E_OK )
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index 22bf0e4..3f85c06 100644
--- a/libvncclient/vncviewer.c
+++ b/libvncclient/vncviewer.c
@@ -116,11 +116,7 @@ static rfbBool MallocFrameBuffer(rfbClient* client) {
static void initAppData(AppData* data) {
data->shareDesktop=TRUE;
data->viewOnly=FALSE;
-#ifdef LIBVNCSERVER_CONFIG_LIBVA
- data->encodingsString="h264 tight zrle ultra copyrect hextile zlib corre rre raw";
-#else
data->encodingsString="tight zrle ultra copyrect hextile zlib corre rre raw";
-#endif
data->useBGR233=FALSE;
data->nColours=0;
data->forceOwnCmap=FALSE;
@@ -224,6 +220,8 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->subAuthScheme = 0;
client->GetCredential = NULL;
client->tlsSession = NULL;
+ client->LockWriteToTLS = NULL;
+ client->UnlockWriteToTLS = NULL;
client->sock = -1;
client->listenSock = -1;
client->listenAddress = NULL;