Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package neatvnc for openSUSE:Factory checked in at 2024-02-26 19:45:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/neatvnc (Old) and /work/SRC/openSUSE:Factory/.neatvnc.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "neatvnc" Mon Feb 26 19:45:33 2024 rev:12 rq:1150570 version:0.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/neatvnc/neatvnc.changes 2024-02-04 19:08:08.082301887 +0100 +++ /work/SRC/openSUSE:Factory/.neatvnc.new.1770/neatvnc.changes 2024-02-26 19:46:23.328073363 +0100 @@ -1,0 +2,17 @@ +Mon Feb 26 07:10:51 UTC 2024 - Michael Vetter <mvet...@suse.com> + +- Update to 0.8.0: + Highlights: + * The colour map pixel format as described in RFC 6143 has been + implemented. Before, the client would just get disconnected if + they requested it. Now they get a map that emulates RGB332. + * Momentary interception of log messages. The user can now set a + thread-local log hander and then set it back to the default. + * Philip Zabel made the code more consistent with the style guide. + Breaking Changes: + * nvnc_client_get_hostname has been replaced with nvnc_client_get_address + Bugfixes: + * Apple's Diffie-Hellman authentication (security type 30) has been fixed. + * A new client connection no longer causes a DNS lookup. + +------------------------------------------------------------------- Old: ---- v0.7.2.tar.gz New: ---- v0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ neatvnc.spec ++++++ --- /var/tmp/diff_new_pack.pgox5h/_old 2024-02-26 19:46:23.940095489 +0100 +++ /var/tmp/diff_new_pack.pgox5h/_new 2024-02-26 19:46:23.944095633 +0100 @@ -19,7 +19,7 @@ %define libsoname libneatvnc0 Name: neatvnc -Version: 0.7.2 +Version: 0.8.0 Release: 0 Summary: A VNC server library License: ISC ++++++ v0.7.2.tar.gz -> v0.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/README.md new/neatvnc-0.8.0/README.md --- old/neatvnc-0.7.2/README.md 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/README.md 2024-02-25 12:11:28.000000000 +0100 @@ -18,6 +18,9 @@ * gnutls (optional) * libdrm (optional) * libturbojpeg (optional) + * nettle (optional) + * hogweed (optional) + * gmp (optional) * pixman * zlib diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/bench/zrle-bench.c new/neatvnc-0.8.0/bench/zrle-bench.c --- old/neatvnc-0.7.2/bench/zrle-bench.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/bench/zrle-bench.c 2024-02-25 12:11:28.000000000 +0100 @@ -71,10 +71,10 @@ z_stream zs = { 0 }; deflateInit2(&zs, /* compression level: */ 1, - /* method: */ Z_DEFLATED, - /* window bits: */ 15, - /* mem level: */ 9, - /* strategy: */ Z_DEFAULT_STRATEGY); + /* method: */ Z_DEFLATED, + /* window bits: */ 15, + /* mem level: */ 9, + /* strategy: */ Z_DEFAULT_STRATEGY); void *dummy = malloc(stride * height * 4); if (!dummy) @@ -86,7 +86,7 @@ uint64_t end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); printf("memcpy baseline for %s took %"PRIu64" micro seconds\n", image, - end_time - start_time); + end_time - start_time); free(dummy); @@ -95,7 +95,7 @@ end_time = gettime_us(CLOCK_PROCESS_CPUTIME_ID); printf("Encoding %s took %"PRIu64" micro seconds\n", image, - end_time - start_time); + end_time - start_time); double orig_size = stride * height * 4; double compressed_size = frame.len; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/examples/draw.c new/neatvnc-0.8.0/examples/draw.c --- old/neatvnc-0.7.2/examples/draw.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/examples/draw.c 2024-02-25 12:11:28.000000000 +0100 @@ -198,7 +198,7 @@ } pixman_region_init_rect(damage, start.x, start.y, - stop.x - start.x, stop.y - start.y); + stop.x - start.x, stop.y - start.y); } static void draw_dot(struct draw *draw, struct coord coord, int radius, @@ -219,7 +219,7 @@ } static void on_pointer_event(struct nvnc_client* client, uint16_t x, uint16_t y, - enum nvnc_button_mask buttons) + enum nvnc_button_mask buttons) { if (!(buttons & NVNC_BUTTON_LEFT)) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/include/common.h new/neatvnc-0.8.0/include/common.h --- old/neatvnc-0.7.2/include/common.h 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/include/common.h 2024-02-25 12:11:28.000000000 +0100 @@ -83,7 +83,6 @@ struct nvnc_common common; int ref; struct stream* net_stream; - char hostname[256]; char username[256]; struct nvnc* server; enum nvnc_client_state state; @@ -109,6 +108,7 @@ struct encoder* tight_encoder; uint32_t cursor_seq; int quality; + bool formats_changed; #ifdef HAVE_CRYPTO struct crypto_key* apple_dh_secret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/include/neatvnc.h new/neatvnc-0.8.0/include/neatvnc.h --- old/neatvnc-0.7.2/include/neatvnc.h 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/include/neatvnc.h 2024-02-25 12:11:28.000000000 +0100 @@ -22,6 +22,7 @@ #include <stdarg.h> #include <stdlib.h> #include <assert.h> +#include <sys/socket.h> #define NVNC_NO_PTS UINT64_MAX @@ -141,7 +142,8 @@ struct nvnc* nvnc_client_get_server(const struct nvnc_client* client); bool nvnc_client_supports_cursor(const struct nvnc_client* client); -const char* nvnc_client_get_hostname(const struct nvnc_client* client); +int nvnc_client_get_address(const struct nvnc_client* client, + struct sockaddr* restrict addr, socklen_t* restrict addrlen); const char* nvnc_client_get_auth_username(const struct nvnc_client* client); struct nvnc_client* nvnc_client_first(struct nvnc* self); @@ -235,6 +237,9 @@ uint16_t height, uint16_t hotspot_x, uint16_t hotspot_y, bool is_damaged); +void nvnc_default_logger(const struct nvnc_log_data* meta, const char* message); + void nvnc_set_log_fn(nvnc_log_fn); +void nvnc_set_log_fn_thread_local(nvnc_log_fn fn); void nvnc_set_log_level(enum nvnc_log_level); void nvnc__log(const struct nvnc_log_data*, const char* fmt, ...); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/include/pixels.h new/neatvnc-0.8.0/include/pixels.h --- old/neatvnc-0.7.2/include/pixels.h 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/include/pixels.h 2024-02-25 12:11:28.000000000 +0100 @@ -22,6 +22,7 @@ #include <stdbool.h> struct rfb_pixel_format; +struct rfb_set_colour_map_entries_msg; void pixel_to_cpixel(uint8_t* restrict dst, const struct rfb_pixel_format* dst_fmt, @@ -41,3 +42,4 @@ const char* drm_format_to_string(uint32_t fmt); const char* rfb_pixfmt_to_string(const struct rfb_pixel_format* fmt); +void make_rgb332_pal8_map(struct rfb_set_colour_map_entries_msg* msg); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/include/rfb-proto.h new/neatvnc-0.8.0/include/rfb-proto.h --- old/neatvnc-0.7.2/include/rfb-proto.h 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/include/rfb-proto.h 2024-02-25 12:11:28.000000000 +0100 @@ -266,3 +266,15 @@ uint16_t length; uint8_t challenge[0]; } RFB_PACKED; + +struct rfb_colour_map_entry { + uint16_t r, g, b; +} RFB_PACKED; + +struct rfb_set_colour_map_entries_msg { + uint8_t type; + uint8_t padding; + uint16_t first_colour; + uint16_t n_colours; + struct rfb_colour_map_entry colours[0]; +} RFB_PACKED; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/meson.build new/neatvnc-0.8.0/meson.build --- old/neatvnc-0.7.2/meson.build 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/meson.build 2024-02-25 12:11:28.000000000 +0100 @@ -1,7 +1,7 @@ project( 'neatvnc', 'c', - version: '0.7.2', + version: '0.8.0', license: 'ISC', default_options: [ 'c_std=gnu11', @@ -13,7 +13,6 @@ host_system = host_machine.system() c_args = [ - '-DPROJECT_VERSION="@0@"'.format(meson.project_version()), '-D_GNU_SOURCE', '-fvisibility=hidden', '-DAML_UNSTABLE_API=1', @@ -27,17 +26,20 @@ c_args += '-DNDEBUG' endif +version = '"@0@"'.format(meson.project_version()) git = find_program('git', native: true, required: false) if git.found() - git_describe = run_command([git, 'describe', '--tags', '--long'], check: false) - git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD'], check: false) - if git_describe.returncode() == 0 and git_branch.returncode() == 0 - c_args += '-DGIT_VERSION="@0@ (@1@)"'.format( - git_describe.stdout().strip(), + git_commit = run_command([git, 'rev-parse', '--short', 'HEAD']) + git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD']) + if git_commit.returncode() == 0 and git_branch.returncode() == 0 + version = '"v@0@-@1@ (@2@)"'.format( + meson.project_version(), + git_commit.stdout().strip(), git_branch.stdout().strip(), ) endif endif +add_project_arguments('-DPROJECT_VERSION=@0@'.format(version), language: 'c') libdrm_inc = dependency('libdrm').partial_dependency(compile_args: true) @@ -153,6 +155,13 @@ config.set('ENABLE_WEBSOCKET', true) endif +if get_option('experimental') + if buildtype == 'release' + warning('Experimental features enabled in release build') + endif + config.set('ENABLE_EXPERIMENTAL', true) +endif + configure_file( output: 'config.h', configuration: config, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/meson_options.txt new/neatvnc-0.8.0/meson_options.txt --- old/neatvnc-0.7.2/meson_options.txt 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/meson_options.txt 2024-02-25 12:11:28.000000000 +0100 @@ -7,3 +7,4 @@ option('systemtap', type: 'boolean', value: false, description: 'Enable tracing using sdt') option('gbm', type: 'feature', value: 'auto', description: 'Enable GBM integration') option('h264', type: 'feature', value: 'auto', description: 'Enable open h264 encoding') +option('experimental', type: 'boolean', value: false, description: 'Enable experimental features') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/crypto-nettle.c new/neatvnc-0.8.0/src/crypto-nettle.c --- old/neatvnc-0.7.2/src/crypto-nettle.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/crypto-nettle.c 2024-02-25 12:11:28.000000000 +0100 @@ -658,7 +658,7 @@ void crypto_rsa_pub_key_modulus(const struct crypto_rsa_pub_key* key, uint8_t* dst, size_t dst_size) { - crypto_export(dst, dst_size, key->key.n); + crypto_export(dst, dst_size, key->key.n); } void crypto_rsa_pub_key_exponent(const struct crypto_rsa_pub_key* key, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/cursor.c new/neatvnc-0.8.0/src/cursor.c --- old/neatvnc-0.7.2/src/cursor.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/cursor.c 2024-02-25 12:11:28.000000000 +0100 @@ -112,8 +112,8 @@ for (uint32_t y = 0; y < height; ++y) { if (!extract_alpha_mask(dstdata + y * UDIV_UP(width, 8), - (uint32_t*)image->addr + y * image->stride, - image->fourcc_format, width)) + (uint32_t*)image->addr + y * image->stride, + image->fourcc_format, width)) goto failure; dst->len += UDIV_UP(width, 8); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/damage-refinery.c new/neatvnc-0.8.0/src/damage-refinery.c --- old/neatvnc-0.7.2/src/damage-refinery.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/damage-refinery.c 2024-02-25 12:11:28.000000000 +0100 @@ -133,12 +133,12 @@ } void damage_refine(struct damage_refinery* self, - struct pixman_region16* refined, + struct pixman_region16* refined, struct pixman_region16* hint, struct nvnc_fb* buffer) { assert(self->width == (uint32_t)buffer->width && - self->height == (uint32_t)buffer->height); + self->height == (uint32_t)buffer->height); nvnc_fb_map(buffer); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/enc-util.c new/neatvnc-0.8.0/src/enc-util.c --- old/neatvnc-0.7.2/src/enc-util.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/enc-util.c 2024-02-25 12:11:28.000000000 +0100 @@ -50,7 +50,7 @@ int n_rects = 0; struct pixman_box16* rects = pixman_region_rectangles(region, - &n_rects); + &n_rects); for (int i = 0; i < n_rects; ++i) { int width = rects[i].x2 - rects[i].x1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/fb.c new/neatvnc-0.8.0/src/fb.c --- old/neatvnc-0.7.2/src/fb.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/fb.c 2024-02-25 12:11:28.000000000 +0100 @@ -35,7 +35,7 @@ EXPORT struct nvnc_fb* nvnc_fb_new(uint16_t width, uint16_t height, - uint32_t fourcc_format, uint16_t stride) + uint32_t fourcc_format, uint16_t stride) { struct nvnc_fb* fb = calloc(1, sizeof(*fb)); if (!fb) @@ -66,7 +66,7 @@ EXPORT struct nvnc_fb* nvnc_fb_from_buffer(void* buffer, uint16_t width, uint16_t height, - uint32_t fourcc_format, int32_t stride) + uint32_t fourcc_format, int32_t stride) { struct nvnc_fb* fb = calloc(1, sizeof(*fb)); if (!fb) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/fb_pool.c new/neatvnc-0.8.0/src/fb_pool.c --- old/neatvnc-0.7.2/src/fb_pool.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/fb_pool.c 2024-02-25 12:11:28.000000000 +0100 @@ -165,7 +165,7 @@ } nvnc_fb_ref(fb); - + struct fbq_item* item = calloc(1, sizeof(*item)); assert(item); item->fb = fb; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/h264-encoder.c new/neatvnc-0.8.0/src/h264-encoder.c --- old/neatvnc-0.7.2/src/h264-encoder.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/h264-encoder.c 2024-02-25 12:11:28.000000000 +0100 @@ -328,7 +328,7 @@ c->sw_format = drm_to_av_pixel_format(self->format); c->width = self->width; c->height = self->height; - + if (av_hwframe_ctx_init(self->hw_frames_ctx) < 0) av_buffer_unref(&self->hw_frames_ctx); @@ -409,10 +409,18 @@ frame->hw_frames_ctx = av_buffer_ref(self->hw_frames_ctx); if (self->current_frame_is_keyframe) { +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 7, 100) + frame->flags |= AV_FRAME_FLAG_KEY; +#else frame->key_frame = 1; +#endif frame->pict_type = AV_PICTURE_TYPE_I; } else { +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 7, 100) + frame->flags &= ~AV_FRAME_FLAG_KEY; +#else frame->key_frame = 0; +#endif frame->pict_type = AV_PICTURE_TYPE_P; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/logging.c new/neatvnc-0.8.0/src/logging.c --- old/neatvnc-0.7.2/src/logging.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/logging.c 2024-02-25 12:11:28.000000000 +0100 @@ -25,6 +25,7 @@ #include <stdarg.h> #include <string.h> #include <ctype.h> +#include <threads.h> #ifdef HAVE_LIBAVUTIL #include <libavutil/avutil.h> @@ -32,10 +33,8 @@ #define EXPORT __attribute__((visibility("default"))) -static void default_logger(const struct nvnc_log_data* meta, - const char* message); - -static nvnc_log_fn log_fn = default_logger; +static nvnc_log_fn log_fn = nvnc_default_logger; +static thread_local nvnc_log_fn thread_local_log_fn = NULL; #ifndef NDEBUG static enum nvnc_log_level log_level = NVNC_LOG_DEBUG; @@ -45,6 +44,11 @@ static bool is_initialised = false; +static nvnc_log_fn get_log_fn(void) +{ + return thread_local_log_fn ? thread_local_log_fn : log_fn; +} + static char* trim_left(char* str) { while (isspace(*str)) @@ -100,14 +104,15 @@ if (meta->level <= log_level) { vsnprintf(message, sizeof(message), fmt, args); - log_fn(meta, trim(message)); + get_log_fn()(meta, trim(message)); } if (meta->level == NVNC_LOG_PANIC) abort(); } -static void default_logger(const struct nvnc_log_data* meta, +EXPORT +void nvnc_default_logger(const struct nvnc_log_data* meta, const char* message) { const char* level = log_level_to_string(meta->level); @@ -178,7 +183,13 @@ EXPORT void nvnc_set_log_fn(nvnc_log_fn fn) { - log_fn = fn; + log_fn = fn ? fn : nvnc_default_logger; +} + +EXPORT +void nvnc_set_log_fn_thread_local(nvnc_log_fn fn) +{ + thread_local_log_fn = fn; } EXPORT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/pixels.c new/neatvnc-0.8.0/src/pixels.c --- old/neatvnc-0.7.2/src/pixels.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/pixels.c 2024-02-25 12:11:28.000000000 +0100 @@ -19,6 +19,7 @@ #include <stdlib.h> #include <assert.h> #include <libdrm/drm_fourcc.h> +#include <math.h> #define POPCOUNT(x) __builtin_popcount(x) #define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) @@ -26,10 +27,10 @@ #define STR(s) #s static void pixel32_to_cpixel(uint8_t* restrict dst, - const struct rfb_pixel_format* dst_fmt, - const uint32_t* restrict src, - const struct rfb_pixel_format* src_fmt, - size_t bytes_per_cpixel, size_t len) + const struct rfb_pixel_format* dst_fmt, + const uint32_t* restrict src, + const struct rfb_pixel_format* src_fmt, + size_t bytes_per_cpixel, size_t len) { assert(src_fmt->true_colour_flag); assert(src_fmt->depth <= 32); @@ -152,10 +153,10 @@ } void pixel_to_cpixel(uint8_t* restrict dst, - const struct rfb_pixel_format* dst_fmt, - const uint8_t* restrict src, - const struct rfb_pixel_format* src_fmt, - size_t bytes_per_cpixel, size_t len) + const struct rfb_pixel_format* dst_fmt, + const uint8_t* restrict src, + const struct rfb_pixel_format* src_fmt, + size_t bytes_per_cpixel, size_t len) { if (src_fmt->bits_per_pixel == 32) { pixel32_to_cpixel(dst, dst_fmt, (uint32_t*)src, src_fmt, bytes_per_cpixel, len); @@ -636,9 +637,6 @@ // Not exact, but close enough for debugging const char* rfb_pixfmt_to_string(const struct rfb_pixel_format* fmt) { - if (!(fmt->red_max == fmt->green_max && fmt->red_max == fmt->blue_max)) - goto failure; - uint32_t profile = (fmt->red_shift << 16) | (fmt->green_shift << 8) | (fmt->blue_shift); @@ -657,9 +655,25 @@ CASE(8, 4, 0): return "XRGB4444"; CASE(0, 4, 8): return "XBGR4444"; CASE(11, 5, 0): return "RGB565"; + CASE(5, 2, 0): return "RGB332"; + CASE(0, 2, 5): return "RGB332"; + CASE(4, 2, 0): return "RGB222"; + CASE(0, 2, 4): return "BGR222"; #undef CASE } - -failure: return "UNKNOWN"; } + +void make_rgb332_pal8_map(struct rfb_set_colour_map_entries_msg* msg) +{ + msg->type = RFB_SERVER_TO_CLIENT_SET_COLOUR_MAP_ENTRIES; + msg->padding = 0; + msg->first_colour = htons(0); + msg->n_colours = htons(256); + + for (unsigned int i = 0; i < 256; ++i) { + msg->colours[i].r = htons(round(65535.0 / 7.0 * ((i >> 5) & 7))); + msg->colours[i].g = htons(round(65535.0 / 7.0 * ((i >> 2) & 7))); + msg->colours[i].b = htons(round(65535.0 / 3.0 * (i & 3))); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/raw-encoding.c new/neatvnc-0.8.0/src/raw-encoding.c --- old/neatvnc-0.7.2/src/raw-encoding.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/raw-encoding.c 2024-02-25 12:11:28.000000000 +0100 @@ -54,10 +54,10 @@ } static int raw_encode_box(struct raw_encoder_work* ctx, struct vec* dst, - const struct rfb_pixel_format* dst_fmt, - const struct nvnc_fb* fb, - const struct rfb_pixel_format* src_fmt, int x_start, - int y_start, int stride, int width, int height) + const struct rfb_pixel_format* dst_fmt, + const struct nvnc_fb* fb, + const struct rfb_pixel_format* src_fmt, int x_start, + int y_start, int stride, int width, int height) { uint16_t x_pos = ctx->x_pos; uint16_t y_pos = ctx->y_pos; @@ -84,8 +84,8 @@ for (int y = y_start; y < y_start + height; ++y) { pixel_to_cpixel(d + dst->len, dst_fmt, - b + xoff + y * src_stride, src_fmt, - bpp, width); + b + xoff + y * src_stride, src_fmt, + bpp, width); dst->len += width * bpp; } @@ -117,7 +117,7 @@ int box_height = box[i].y2 - y; rc = raw_encode_box(ctx, dst, dst_fmt, src, src_fmt, x, y, - src->stride, box_width, box_height); + src->stride, box_width, box_height); if (rc < 0) return -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/server.c new/neatvnc-0.8.0/src/server.c --- old/neatvnc-0.7.2/src/server.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/server.c 2024-02-25 12:11:28.000000000 +0100 @@ -77,17 +77,16 @@ static int send_desktop_resize(struct nvnc_client* client, struct nvnc_fb* fb); static bool send_ext_support_frame(struct nvnc_client* client); static enum rfb_encodings choose_frame_encoding(struct nvnc_client* client, - struct nvnc_fb*); + const struct nvnc_fb*); static void on_encode_frame_done(struct encoder*, struct rcbuf*, uint64_t pts); static bool client_has_encoding(const struct nvnc_client* client, enum rfb_encodings encoding); static void process_fb_update_requests(struct nvnc_client* client); static void sockaddr_to_string(char* dst, size_t sz, const struct sockaddr* addr); +static const char* encoding_to_string(enum rfb_encodings encoding); -#if defined(GIT_VERSION) -EXPORT const char nvnc_version[] = GIT_VERSION; -#elif defined(PROJECT_VERSION) +#if defined(PROJECT_VERSION) EXPORT const char nvnc_version[] = PROJECT_VERSION; #else EXPORT const char nvnc_version[] = "UNKNOWN"; @@ -211,7 +210,7 @@ size_t len = 1 + sizeof(*reason) + strlen(reason_string); stream_write(client->net_stream, buffer, len, close_after_write, - client); + client); return 0; } @@ -270,8 +269,15 @@ } static int security_handshake_failed(struct nvnc_client* client, - const char* reason_string) + const char* username, const char* reason_string) { + if (username) + nvnc_log(NVNC_LOG_INFO, "Security handshake failed for \"%s\": %s", + username, reason_string); + else + nvnc_log(NVNC_LOG_INFO, "Security handshake: %s", + username, reason_string); + char buffer[256]; client->state = VNC_CLIENT_STATE_ERROR; @@ -287,16 +293,23 @@ size_t len = sizeof(*result) + sizeof(*reason) + strlen(reason_string); stream_write(client->net_stream, buffer, len, close_after_write, - client); + client); return 0; } -static int security_handshake_ok(struct nvnc_client* client) +static int security_handshake_ok(struct nvnc_client* client, const char* username) { + if (username) { + nvnc_log(NVNC_LOG_INFO, "User \"%s\" authenticated", username); + + strncpy(client->username, username, sizeof(client->username)); + client->username[sizeof(client->username) - 1] = '\0'; + } + uint32_t result = htonl(RFB_SECURITY_HANDSHAKE_OK); return stream_write(client->net_stream, &result, sizeof(result), NULL, - NULL); + NULL); } #ifdef ENABLE_TLS @@ -308,7 +321,7 @@ static int send_byte_and_close(struct nvnc_client* client, uint8_t value) { return stream_write(client->net_stream, &value, 1, close_after_write, - client); + client); } static int vencrypt_send_version(struct nvnc_client* client) @@ -330,7 +343,8 @@ return 0; if (msg->major != 0 || msg->minor != 2) { - security_handshake_failed(client, "Unsupported VeNCrypt version"); + security_handshake_failed(client, NULL, + "Unsupported VeNCrypt version"); return sizeof(*msg); } @@ -399,16 +413,12 @@ username[MIN(ulen, sizeof(username) - 1)] = '\0'; password[MIN(plen, sizeof(password) - 1)] = '\0'; - strncpy(client->username, username, sizeof(client->username)); - client->username[sizeof(client->username) - 1] = '\0'; - if (server->auth_fn(username, password, server->auth_ud)) { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" authenticated", username); - security_handshake_ok(client); + security_handshake_ok(client, username); client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT; } else { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" rejected", username); - security_handshake_failed(client, "Invalid username or password"); + security_handshake_failed(client, username, + "Invalid username or password"); } return sizeof(*msg) + ulen + plen; @@ -492,12 +502,11 @@ crypto_cipher_del(cipher); if (server->auth_fn(username, password, server->auth_ud)) { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" authenticated", username); - security_handshake_ok(client); + security_handshake_ok(client, username); client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT; } else { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" rejected", username); - security_handshake_failed(client, "Invalid username or password"); + security_handshake_failed(client, username, + "Invalid username or password"); } return sizeof(*msg) + key_len; @@ -769,12 +778,11 @@ password[password_len] = '\0'; if (server->auth_fn(username, password, server->auth_ud)) { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" authenticated", username); - security_handshake_ok(client); + security_handshake_ok(client, username); client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT; } else { - nvnc_log(NVNC_LOG_INFO, "User \"%s\" rejected", username); - security_handshake_failed(client, "Invalid username or password"); + security_handshake_failed(client, username, + "Invalid username or password"); } return 2 + username_len + password_len; @@ -792,7 +800,7 @@ switch (type) { case RFB_SECURITY_TYPE_NONE: - security_handshake_ok(client); + security_handshake_ok(client, NULL); client->state = VNC_CLIENT_STATE_WAITING_FOR_INIT; break; #ifdef ENABLE_TLS @@ -822,7 +830,8 @@ break; #endif default: - security_handshake_failed(client, "Unsupported security type"); + security_handshake_failed(client, NULL, + "Unsupported security type"); break; } @@ -915,6 +924,30 @@ return sizeof(shared_flag); } +static int cook_pixel_map(struct nvnc_client* client) +{ + struct rfb_pixel_format* fmt = &client->pixfmt; + + // We'll just pretend that this is rgb332 + fmt->true_colour_flag = true; + fmt->big_endian_flag = false; + fmt->bits_per_pixel = 8; + fmt->depth = 8; + fmt->red_max = 7; + fmt->green_max = 7; + fmt->blue_max = 3; + fmt->red_shift = 5; + fmt->green_shift = 2; + fmt->blue_shift = 0; + + uint8_t buf[sizeof(struct rfb_set_colour_map_entries_msg) + + 256 * sizeof(struct rfb_colour_map_entry)]; + struct rfb_set_colour_map_entries_msg* msg = + (struct rfb_set_colour_map_entries_msg*)buf; + make_rgb332_pal8_map(msg); + return stream_write(client->net_stream, buf, sizeof(buf), NULL, NULL); +} + static int on_client_set_pixel_format(struct nvnc_client* client) { if (client->buffer_len - client->buffer_index < @@ -925,23 +958,42 @@ (struct rfb_pixel_format*)(client->msg_buffer + client->buffer_index + 4); - if (!fmt->true_colour_flag) { - /* We don't really know what to do with color maps right now */ - nvnc_client_close(client); - return 0; + if (fmt->true_colour_flag) { + nvnc_log(NVNC_LOG_DEBUG, "Using color palette for client %p", + client); + fmt->red_max = ntohs(fmt->red_max); + fmt->green_max = ntohs(fmt->green_max); + fmt->blue_max = ntohs(fmt->blue_max); + memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt)); + } else { + nvnc_log(NVNC_LOG_DEBUG, "Using color palette for client %p", + client); + cook_pixel_map(client); } - fmt->red_max = ntohs(fmt->red_max); - fmt->green_max = ntohs(fmt->green_max); - fmt->blue_max = ntohs(fmt->blue_max); - - memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt)); - client->has_pixfmt = true; + client->formats_changed = true; + + nvnc_log(NVNC_LOG_DEBUG, "Client %p chose pixel format: %s", client, + rfb_pixfmt_to_string(&client->pixfmt)); return 4 + sizeof(struct rfb_pixel_format); } +static void encodings_to_string_list(char* dst, size_t len, + enum rfb_encodings* encodings, size_t n) +{ + size_t off = 0; + + if (n > 0) + off += snprintf(dst, len, "%s", + encoding_to_string(encodings[0])); + + for (size_t i = 1; i < n; ++i) + off += snprintf(dst + off, len - off, ",%s", + encoding_to_string(encodings[i])); +} + static int on_client_set_encodings(struct nvnc_client* client) { struct rfb_client_set_encodings_msg* msg = @@ -973,10 +1025,16 @@ case RFB_ENCODING_DESKTOPSIZE: case RFB_ENCODING_EXTENDEDDESKTOPSIZE: case RFB_ENCODING_QEMU_EXT_KEY_EVENT: +#ifdef ENABLE_EXPERIMENTAL + case RFB_ENCODING_PTS: + case RFB_ENCODING_NTP: +#endif client->encodings[n++] = encoding; +#ifndef ENABLE_EXPERIMENTAL case RFB_ENCODING_PTS: case RFB_ENCODING_NTP: ; +#endif } if (RFB_ENCODING_JPEG_LOWQ <= encoding && @@ -984,7 +1042,14 @@ client->quality = encoding - RFB_ENCODING_JPEG_LOWQ; } + char encoding_list[256] = {}; + encodings_to_string_list(encoding_list, sizeof(encoding_list), + client->encodings, n); + nvnc_log(NVNC_LOG_DEBUG, "Client %p set encodings: %s", client, + encoding_list); + client->n_encodings = n; + client->formats_changed = true; return sizeof(*msg) + 4 * n_encodings; } @@ -1041,14 +1106,77 @@ { switch (encoding) { case RFB_ENCODING_RAW: return "raw"; + case RFB_ENCODING_COPYRECT: return "copyrect"; + case RFB_ENCODING_RRE: return "rre"; + case RFB_ENCODING_HEXTILE: return "hextile"; case RFB_ENCODING_TIGHT: return "tight"; + case RFB_ENCODING_TRLE: return "trle"; case RFB_ENCODING_ZRLE: return "zrle"; case RFB_ENCODING_OPEN_H264: return "open-h264"; + case RFB_ENCODING_CURSOR: return "cursor"; + case RFB_ENCODING_DESKTOPSIZE: return "desktop-size"; + case RFB_ENCODING_EXTENDEDDESKTOPSIZE: return "extended-desktop-size"; + case RFB_ENCODING_QEMU_EXT_KEY_EVENT: return "qemu-extended-key-event"; + case RFB_ENCODING_PTS: return "pts"; + case RFB_ENCODING_NTP: return "ntp"; + } + return "UNKNOWN"; +} + +static bool ensure_encoder(struct nvnc_client* client, const struct nvnc_fb *fb) +{ + struct nvnc* server = client->server; + + enum rfb_encodings encoding = choose_frame_encoding(client, fb); + if (client->encoder && encoding == encoder_get_type(client->encoder)) + return true; + + int width = server->display->buffer->width; + int height = server->display->buffer->height; + if (client->encoder) { + server->n_damage_clients -= !(client->encoder->impl->flags & + ENCODER_IMPL_FLAG_IGNORES_DAMAGE); + client->encoder->on_done = NULL; + } + 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); break; } - return "UNKNOWN"; + if (!client->encoder) { + nvnc_log(NVNC_LOG_ERROR, "Failed to allocate new encoder"); + return false; + } + + server->n_damage_clients += !(client->encoder->impl->flags & + ENCODER_IMPL_FLAG_IGNORES_DAMAGE); + + nvnc_log(NVNC_LOG_INFO, "Choosing %s encoding for client %p", + encoding_to_string(encoding), client); + + return true; } static void process_fb_update_requests(struct nvnc_client* client) @@ -1100,63 +1228,17 @@ if (!pixman_region_not_empty(&client->damage)) return; - DTRACE_PROBE1(neatvnc, update_fb_start, client); - - enum rfb_encodings encoding = choose_frame_encoding(client, fb); - if (!client->encoder || encoding != encoder_get_type(client->encoder)) { - int width = server->display->buffer->width; - int height = server->display->buffer->height; - if (client->encoder) { - server->n_damage_clients -= - !(client->encoder->impl->flags & - ENCODER_IMPL_FLAG_IGNORES_DAMAGE); - client->encoder->on_done = NULL; - } - 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); - break; - } - - if (!client->encoder) { - nvnc_log(NVNC_LOG_ERROR, "Failed to allocate new encoder"); - return; - } - - server->n_damage_clients += - !(client->encoder->impl->flags & - ENCODER_IMPL_FLAG_IGNORES_DAMAGE); + if (!ensure_encoder(client, fb)) + return; - nvnc_log(NVNC_LOG_INFO, "Choosing %s encoding for client %p", - encoding_to_string(encoding), client); - } + DTRACE_PROBE1(neatvnc, update_fb_start, client); /* The client's damage is exchanged for an empty one */ struct pixman_region16 damage = client->damage; pixman_region_init(&client->damage); client->is_updating = true; + client->formats_changed = false; client->current_fb = fb; nvnc_fb_hold(fb); nvnc_fb_ref(fb); @@ -1178,6 +1260,7 @@ nvnc_log(NVNC_LOG_ERROR, "Failed to encode current frame"); client_unref(client); client->is_updating = false; + client->formats_changed = false; assert(client->current_fb); nvnc_fb_release(client->current_fb); nvnc_fb_unref(client->current_fb); @@ -1211,7 +1294,7 @@ */ if (!incremental) { pixman_region_union_rect(&client->damage, &client->damage, x, y, - width, height); + width, height); if (client->encoder) encoder_request_key_frame(client->encoder); @@ -1294,7 +1377,7 @@ } nvnc_log(NVNC_LOG_WARNING, "Got uninterpretable qemu message from client: %p (ref %d)", - client, client->ref); + client, client->ref); nvnc_client_close(client); return 0; } @@ -1353,7 +1436,7 @@ /* Messages greater than this size are unsupported */ if (length > max_length) { nvnc_log(NVNC_LOG_ERROR, "Copied text length (%d) is greater than max supported length (%d)", - length, max_length); + length, max_length); nvnc_client_close(client); return 0; } @@ -1404,7 +1487,7 @@ if (n_read < 0) { if (errno != EAGAIN) { nvnc_log(NVNC_LOG_INFO, "Client connection error: %p (ref %d)", - client, client->ref); + client, client->ref); nvnc_client_close(client); } @@ -1518,7 +1601,7 @@ msg->number_of_screens, msg->screens); send_extended_desktop_size(client, RFB_RESIZE_INITIATOR_THIS_CLIENT, - status); + status); return sizeof(*msg) + msg->number_of_screens * sizeof(struct rfb_screen); } @@ -1603,7 +1686,7 @@ } nvnc_log(NVNC_LOG_WARNING, "Got uninterpretable message from client: %p (ref %d)", - client, client->ref); + client, client->ref); nvnc_client_close(client); return 0; } @@ -1676,7 +1759,7 @@ if (n_read < 0) { if (errno != EAGAIN) { nvnc_log(NVNC_LOG_INFO, "Client connection error: %p (ref %d)", - client, client->ref); + client, client->ref); nvnc_client_close(client); } @@ -1698,30 +1781,10 @@ client->buffer_len -= client->buffer_index; memmove(client->msg_buffer, client->msg_buffer + client->buffer_index, - client->buffer_len); + client->buffer_len); client->buffer_index = 0; } -// TODO: Remove this when nvnc_client_get_hostname gets renamed. -static void record_peer_hostname(int fd, struct nvnc_client* client) -{ - struct sockaddr_storage storage; - struct sockaddr* peer = (struct sockaddr*)&storage; - socklen_t peerlen = sizeof(storage); - if (getpeername(fd, peer, &peerlen) < 0) { - nvnc_log(NVNC_LOG_WARNING, "Failed to get address for client: %m"); - return; - } - - if (peer->sa_family == AF_UNIX) { - snprintf(client->hostname, sizeof(client->hostname), - "unix domain socket"); - } else { - sockaddr_to_string(client->hostname, sizeof(client->hostname), - peer); - } -} - static void on_connection(void* obj) { struct nvnc* server = aml_get_userdata(obj); @@ -1743,8 +1806,6 @@ int one = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); - record_peer_hostname(fd, client); - #ifdef ENABLE_WEBSOCKET if (server->socket_type == NVNC__SOCKET_WEBSOCKET) { @@ -1779,7 +1840,14 @@ client->state = VNC_CLIENT_STATE_WAITING_FOR_VERSION; - nvnc_log(NVNC_LOG_INFO, "New client connection from %s: %p (ref %d)", client->hostname, client, client->ref); + char ip_address[256]; + struct sockaddr_storage addr; + socklen_t addrlen = sizeof(addr); + nvnc_client_get_address(client, (struct sockaddr*)&addr, &addrlen); + sockaddr_to_string(ip_address, sizeof(ip_address), + (struct sockaddr*)&addr); + nvnc_log(NVNC_LOG_INFO, "New client connection from %s: %p (ref %d)", + ip_address, client, client->ref); return; @@ -2032,6 +2100,8 @@ static void complete_fb_update(struct nvnc_client* client) { + if (!client->is_updating) + return; client->is_updating = false; assert(client->current_fb); nvnc_fb_release(client->current_fb); @@ -2049,7 +2119,7 @@ } static enum rfb_encodings choose_frame_encoding(struct nvnc_client* client, - struct nvnc_fb* fb) + const struct nvnc_fb* fb) { for (size_t i = 0; i < client->n_encodings; ++i) switch (client->encodings[i]) { @@ -2089,6 +2159,17 @@ if (client->net_stream->state == STREAM_STATE_CLOSED) goto complete; + if (client->formats_changed) { + /* Client has requested new pixel format or encoding in the + * meantime, so it probably won't know what to do with this + * frame. Pending requests get incremented because this one is + * dropped. + */ + nvnc_log(NVNC_LOG_DEBUG, "Client changed pixel format or encoding with in-flight buffer"); + client->n_pending_requests++; + goto complete; + } + DTRACE_PROBE2(neatvnc, send_fb_start, client, pts); n_rects += will_send_pts(client, pts) ? 1 : 0; struct rfb_server_fb_update_msg update_msg = { @@ -2104,7 +2185,7 @@ rcbuf_ref(payload); if (stream_send(client->net_stream, payload, - on_write_frame_done, client) < 0) + on_write_frame_done, client) < 0) goto complete; DTRACE_PROBE2(neatvnc, send_fb_done, client, pts); @@ -2204,7 +2285,7 @@ LIST_FOREACH(client, &self->clients, link) if (client->net_stream->state != STREAM_STATE_CLOSED) pixman_region_union(&client->damage, &client->damage, - (struct pixman_region16*)damage); + (struct pixman_region16*)damage); LIST_FOREACH(client, &self->clients, link) process_fb_update_requests(client); @@ -2301,13 +2382,10 @@ return client->server; } -// TODO: This function should be renamed to nvnc_client_get_address and it -// should return the sockaddr. EXPORT -const char* nvnc_client_get_hostname(const struct nvnc_client* client) { - if (client->hostname[0] == '\0') - return NULL; - return client->hostname; +int nvnc_client_get_address(const struct nvnc_client* client, + struct sockaddr* restrict addr, socklen_t* restrict addrlen) { + return getpeername(client->net_stream->fd, addr, addrlen); } EXPORT @@ -2366,7 +2444,7 @@ EXPORT int nvnc_set_tls_creds(struct nvnc* self, const char* privkey_path, - const char* cert_path) + const char* cert_path) { #ifdef ENABLE_TLS if (self->tls_creds) @@ -2378,22 +2456,22 @@ int rc = gnutls_global_init(); if (rc != GNUTLS_E_SUCCESS) { nvnc_log(NVNC_LOG_ERROR, "GnuTLS: Failed to initialise: %s", - gnutls_strerror(rc)); + gnutls_strerror(rc)); return -1; } rc = gnutls_certificate_allocate_credentials(&self->tls_creds); if (rc != GNUTLS_E_SUCCESS) { nvnc_log(NVNC_LOG_ERROR, "GnuTLS: Failed to allocate credentials: %s", - gnutls_strerror(rc)); + gnutls_strerror(rc)); goto cert_alloc_failure; } rc = gnutls_certificate_set_x509_key_file( - self->tls_creds, cert_path, privkey_path, GNUTLS_X509_FMT_PEM); + self->tls_creds, cert_path, privkey_path, GNUTLS_X509_FMT_PEM); if (rc != GNUTLS_E_SUCCESS) { nvnc_log(NVNC_LOG_ERROR, "GnuTLS: Failed to load credentials: %s", - gnutls_strerror(rc)); + gnutls_strerror(rc)); goto cert_set_failure; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/stream-gnutls.c new/neatvnc-0.8.0/src/stream-gnutls.c --- old/neatvnc-0.7.2/src/stream-gnutls.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/stream-gnutls.c 2024-02-25 12:11:28.000000000 +0100 @@ -169,7 +169,7 @@ } static int stream_gnutls_send(struct stream* self, struct rcbuf* payload, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { if (self->state == STREAM_STATE_CLOSED) return -1; @@ -266,7 +266,7 @@ goto failure; rc = gnutls_credentials_set(self->session, GNUTLS_CRD_CERTIFICATE, - context); + context); if (rc != GNUTLS_E_SUCCESS) goto failure; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/stream-rsa-aes.c new/neatvnc-0.8.0/src/stream-rsa-aes.c --- old/neatvnc-0.7.2/src/stream-rsa-aes.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/stream-rsa-aes.c 2024-02-25 12:11:28.000000000 +0100 @@ -148,7 +148,7 @@ } static int stream_rsa_aes_send(struct stream* base, struct rcbuf* payload, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { struct stream_rsa_aes* self = (struct stream_rsa_aes*)base; size_t n_msg = UDIV_UP(payload->size, RSA_AES_BUFFER_SIZE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/stream-tcp.c new/neatvnc-0.8.0/src/stream-tcp.c --- old/neatvnc-0.7.2/src/stream-tcp.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/stream-tcp.c 2024-02-25 12:11:28.000000000 +0100 @@ -208,7 +208,7 @@ } int stream_tcp_send(struct stream* self, struct rcbuf* payload, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { if (self->state == STREAM_STATE_CLOSED) return -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/stream-ws.c new/neatvnc-0.8.0/src/stream-ws.c --- old/neatvnc-0.7.2/src/stream-ws.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/stream-ws.c 2024-02-25 12:11:28.000000000 +0100 @@ -145,7 +145,7 @@ } if (!ws_parse_frame_header(&ws->header, ws->read_buffer, - ws->read_index)) { + ws->read_index)) { return 0; } @@ -230,7 +230,7 @@ } static int stream_ws_send(struct stream* self, struct rcbuf* payload, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { struct stream_ws* ws = (struct stream_ws*)self; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/stream.c new/neatvnc-0.8.0/src/stream.c --- old/neatvnc-0.7.2/src/stream.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/stream.c 2024-02-25 12:11:28.000000000 +0100 @@ -31,7 +31,7 @@ } int stream_send(struct stream* self, struct rcbuf* payload, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { assert(self->impl && self->impl->send); return self->impl->send(self, payload, on_done, userdata); @@ -44,7 +44,7 @@ } int stream_write(struct stream* self, const void* payload, size_t len, - stream_req_fn on_done, void* userdata) + stream_req_fn on_done, void* userdata) { struct rcbuf* buf = rcbuf_from_mem(payload, len); return buf ? stream_send(self, buf, on_done, userdata) : -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/tight.c new/neatvnc-0.8.0/src/tight.c --- old/neatvnc-0.7.2/src/tight.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/tight.c 2024-02-25 12:11:28.000000000 +0100 @@ -119,11 +119,11 @@ static int tight_encoder_init_stream(z_stream* zs) { int rc = deflateInit2(zs, - /* compression level: */ 1, - /* method: */ Z_DEFLATED, - /* window bits: */ 15, - /* mem level: */ 9, - /* strategy: */ Z_DEFAULT_STRATEGY); + /* compression level: */ 1, + /* method: */ Z_DEFLATED, + /* window bits: */ 15, + /* mem level: */ 9, + /* strategy: */ Z_DEFAULT_STRATEGY); return rc == Z_OK ? 0 : -1; } @@ -261,7 +261,7 @@ } static int tight_deflate(struct tight_tile* tile, void* src, - size_t len, z_stream* zs, bool flush) + size_t len, z_stream* zs, bool flush) { zs->next_in = src; zs->avail_in = len; @@ -310,7 +310,7 @@ for (uint32_t y = y_start; y < y_start + height; ++y) { uint8_t* img = addr + xoff + y * byte_stride; pixel_to_cpixel(row, &cfmt, img, &self->sfmt, - bytes_per_cpixel, width); + bytes_per_cpixel, width); // TODO What to do if the buffer fills up? if (tight_deflate(tile, row, bytes_per_cpixel * width, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/ws-handshake.c new/neatvnc-0.8.0/src/ws-handshake.c --- old/neatvnc-0.7.2/src/ws-handshake.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/ws-handshake.c 2024-02-25 12:11:28.000000000 +0100 @@ -88,15 +88,15 @@ base64_encode(response, hash, sizeof(hash)); size_t len = snprintf(output, output_maxlen, - "HTTP/1.1 101 Switching Protocols\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: %s\r\n" - "%s%s" - "\r\n", - response, - have_protocols ? "Sec-WebSocket-Protocol: char\r\n" : "", - have_versions ? "Sec-WebSocket-Version: 13\r\n" : ""); + "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: %s\r\n" + "%s%s" + "\r\n", + response, + have_protocols ? "Sec-WebSocket-Protocol: char\r\n" : "", + have_versions ? "Sec-WebSocket-Version: 13\r\n" : ""); ssize_t header_len = req.header_length; ok = len < output_maxlen; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/src/zrle.c new/neatvnc-0.8.0/src/zrle.c --- old/neatvnc-0.7.2/src/zrle.c 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/src/zrle.c 2024-02-25 12:11:28.000000000 +0100 @@ -62,7 +62,7 @@ } static inline int find_colour_in_palette(uint8_t* palette, int len, - const uint8_t* colour, int bpp) + const uint8_t* colour, int bpp) { for (int i = 0; i < len; ++i) if (memcmp(palette + i * bpp, colour, bpp) == 0) @@ -72,7 +72,7 @@ } static int zrle_get_tile_palette(uint8_t* palette, const uint8_t* src, - const int src_bpp, size_t length) + const int src_bpp, size_t length) { int n = 0; @@ -94,16 +94,16 @@ } static void zrle_encode_unichrome_tile(struct vec* dst, - const struct rfb_pixel_format* dst_fmt, - uint8_t* colour, - const struct rfb_pixel_format* src_fmt) + const struct rfb_pixel_format* dst_fmt, + uint8_t* colour, + const struct rfb_pixel_format* src_fmt) { int bytes_per_cpixel = calc_bytes_per_cpixel(dst_fmt); vec_fast_append_8(dst, 1); pixel_to_cpixel(((uint8_t*)dst->data) + 1, dst_fmt, colour, src_fmt, - bytes_per_cpixel, 1); + bytes_per_cpixel, 1); dst->len += bytes_per_cpixel; } @@ -126,18 +126,18 @@ } static void zrle_encode_packed_tile(struct vec* dst, - const struct rfb_pixel_format* dst_fmt, - const uint8_t* src, - const struct rfb_pixel_format* src_fmt, - size_t length, uint8_t* palette, - int palette_size) + const struct rfb_pixel_format* dst_fmt, + const uint8_t* src, + const struct rfb_pixel_format* src_fmt, + size_t length, uint8_t* palette, + int palette_size) { int bytes_per_cpixel = calc_bytes_per_cpixel(dst_fmt); int src_bpp = src_fmt->bits_per_pixel / 8; uint8_t cpalette[16 * 3]; pixel_to_cpixel(cpalette, dst_fmt, palette, src_fmt, - bytes_per_cpixel, palette_size); + bytes_per_cpixel, palette_size); vec_fast_append_8(dst, 128 | palette_size); @@ -159,13 +159,13 @@ if (run_length > 0) { index = find_colour_in_palette(palette, palette_size, - src + (length - 1) * src_bpp, src_bpp); + src + (length - 1) * src_bpp, src_bpp); encode_run_length(dst, index, run_length); } } static void zrle_copy_tile(uint8_t* tile, const uint8_t* src, int src_bpp, - int stride, int width, int height) + int stride, int width, int height) { int byte_stride = stride * src_bpp; for (int y = 0; y < height; ++y) @@ -173,10 +173,10 @@ } static void zrle_encode_tile(struct vec* dst, - const struct rfb_pixel_format* dst_fmt, - const uint8_t* src, - const struct rfb_pixel_format* src_fmt, - size_t length) + const struct rfb_pixel_format* dst_fmt, + const uint8_t* src, + const struct rfb_pixel_format* src_fmt, + size_t length) { int bytes_per_cpixel = calc_bytes_per_cpixel(dst_fmt); int src_bpp = src_fmt->bits_per_pixel / 8; @@ -192,20 +192,20 @@ if (palette_size > 1) { zrle_encode_packed_tile(dst, dst_fmt, src, src_fmt, length, - palette, palette_size); + palette, palette_size); return; } vec_fast_append_8(dst, 0); pixel_to_cpixel(((uint8_t*)dst->data) + 1, dst_fmt, (uint8_t*)src, src_fmt, - bytes_per_cpixel, length); + bytes_per_cpixel, length); dst->len += bytes_per_cpixel * length; } static int zrle_deflate(struct vec* dst, const struct vec* src, z_stream* zs, - bool flush) + bool flush) { zs->next_in = src->data; zs->avail_in = src->len; @@ -230,10 +230,10 @@ } static int zrle_encode_box(struct zrle_encoder* self, struct vec* out, - const struct rfb_pixel_format* dst_fmt, - const struct nvnc_fb* fb, - const struct rfb_pixel_format* src_fmt, int x, int y, - int stride, int width, int height, z_stream* zs) + const struct rfb_pixel_format* dst_fmt, + const struct nvnc_fb* fb, + const struct rfb_pixel_format* src_fmt, int x, int y, + int stride, int width, int height, z_stream* zs) { int r = -1; int bytes_per_cpixel = calc_bytes_per_cpixel(dst_fmt); @@ -275,11 +275,11 @@ int x_off = (x + tile_x) * src_bpp; zrle_copy_tile(tile, - ((uint8_t*)fb->addr) + x_off + y_off, src_bpp, - stride, tile_width, tile_height); + ((uint8_t*)fb->addr) + x_off + y_off, src_bpp, + stride, tile_width, tile_height); zrle_encode_tile(&in, dst_fmt, tile, src_fmt, - tile_width * tile_height); + tile_width * tile_height); r = zrle_deflate(out, &in, zs, i == n_tiles - 1); if (r < 0) @@ -323,7 +323,7 @@ int box_height = box[i].y2 - y; rc = zrle_encode_box(self, dst, dst_fmt, src, src_fmt, x, y, - src->stride, box_width, box_height, zs); + src->stride, box_width, box_height, zs); if (rc < 0) return -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/neatvnc-0.7.2/test/meson.build new/neatvnc-0.8.0/test/meson.build --- old/neatvnc-0.7.2/test/meson.build 2024-02-02 23:42:16.000000000 +0100 +++ new/neatvnc-0.8.0/test/meson.build 2024-02-25 12:11:28.000000000 +0100 @@ -7,6 +7,7 @@ dependencies: [ pixman, libdrm_inc, + libm, ], ) test('pixels', pixels)