diff --git a/examples/draw.c b/examples/draw.c index d888487..0b438e3 100644 --- a/examples/draw.c +++ b/examples/draw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 - 2021 Andri Yngvason + * Copyright (c) 2019 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -281,7 +281,7 @@ int main(int argc, char* argv[]) struct nvnc_fb* cursor = create_cursor(); assert(cursor); - nvnc_set_cursor(server, cursor, 0, 0, NULL); + nvnc_set_cursor(server, cursor, 0, 0, 32, 32); nvnc_fb_unref(cursor); struct aml_signal* sig = aml_signal_new(SIGINT, on_sigint, NULL, NULL); diff --git a/include/common.h b/include/common.h index 7c3dafc..a5184e6 100644 --- a/include/common.h +++ b/include/common.h @@ -110,7 +110,8 @@ struct nvnc { struct nvnc_display* display; struct { struct nvnc_fb* buffer; - uint32_t x_hotspot, y_hotspot; + uint32_t width, height; + uint32_t hotspot_x, hotspot_y; } cursor; uint32_t cursor_seq; diff --git a/include/cursor.h b/include/cursor.h index 2019341..1560be2 100644 --- a/include/cursor.h +++ b/include/cursor.h @@ -16,9 +16,12 @@ #pragma once +#include + struct vec; struct nvnc_fb; struct rfb_pixel_format; int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, - struct nvnc_fb* image, int x_hotspot, int y_hotspot); + struct nvnc_fb* image, uint32_t width, uint32_t height, + uint32_t x_hotspot, uint32_t y_hotspot); diff --git a/include/neatvnc.h b/include/neatvnc.h index 3b6e99e..8899eda 100644 --- a/include/neatvnc.h +++ b/include/neatvnc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 - 2021 Andri Yngvason + * Copyright (c) 2019 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -142,5 +142,5 @@ void nvnc_display_feed_buffer(struct nvnc_display*, struct nvnc_fb*, void nvnc_send_cut_text(struct nvnc*, const char* text, uint32_t len); -void nvnc_set_cursor(struct nvnc*, struct nvnc_fb*, uint16_t x_hotspot, - uint16_t y_hotspot, struct pixman_region16* damage); +void nvnc_set_cursor(struct nvnc*, struct nvnc_fb*, uint16_t width, + uint16_t height, uint16_t hotspot_x, uint16_t hotspot_y); diff --git a/src/cursor.c b/src/cursor.c index 085cd08..c330224 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -29,12 +29,16 @@ #define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, - struct nvnc_fb* image, int x_hotspot, int y_hotspot) + struct nvnc_fb* image, uint32_t width, uint32_t height, + uint32_t hotspot_x, uint32_t hotspot_y) { // TODO: Handle rotated cursors int rc = -1; + assert(width <= image->width); + assert(height <= image->height); + if (nvnc_fb_map(image) < 0) return -1; @@ -43,13 +47,13 @@ int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, if (rc < 0) return -1; - rc = encode_rect_head(dst, RFB_ENCODING_CURSOR, x_hotspot, y_hotspot, - image->width, image->height); + rc = encode_rect_head(dst, RFB_ENCODING_CURSOR, hotspot_x, hotspot_y, + width, height); if (rc < 0) return -1; int bpp = pixfmt->bits_per_pixel / 8; - size_t size = image->width * image->height; + size_t size = width * height; rc = vec_reserve(dst, dst->len + size * bpp + UDIV_UP(size, 8)); if (rc < 0) @@ -58,13 +62,13 @@ int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, uint8_t* dstdata = dst->data; dstdata += dst->len; - if(image->width == image->stride) { + if((int32_t)width == image->stride) { pixel32_to_cpixel(dstdata, pixfmt, image->addr, &srcfmt, bpp, size); } else { - for (int y = 0; y < image->height; ++y) { - pixel32_to_cpixel(dstdata + y * bpp * image->width, pixfmt, + for (int y = 0; y < height; ++y) { + pixel32_to_cpixel(dstdata + y * bpp * width, pixfmt, (uint32_t*)image->addr + y * image->stride, - &srcfmt, bpp, image->width); + &srcfmt, bpp, width); } } @@ -72,13 +76,13 @@ int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, dstdata = dst->data; dstdata += dst->len; - for (int y = 0; y < image->height; ++y) { - if (!extract_alpha_mask(dstdata + y * UDIV_UP(image->width, 8), + for (int 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, image->width)) + image->fourcc_format, width)) return -1; - dst->len += UDIV_UP(image->width, 8); + dst->len += UDIV_UP(width, 8); } return 0; diff --git a/src/server.c b/src/server.c index a7d54c7..b576424 100644 --- a/src/server.c +++ b/src/server.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 - 2021 Andri Yngvason + * Copyright (c) 2019 - 2022 Andri Yngvason * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -467,6 +467,9 @@ static int on_client_set_pixel_format(struct nvnc_client* client) memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt)); + if (client->has_pixfmt && client->cursor_seq) + client->cursor_seq--; + client->has_pixfmt = true; return 4 + sizeof(struct rfb_pixel_format); @@ -525,6 +528,7 @@ static void send_cursor_update(struct nvnc_client* client) if (!server->cursor.buffer) { // TODO: Empty buffer means that no cursor should be visible + client->cursor_seq = server->cursor_seq; return; } @@ -539,7 +543,8 @@ static void send_cursor_update(struct nvnc_client* client) vec_append(&payload, &head, sizeof(head)); int rc = cursor_encode(&payload, &client->pixfmt, server->cursor.buffer, - server->cursor.x_hotspot, server->cursor.y_hotspot); + server->cursor.width, server->cursor.height, + server->cursor.hotspot_x, server->cursor.hotspot_y); if (rc < 0) { log_error("Failed to send cursor to client\n"); vec_destroy(&payload); @@ -1577,8 +1582,8 @@ cert_alloc_failure: } EXPORT -void nvnc_set_cursor(struct nvnc* self, struct nvnc_fb* fb, uint16_t x_hotspot, - uint16_t y_hotspot, struct pixman_region16* damage) +void nvnc_set_cursor(struct nvnc* self, struct nvnc_fb* fb, uint16_t width, + uint16_t height, uint16_t hotspot_x, uint16_t hotspot_y) { if (self->cursor.buffer) { nvnc_fb_release(self->cursor.buffer); @@ -1587,24 +1592,26 @@ void nvnc_set_cursor(struct nvnc* self, struct nvnc_fb* fb, uint16_t x_hotspot, self->cursor.buffer = fb; if (!fb) { - self->cursor.x_hotspot = 0; - self->cursor.y_hotspot = 0; + self->cursor.hotspot_x = 0; + self->cursor.hotspot_y = 0; return; } + // TODO: Hash cursors to check if they actually changed? + nvnc_fb_ref(fb); nvnc_fb_hold(fb); - self->cursor.x_hotspot = x_hotspot; - self->cursor.y_hotspot = y_hotspot; + self->cursor.width = width; + self->cursor.height = height; + self->cursor.hotspot_x = hotspot_x; + self->cursor.hotspot_y = hotspot_y; - if (!damage || pixman_region_not_empty(damage)) { - // TODO: Hash cursors to check if they actually changed + self->cursor_seq++; - self->cursor_seq++; + struct nvnc_client* client; + LIST_FOREACH(client, &self->clients, link) + process_fb_update_requests(client); - struct nvnc_client* client; - LIST_FOREACH(client, &self->clients, link) - process_fb_update_requests(client); - } + log_debug("Setting cursor\n"); }