Implement some more

tight-png
Andri Yngvason 2019-08-12 23:33:06 +00:00 committed by Andri Yngvason
parent 0b0baae302
commit e42b8ffa92
2 changed files with 136 additions and 3 deletions

View File

@ -33,6 +33,17 @@ enum rfb_client_to_server_msg_type {
RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT = 6, RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT = 6,
}; };
enum rfb_encodings {
RFB_ENCODING_RAW = 0,
RFB_ENCODING_COPYRECT = 1,
RFB_ENCODING_RRE = 2,
RFB_ENCODING_HEXTILE = 5,
RFB_ENCODING_TRLE = 15,
RFB_ENCODING_ZRLE = 16,
RFB_ENCODING_CURSOR = -239,
RFB_ENCODING_DESKTOPSIZE = -223,
};
struct rfb_security_types_msg { struct rfb_security_types_msg {
uint8_t n; uint8_t n;
uint8_t types[1]; uint8_t types[1];
@ -65,6 +76,36 @@ struct rfb_server_init_msg {
char name_string[0]; char name_string[0];
} RFB_PACKED; } RFB_PACKED;
struct rfb_client_set_encodings_msg {
uint8_t type;
uint8_t padding;
uint16_t n_encodings;
int32_t encodings[0];
} RFB_PACKED;
struct rfb_client_fb_update_req_msg {
uint8_t type;
uint8_t incremental;
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
} RFB_PACKED;
struct rfb_client_key_event_msg {
uint8_t type;
uint8_t down_flag;
uint16_t padding;
uint32_t key;
} RFB_PACKED;
struct rfb_client_pointer_event_msg {
uint8_t type;
uint8_t button_mask;
uint16_t x;
uint16_t y;
} RFB_PACKED;
static inline int rfb_send_security_types(void *client) static inline int rfb_send_security_types(void *client)
{ {
struct rfb_security_types_msg payload = { struct rfb_security_types_msg payload = {

View File

@ -10,6 +10,17 @@
#define READ_BUFFER_SIZE 4096 #define READ_BUFFER_SIZE 4096
#define MSG_BUFFER_SIZE 4096 #define MSG_BUFFER_SIZE 4096
enum vnc_encodings {
VNC_ENCODING_RAW = 1 << 0,
VNC_ENCODING_COPYRECT = 1 << 1,
VNC_ENCODING_RRE = 1 << 2,
VNC_ENCODING_HEXTILE = 1 << 3,
VNC_ENCODING_TRLE = 1 << 4,
VNC_ENCODING_ZRLE = 1 << 5,
VNC_ENCODING_CURSOR = 1 << 6,
VNC_ENCODING_DESKTOPSIZE = 1 << 7,
};
enum vnc_client_state { enum vnc_client_state {
VNC_CLIENT_STATE_ERROR = -1, VNC_CLIENT_STATE_ERROR = -1,
VNC_CLIENT_STATE_WAITING_FOR_VERSION = 0, VNC_CLIENT_STATE_WAITING_FOR_VERSION = 0,
@ -25,6 +36,7 @@ struct vnc_client {
struct vnc_server *server; struct vnc_server *server;
enum vnc_client_state state; enum vnc_client_state state;
uint32_t pixfmt; uint32_t pixfmt;
enum vnc_encodings encodings;
LIST_ENTRY(vnc_client) link; LIST_ENTRY(vnc_client) link;
size_t buffer_index; size_t buffer_index;
size_t buffer_len; size_t buffer_len;
@ -424,11 +436,87 @@ static int on_client_set_pixel_format(struct vnc_client *client)
client->pixfmt = rfb_pixfmt_to_fourcc(fmt); client->pixfmt = rfb_pixfmt_to_fourcc(fmt);
printf("SetPixelFormat: %x\n", client->pixfmt); printf("SetPixelFormat: %s\n", fourcc_to_string(client->pixfmt));
return 4 + sizeof(struct rfb_pixel_format); return 4 + sizeof(struct rfb_pixel_format);
} }
static int on_client_set_encodings(struct vnc_client *client)
{
struct rfb_client_set_encodings_msg *msg =
(struct rfb_client_set_encodings_msg*)(client->msg_buffer +
client->buffer_index);
int n_encodings = ntohs(msg->n_encodings);
uint32_t e = 0;
for (int i = 0; i < n_encodings; ++i)
switch (msg->encodings[i]) {
case RFB_ENCODING_RAW: e |= VNC_ENCODING_RAW;
case RFB_ENCODING_COPYRECT: e |= VNC_ENCODING_COPYRECT;
case RFB_ENCODING_RRE: e |= VNC_ENCODING_RRE;
case RFB_ENCODING_HEXTILE: e |= VNC_ENCODING_HEXTILE;
case RFB_ENCODING_TRLE: e |= VNC_ENCODING_TRLE;
case RFB_ENCODING_ZRLE: e |= VNC_ENCODING_ZRLE;
case RFB_ENCODING_CURSOR: e |= VNC_ENCODING_CURSOR;
case RFB_ENCODING_DESKTOPSIZE: e |= VNC_ENCODING_COPYRECT;
}
client->encodings = e;
return sizeof(*msg) + 4 * n_encodings;
}
static int on_client_fb_update_request(struct vnc_client *client)
{
struct rfb_client_fb_update_req_msg *msg =
(struct rfb_client_fb_update_req_msg*)(client->msg_buffer +
client->buffer_index);
int incremental = msg->incremental;
int x = ntohs(msg->x);
int y = ntohs(msg->y);
int width = ntohs(msg->width);
int height = ntohs(msg->height);
printf("framebuffer update: %d, %d. %d %d\n", x, y, width, height);
// TODO
return sizeof(*msg);
}
static int on_client_key_event(struct vnc_client *client)
{
struct rfb_client_key_event_msg *msg =
(struct rfb_client_key_event_msg*)(client->msg_buffer +
client->buffer_index);
int down_flag = msg->down_flag;
uint32_t key = ntohl(msg->key);
printf("key event: %d\n", key);
// TODO
return sizeof(*msg);
}
static int on_client_pointer_event(struct vnc_client *client)
{
struct rfb_client_pointer_event_msg *msg =
(struct rfb_client_pointer_event_msg*)(client->msg_buffer +
client->buffer_index);
int button_mask = msg->button_mask;
uint16_t x = ntohs(msg->x);
uint16_t y = ntohs(msg->y);
printf("pointer event: %d, %d, %d\n", x, y, button_mask);
// TODO
return sizeof(*msg);
}
static int on_client_message(struct vnc_client *client) static int on_client_message(struct vnc_client *client)
{ {
if (client->buffer_len - client->buffer_index < 1) if (client->buffer_len - client->buffer_index < 1)
@ -441,9 +529,13 @@ static int on_client_message(struct vnc_client *client)
case RFB_CLIENT_TO_SERVER_SET_PIXEL_FORMAT: case RFB_CLIENT_TO_SERVER_SET_PIXEL_FORMAT:
return on_client_set_pixel_format(client); return on_client_set_pixel_format(client);
case RFB_CLIENT_TO_SERVER_SET_ENCODINGS: case RFB_CLIENT_TO_SERVER_SET_ENCODINGS:
return on_client_set_encodings(client);
case RFB_CLIENT_TO_SERVER_FRAMEBUFFER_UPDATE_REQUEST: case RFB_CLIENT_TO_SERVER_FRAMEBUFFER_UPDATE_REQUEST:
return on_client_fb_update_request(client);
case RFB_CLIENT_TO_SERVER_KEY_EVENT: case RFB_CLIENT_TO_SERVER_KEY_EVENT:
return on_client_key_event(client);
case RFB_CLIENT_TO_SERVER_POINTER_EVENT: case RFB_CLIENT_TO_SERVER_POINTER_EVENT:
return on_client_pointer_event(client);
case RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT: case RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT:
break; break;
} }
@ -479,7 +571,7 @@ static void on_client_read(uv_stream_t *stream, ssize_t n_read,
if (n_read == UV_EOF) { if (n_read == UV_EOF) {
// TODO: Make it known to the user of the library that the // TODO: Make it known to the user of the library that the
// client is gone. // client is gone.
uv_close((uv_handle_t*)&stream, cleanup_client); uv_close((uv_handle_t*)stream, cleanup_client);
return; return;
} }
@ -493,7 +585,7 @@ static void on_client_read(uv_stream_t *stream, ssize_t n_read,
if (n_read > MSG_BUFFER_SIZE - client->buffer_len) { if (n_read > MSG_BUFFER_SIZE - client->buffer_len) {
/* Can't handle this. Let's just give up */ /* Can't handle this. Let's just give up */
client->state = VNC_CLIENT_STATE_ERROR; client->state = VNC_CLIENT_STATE_ERROR;
uv_close((uv_handle_t*)&stream, cleanup_client); uv_close((uv_handle_t*)stream, cleanup_client);
return; return;
} }