Add width and height arguments to nvnc_set_cursor
parent
afc0f018da
commit
1553c88f5e
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
28
src/cursor.c
28
src/cursor.c
|
@ -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;
|
||||||
|
|
37
src/server.c
37
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
|
* 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;
|
||||||
|
self->cursor.hotspot_y = hotspot_y;
|
||||||
|
|
||||||
if (!damage || pixman_region_not_empty(damage)) {
|
self->cursor_seq++;
|
||||||
// TODO: Hash cursors to check if they actually changed
|
|
||||||
|
|
||||||
self->cursor_seq++;
|
struct nvnc_client* client;
|
||||||
|
LIST_FOREACH(client, &self->clients, link)
|
||||||
|
process_fb_update_requests(client);
|
||||||
|
|
||||||
struct nvnc_client* client;
|
log_debug("Setting cursor\n");
|
||||||
LIST_FOREACH(client, &self->clients, link)
|
|
||||||
process_fb_update_requests(client);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue