From feaba3d97aefe2e6796c23171d62003a3351ed31 Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Thu, 28 Jan 2021 23:52:25 +0330 Subject: [PATCH] fbvnc: send set encoding message --- fbvnc.c | 63 ++++++++++++++++++++++++++++++++------------------------- vnc.h | 72 +++++++++++++++++++++++++++++++++++------------------------------ 2 files changed, 75 insertions(+), 60 deletions(-) diff --git a/fbvnc.c b/fbvnc.c index e72464b..edf3d2d 100644 --- a/fbvnc.c +++ b/fbvnc.c @@ -1,7 +1,7 @@ /* * FBVNC: a small Linux framebuffer VNC viewer * - * Copyright (C) 2009-2020 Ali Gholami Rudi + * Copyright (C) 2009-2021 Ali Gholami Rudi * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -88,51 +88,59 @@ static int vnc_init(int fd) { char vncver[16]; int rr, rg, rb; - - struct vnc_client_init clientinit; - struct vnc_server_init serverinit; - struct vnc_client_pixelfmt pixfmt_cmd; + struct vnc_clientinit clientinit; + struct vnc_serverinit serverinit; + struct vnc_setpixelformat pixfmt_cmd; + struct vnc_setencoding enc_cmd; + u32 enc[] = {VNC_ENC_RAW}; int connstat = VNC_CONN_FAILED; + /* handshake */ read(fd, vncver, 12); strcpy(vncver, "RFB 003.003\n"); write(fd, vncver, 12); - read(fd, &connstat, sizeof(connstat)); - if (ntohl(connstat) != VNC_CONN_NOAUTH) return -1; - clientinit.shared = 1; write(fd, &clientinit, sizeof(clientinit)); read(fd, &serverinit, sizeof(serverinit)); + read(fd, buf, ntohl(serverinit.len)); + srv_cols = ntohs(serverinit.w); + srv_rows = ntohs(serverinit.h); + /* set up the framebuffer */ if (fb_init()) return -1; - srv_cols = ntohs(serverinit.w); - srv_rows = ntohs(serverinit.h); cols = MIN(srv_cols, fb_cols()); rows = MIN(srv_rows, fb_rows()); bpp = FBM_BPP(fb_mode()); mr = rows / 2; mc = cols / 2; - read(fd, buf, ntohl(serverinit.len)); - pixfmt_cmd.type = VNC_CLIENT_PIXFMT; + /* send framebuffer configuration */ + pixfmt_cmd.type = VNC_SETPIXELFORMAT; pixfmt_cmd.format.bpp = bpp << 3; pixfmt_cmd.format.depth = bpp << 3; pixfmt_cmd.format.bigendian = 0; pixfmt_cmd.format.truecolor = 1; - fbmode_bits(&rr, &rg, &rb); pixfmt_cmd.format.rmax = htons((1 << rr) - 1); pixfmt_cmd.format.gmax = htons((1 << rg) - 1); pixfmt_cmd.format.bmax = htons((1 << rb) - 1); + /* assuming colors packed as RGB; shall handle other cases later */ pixfmt_cmd.format.rshl = rg + rb; pixfmt_cmd.format.gshl = rb; pixfmt_cmd.format.bshl = 0; write(fd, &pixfmt_cmd, sizeof(pixfmt_cmd)); + + /* send pixel format */ + enc_cmd.type = VNC_SETENCODING; + enc_cmd.pad = 0; + enc_cmd.n = htons(1); + write(fd, &enc_cmd, sizeof(enc_cmd)); + write(fd, enc, ntohs(enc_cmd.n) * sizeof(enc[0])); return 0; } @@ -144,8 +152,8 @@ static int vnc_free(void) static int vnc_refresh(int fd, int inc) { - struct vnc_client_fbup fbup_req; - fbup_req.type = VNC_CLIENT_FBUP; + struct vnc_updaterequest fbup_req; + fbup_req.type = VNC_UPDATEREQUEST; fbup_req.inc = inc; fbup_req.x = htons(oc); fbup_req.y = htons(or); @@ -183,16 +191,16 @@ static int vnc_event(int fd) { struct vnc_rect uprect; char msg[1 << 12]; - struct vnc_server_fbup *fbup = (void *) msg; - struct vnc_server_cuttext *cuttext = (void *) msg; - struct vnc_server_colormap *colormap = (void *) msg; + struct vnc_update *fbup = (void *) msg; + struct vnc_servercuttext *cuttext = (void *) msg; + struct vnc_setcolormapentries *colormap = (void *) msg; int i, j; int n; if (read(fd, msg, 1) != 1) return -1; switch (msg[0]) { - case VNC_SERVER_FBUP: + case VNC_UPDATE: xread(fd, msg + 1, sizeof(*fbup) - 1); n = ntohs(fbup->n); for (j = 0; j < n; j++) { @@ -213,13 +221,13 @@ static int vnc_event(int fd) } } break; - case VNC_SERVER_BELL: + case VNC_BELL: break; - case VNC_SERVER_CUTTEXT: + case VNC_SERVERCUTTEXT: xread(fd, msg + 1, sizeof(*cuttext) - 1); xread(fd, buf, ntohl(cuttext->len)); break; - case VNC_SERVER_COLORMAP: + case VNC_SETCOLORMAPENTRIES: xread(fd, msg + 1, sizeof(*colormap) - 1); xread(fd, buf, ntohs(colormap->n) * 3 * 2); break; @@ -232,11 +240,11 @@ static int vnc_event(int fd) static int rat_event(int fd, int ratfd) { - char ie[4]; - struct vnc_client_ratevent me = {VNC_CLIENT_RATEVENT}; + char ie[4] = {0}; + struct vnc_pointerevent me = {VNC_POINTEREVENT}; int mask = 0; int or_ = or, oc_ = oc; - if (read(ratfd, &ie, sizeof(ie)) != 4) + if (ratfd > 0 && read(ratfd, &ie, sizeof(ie)) != 4) return -1; /* ignore mouse movements when nodraw */ if (nodraw) @@ -277,7 +285,7 @@ static int rat_event(int fd, int ratfd) static int press(int fd, int key, int down) { - struct vnc_client_keyevent ke = {VNC_CLIENT_KEYEVENT}; + struct vnc_keyevent ke = {VNC_KEYEVENT}; ke.key = htonl(key); ke.down = down; return write(fd, &ke, sizeof(ke)); @@ -347,7 +355,7 @@ static int kbd_event(int fd, int kbdfd) default: k = (unsigned char) key[i]; } - if (k >= 'A' && k <= 'Z' || strchr(":\"<>?{}|+_()*&^%$#@!~", k)) + if ((k >= 'A' && k <= 'Z') || strchr(":\"<>?{}|+_()*&^%$#@!~", k)) mod[nmod++] = 0xffe1; if (k >= 1 && k <= 26) { k = 'a' + k - 1; @@ -395,6 +403,7 @@ static void mainloop(int vnc_fd, int kbd_fd, int rat_fd) ufds[1].events = POLLIN; ufds[2].fd = rat_fd; ufds[2].events = POLLIN; + rat_event(vnc_fd, -1); if (vnc_refresh(vnc_fd, 0)) return; while (1) { diff --git a/vnc.h b/vnc.h index 4d6c054..2d43d65 100644 --- a/vnc.h +++ b/vnc.h @@ -6,18 +6,18 @@ #define VNC_AUTH_FAILED 1 #define VNC_AUTH_TOOMANY 2 -#define VNC_SERVER_FBUP 0 -#define VNC_SERVER_COLORMAP 1 -#define VNC_SERVER_BELL 2 -#define VNC_SERVER_CUTTEXT 3 - -#define VNC_CLIENT_PIXFMT 0 -#define VNC_CLIENT_COLORMAP 1 -#define VNC_CLIENT_SETENC 2 -#define VNC_CLIENT_FBUP 3 -#define VNC_CLIENT_KEYEVENT 4 -#define VNC_CLIENT_RATEVENT 5 -#define VNC_CLIENT_CUTTEXT 6 +#define VNC_UPDATE 0 +#define VNC_SERVERCOLORMAP 1 +#define VNC_BELL 2 +#define VNC_SERVERCUTTEXT 3 + +#define VNC_SETPIXELFORMAT 0 +#define VNC_SETCOLORMAPENTRIES 1 +#define VNC_SETENCODING 2 +#define VNC_UPDATEREQUEST 3 +#define VNC_KEYEVENT 4 +#define VNC_POINTEREVENT 5 +#define VNC_CLIENTCUTTEXT 6 #define VNC_ENC_RAW 0 #define VNC_ENC_COPYRECT 1 @@ -35,7 +35,7 @@ typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; -struct vnc_pixelfmt { +struct vnc_pixelformat { u8 bpp; u8 depth; u8 bigendian; @@ -46,21 +46,20 @@ struct vnc_pixelfmt { u8 rshl; u8 gshl; u8 bshl; - u8 pad1; u16 pad2; }; -struct vnc_client_init { +struct vnc_clientinit { u8 shared; }; -struct vnc_server_init { - u16 w; - u16 h; - struct vnc_pixelfmt fmt; - u32 len; - /* char name[len]; */ +struct vnc_serverinit { + u16 w; + u16 h; + struct vnc_pixelformat fmt; + u32 len; + /* char name[len]; */ }; struct vnc_rect { @@ -70,14 +69,14 @@ struct vnc_rect { /* rect bytes */ }; -struct vnc_server_fbup { - u8 type; - u8 pad; - u16 n; - /* struct vnc_rect rects[n]; */ +struct vnc_update { + u8 type; + u8 pad; + u16 n; + /* struct vnc_rect rects[n]; */ }; -struct vnc_server_cuttext { +struct vnc_servercuttext { u8 type; u8 pad1; u16 pad2; @@ -85,7 +84,7 @@ struct vnc_server_cuttext { /* char text[length] */ }; -struct vnc_server_colormap { +struct vnc_setcolormapentries { u8 type; u8 pad; u16 first; @@ -93,14 +92,21 @@ struct vnc_server_colormap { /* u8 colors[n * 3 * 2]; */ }; -struct vnc_client_pixelfmt { +struct vnc_setpixelformat { u8 type; u8 pad1; u16 pad2; - struct vnc_pixelfmt format; + struct vnc_pixelformat format; +}; + +struct vnc_setencoding { + u8 type; + u8 pad; + u16 n; + /* s32[n] */ }; -struct vnc_client_fbup { +struct vnc_updaterequest { u8 type; u8 inc; u16 x; @@ -109,14 +115,14 @@ struct vnc_client_fbup { u16 h; }; -struct vnc_client_keyevent { +struct vnc_keyevent { u8 type; u8 down; u16 pad; u32 key; }; -struct vnc_client_ratevent { +struct vnc_pointerevent { u8 type; u8 mask; u16 x; -- 2.11.4.GIT