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
* 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);

View File

@ -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;

View File

@ -16,9 +16,12 @@
#pragma once
#include <stdint.h>
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);

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
* 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);

View File

@ -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;

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
* 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;
if (!damage || pixman_region_not_empty(damage)) {
// TODO: Hash cursors to check if they actually changed
self->cursor.width = width;
self->cursor.height = height;
self->cursor.hotspot_x = hotspot_x;
self->cursor.hotspot_y = hotspot_y;
self->cursor_seq++;
struct nvnc_client* client;
LIST_FOREACH(client, &self->clients, link)
process_fb_update_requests(client);
}
log_debug("Setting cursor\n");
}