Add width and height arguments to nvnc_set_cursor

pull/63/head
Andri Yngvason 2022-02-19 23:06:15 +00:00
parent afc0f018da
commit 1553c88f5e
6 changed files with 49 additions and 34 deletions

View File

@ -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 * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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(); struct nvnc_fb* cursor = create_cursor();
assert(cursor); assert(cursor);
nvnc_set_cursor(server, cursor, 0, 0, NULL); nvnc_set_cursor(server, cursor, 0, 0, 32, 32);
nvnc_fb_unref(cursor); nvnc_fb_unref(cursor);
struct aml_signal* sig = aml_signal_new(SIGINT, on_sigint, NULL, NULL); struct aml_signal* sig = aml_signal_new(SIGINT, on_sigint, NULL, NULL);

View File

@ -110,7 +110,8 @@ struct nvnc {
struct nvnc_display* display; struct nvnc_display* display;
struct { struct {
struct nvnc_fb* buffer; struct nvnc_fb* buffer;
uint32_t x_hotspot, y_hotspot; uint32_t width, height;
uint32_t hotspot_x, hotspot_y;
} cursor; } cursor;
uint32_t cursor_seq; uint32_t cursor_seq;

View File

@ -16,9 +16,12 @@
#pragma once #pragma once
#include <stdint.h>
struct vec; struct vec;
struct nvnc_fb; struct nvnc_fb;
struct rfb_pixel_format; struct rfb_pixel_format;
int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, 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);

View File

@ -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 * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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_send_cut_text(struct nvnc*, const char* text, uint32_t len);
void nvnc_set_cursor(struct nvnc*, struct nvnc_fb*, uint16_t x_hotspot, void nvnc_set_cursor(struct nvnc*, struct nvnc_fb*, uint16_t width,
uint16_t y_hotspot, struct pixman_region16* damage); uint16_t height, uint16_t hotspot_x, uint16_t hotspot_y);

View File

@ -29,12 +29,16 @@
#define UDIV_UP(a, b) (((a) + (b) - 1) / (b)) #define UDIV_UP(a, b) (((a) + (b) - 1) / (b))
int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt, 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 // TODO: Handle rotated cursors
int rc = -1; int rc = -1;
assert(width <= image->width);
assert(height <= image->height);
if (nvnc_fb_map(image) < 0) if (nvnc_fb_map(image) < 0)
return -1; return -1;
@ -43,13 +47,13 @@ int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt,
if (rc < 0) if (rc < 0)
return -1; return -1;
rc = encode_rect_head(dst, RFB_ENCODING_CURSOR, x_hotspot, y_hotspot, rc = encode_rect_head(dst, RFB_ENCODING_CURSOR, hotspot_x, hotspot_y,
image->width, image->height); width, height);
if (rc < 0) if (rc < 0)
return -1; return -1;
int bpp = pixfmt->bits_per_pixel / 8; 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)); rc = vec_reserve(dst, dst->len + size * bpp + UDIV_UP(size, 8));
if (rc < 0) if (rc < 0)
@ -58,13 +62,13 @@ int cursor_encode(struct vec* dst, struct rfb_pixel_format* pixfmt,
uint8_t* dstdata = dst->data; uint8_t* dstdata = dst->data;
dstdata += dst->len; dstdata += dst->len;
if(image->width == image->stride) { if((int32_t)width == image->stride) {
pixel32_to_cpixel(dstdata, pixfmt, image->addr, &srcfmt, bpp, size); pixel32_to_cpixel(dstdata, pixfmt, image->addr, &srcfmt, bpp, size);
} else { } else {
for (int y = 0; y < image->height; ++y) { for (int y = 0; y < height; ++y) {
pixel32_to_cpixel(dstdata + y * bpp * image->width, pixfmt, pixel32_to_cpixel(dstdata + y * bpp * width, pixfmt,
(uint32_t*)image->addr + y * image->stride, (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->data;
dstdata += dst->len; dstdata += dst->len;
for (int y = 0; y < image->height; ++y) { for (int y = 0; y < height; ++y) {
if (!extract_alpha_mask(dstdata + y * UDIV_UP(image->width, 8), if (!extract_alpha_mask(dstdata + y * UDIV_UP(width, 8),
(uint32_t*)image->addr + y * image->stride, (uint32_t*)image->addr + y * image->stride,
image->fourcc_format, image->width)) image->fourcc_format, width))
return -1; return -1;
dst->len += UDIV_UP(image->width, 8); dst->len += UDIV_UP(width, 8);
} }
return 0; return 0;

View File

@ -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 * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * 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)); memcpy(&client->pixfmt, fmt, sizeof(client->pixfmt));
if (client->has_pixfmt && client->cursor_seq)
client->cursor_seq--;
client->has_pixfmt = true; client->has_pixfmt = true;
return 4 + sizeof(struct rfb_pixel_format); return 4 + sizeof(struct rfb_pixel_format);
@ -525,6 +528,7 @@ static void send_cursor_update(struct nvnc_client* client)
if (!server->cursor.buffer) { if (!server->cursor.buffer) {
// TODO: Empty buffer means that no cursor should be visible // TODO: Empty buffer means that no cursor should be visible
client->cursor_seq = server->cursor_seq;
return; return;
} }
@ -539,7 +543,8 @@ static void send_cursor_update(struct nvnc_client* client)
vec_append(&payload, &head, sizeof(head)); vec_append(&payload, &head, sizeof(head));
int rc = cursor_encode(&payload, &client->pixfmt, server->cursor.buffer, 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) { if (rc < 0) {
log_error("Failed to send cursor to client\n"); log_error("Failed to send cursor to client\n");
vec_destroy(&payload); vec_destroy(&payload);
@ -1577,8 +1582,8 @@ cert_alloc_failure:
} }
EXPORT EXPORT
void nvnc_set_cursor(struct nvnc* self, struct nvnc_fb* fb, uint16_t x_hotspot, void nvnc_set_cursor(struct nvnc* self, struct nvnc_fb* fb, uint16_t width,
uint16_t y_hotspot, struct pixman_region16* damage) uint16_t height, uint16_t hotspot_x, uint16_t hotspot_y)
{ {
if (self->cursor.buffer) { if (self->cursor.buffer) {
nvnc_fb_release(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; self->cursor.buffer = fb;
if (!fb) { if (!fb) {
self->cursor.x_hotspot = 0; self->cursor.hotspot_x = 0;
self->cursor.y_hotspot = 0; self->cursor.hotspot_y = 0;
return; return;
} }
// TODO: Hash cursors to check if they actually changed?
nvnc_fb_ref(fb); nvnc_fb_ref(fb);
nvnc_fb_hold(fb); nvnc_fb_hold(fb);
self->cursor.x_hotspot = x_hotspot; self->cursor.width = width;
self->cursor.y_hotspot = y_hotspot; self->cursor.height = height;
self->cursor.hotspot_x = hotspot_x;
if (!damage || pixman_region_not_empty(damage)) { self->cursor.hotspot_y = hotspot_y;
// TODO: Hash cursors to check if they actually changed
self->cursor_seq++; self->cursor_seq++;
struct nvnc_client* client; struct nvnc_client* client;
LIST_FOREACH(client, &self->clients, link) LIST_FOREACH(client, &self->clients, link)
process_fb_update_requests(client); process_fb_update_requests(client);
}
log_debug("Setting cursor\n");
} }