diff --git a/include/common.h b/include/common.h index 24389e6..6c72f46 100644 --- a/include/common.h +++ b/include/common.h @@ -96,6 +96,7 @@ struct nvnc { nvnc_pointer_fn pointer_fn; nvnc_fb_req_fn fb_req_fn; nvnc_client_fn new_client_fn; + nvnc_cut_text_fn cut_text_fn; struct nvnc_display* display; #ifdef ENABLE_TLS diff --git a/include/neatvnc.h b/include/neatvnc.h index 429cdc1..763de0e 100644 --- a/include/neatvnc.h +++ b/include/neatvnc.h @@ -49,6 +49,7 @@ typedef void (*nvnc_damage_fn)(struct pixman_region16* damage, void* userdata); typedef bool (*nvnc_auth_fn)(const char* username, const char* password, void* userdata); typedef void (*nvnc_render_fn)(struct nvnc_display*, struct nvnc_fb*); +typedef void (*nvnc_cut_text_fn)(struct nvnc*, const char* text, uint32_t len); extern const char nvnc_version[]; @@ -70,6 +71,7 @@ void nvnc_set_pointer_fn(struct nvnc* self, nvnc_pointer_fn); void nvnc_set_fb_req_fn(struct nvnc* self, nvnc_fb_req_fn); void nvnc_set_new_client_fn(struct nvnc* self, nvnc_client_fn); void nvnc_set_client_cleanup_fn(struct nvnc_client* self, nvnc_client_fn fn); +void nvnc_set_cut_text_receive_fn(struct nvnc* self, nvnc_cut_text_fn fn); bool nvnc_has_auth(void); int nvnc_enable_auth(struct nvnc* self, const char* privkey_path, @@ -111,3 +113,5 @@ void nvnc_display_damage_whole(struct nvnc_display*); int nvnc_check_damage(struct nvnc_fb* fb0, struct nvnc_fb* fb1, int x_hint, int y_hint, int width_hint, int height_hint, nvnc_damage_fn on_check_done, void* userdata); + +void nvnc_send_cut_text(struct nvnc*, const char* text, uint32_t len); diff --git a/include/rfb-proto.h b/include/rfb-proto.h index 82a1891..32af1a9 100644 --- a/include/rfb-proto.h +++ b/include/rfb-proto.h @@ -140,11 +140,11 @@ struct rfb_client_pointer_event_msg { uint16_t y; } RFB_PACKED; -struct rfb_client_cut_text_msg { +struct rfb_cut_text_msg { uint8_t type; uint8_t padding[3]; uint32_t length; - char test[0]; + char text[0]; } RFB_PACKED; struct rfb_server_fb_rect { diff --git a/src/server.c b/src/server.c index 92437db..2f12689 100644 --- a/src/server.c +++ b/src/server.c @@ -584,18 +584,44 @@ static int on_client_pointer_event(struct nvnc_client* client) return sizeof(*msg); } +EXPORT +void nvnc_send_cut_text(struct nvnc* server, const char* text, uint32_t len) +{ + struct rfb_cut_text_msg msg; + + msg.type = RFB_SERVER_TO_CLIENT_SERVER_CUT_TEXT; + msg.length = htonl(len); + + struct nvnc_client* client; + LIST_FOREACH (client, &server->clients, link) { + stream_write(client->net_stream, &msg, sizeof(msg), NULL, NULL); + stream_write(client->net_stream, text, len, NULL, NULL); + } +} + static int on_client_cut_text(struct nvnc_client* client) { - struct rfb_client_cut_text_msg* msg = - (struct rfb_client_cut_text_msg*)(client->msg_buffer + - client->buffer_index); + struct nvnc* server = client->server; + struct rfb_cut_text_msg* msg = + (struct rfb_cut_text_msg*)(client->msg_buffer + + client->buffer_index); if (client->buffer_len - client->buffer_index < sizeof(*msg)) return 0; uint32_t length = ntohl(msg->length); - // TODO + /* Messages greater than this size are unsupported */ + if (length > MSG_BUFFER_SIZE - sizeof(*msg)) { + stream_close(client->net_stream); + client_unref(client); + return 0; + } + + nvnc_cut_text_fn fn = server->cut_text_fn; + if (fn) { + fn(server, msg->text, length); + } return sizeof(*msg) + length; } @@ -1197,6 +1223,12 @@ void nvnc_set_client_cleanup_fn(struct nvnc_client* self, nvnc_client_fn fn) self->cleanup_fn = fn; } +EXPORT +void nvnc_set_cut_text_receive_fn(struct nvnc* self, nvnc_cut_text_fn fn) +{ + self->cut_text_fn = fn; +} + EXPORT void nvnc_add_display(struct nvnc* self, struct nvnc_display* display) {