X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=rdpsrv.c;h=432147b15eac061bbd490d9f206e2877ec124498;hb=25e1484eafa79fa2b644af1d923513b549c6bfd9;hp=9b198ef41d04c489a8d90402c2040b60b77ed897;hpb=cb78b4571e17e9c6c5463f871c69c1fd0603cf60;p=rdpsrv diff --git a/rdpsrv.c b/rdpsrv.c index 9b198ef..432147b 100644 --- a/rdpsrv.c +++ b/rdpsrv.c @@ -91,9 +91,6 @@ void handle_input_pdu(STREAM s) printf("- Device flags: %x\n", device_flags); printf("- Position: (%u,%u)\n", param1, param2); - // debug - rdp_send_bitmap_update(param1, param2); - break; default: printf("- Unknown type %x\n", message_type); @@ -138,10 +135,10 @@ int vnc_init() printf("Server is %u x %u\n", ntohs(si.width), ntohs(si.height)); - if (read(vnc_sock, buf, ntohs(si.name_len)) != ntohs(si.name_len)) + if (read(vnc_sock, buf, ntohl(si.name_len)) != ntohl(si.name_len)) error("short read on server name\n"); - printf("Server name is '%*s'\n", ntohs(si.name_len), buf); + printf("Server name is '%*s' (%u bytes)\n", ntohl(si.name_len), buf, ntohl(si.name_len)); // we can only accept raw encoding buf[0] = 2; // message type @@ -149,8 +146,11 @@ int vnc_init() buf[2] = 0; // number of encodings buf[3] = 1; buf[4] = 0; // raw encoding + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; - write(vnc_sock, buf, 5); + write(vnc_sock, buf, 8); // request the entire framebuffer buf[0] = 3; // message type @@ -159,9 +159,9 @@ int vnc_init() buf[3] = 0; buf[4] = 0; // ypos buf[5] = 0; - buf[6] = 640 >> 8; // width + buf[6] = 0; // width buf[7] = 640 % 0xff; - buf[8] = 480 >> 8; // height + buf[8] = 0; // height buf[9] = 480 % 0xff; write(vnc_sock, buf, 10); @@ -171,9 +171,52 @@ int vnc_init() return vnc_sock; } +struct vnc_rectangle { + unsigned short x, y, width, height; + unsigned int encoding; +}; + +void handle_vnc_fbupdate(int vnc_sock) +{ + struct vnc_rectangle rect; + unsigned char *data, *ptr; + unsigned short num_rect; + int ret, data_left, i; + + if (read(vnc_sock, &num_rect, 2) != 2) + error("short read on num_rect\n"); + + for (i = 0; i < ntohs(num_rect); ++i) { + if (read(vnc_sock, &rect, sizeof(struct vnc_rectangle)) != sizeof(struct vnc_rectangle)) + error("short read on vnc_rectangle\n"); + + printf("UPDATE: %ux%u at (%u,%u)\n", ntohs(rect.width), ntohs(rect.height), + ntohs(rect.x), ntohs(rect.y)); + + if (ntohl(rect.encoding) != 0) + error("unsupported encoding\n"); + + ptr = data = xmalloc(ntohs(rect.width) * ntohs(rect.height) * 3); + data_left = ntohs(rect.width) * ntohs(rect.height) * 3; + + while (data_left > 0) { + ret = read(vnc_sock, ptr, data_left); + if (ret <= 0) + error("error on data read\n"); + + ptr += ret; + data_left -= ret; + } + +// rdp_send_bitmap_update(ntohs(rect.x), ntohs(rect.y), ntohs(rect.width), ntohs(rect.height), data); + xfree(data); + } +} + int serve_client() { int vnc_sock = vnc_init(); + int listen_on_vnc = 0; if (!mcs_recv_connect_initial()) error("MCS_CONNECT_INITIAL recv failed"); @@ -206,6 +249,7 @@ int serve_client() case RDP_DATA_PDU_INPUT: printf("Input PDU\n"); handle_input_pdu(s); + listen_on_vnc = 1; break; default: printf("Unknown data PDU type %u\n", data_pdu_type); @@ -214,8 +258,23 @@ int serve_client() } // activity on VNC socket? - if (FD_ISSET(vnc_sock, &readfs)) { + if (FD_ISSET(vnc_sock, &readfs) && listen_on_vnc) { + unsigned char buf[256]; + printf("Activity on VNC socket!\n"); + + if (read(vnc_sock, buf, 2) != 2) + error("short read on vnc_sock\n"); + + switch (buf[0]) { + case 0: + // frame buffer update! + handle_vnc_fbupdate(vnc_sock); + break; + default: + printf("Unknown VNC server message %x\n", buf[0]); +// exit(1); + } } } }