wok diff busybox/stuff/busybox-1.27-fbvnc.u @ rev 21937
Up nnn (2.7)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Mon Oct 07 18:30:01 2019 +0200 (2019-10-07) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/busybox/stuff/busybox-1.27-fbvnc.u Mon Oct 07 18:30:01 2019 +0200 1.3 @@ -0,0 +1,684 @@ 1.4 + text data bss dec hex filename 1.5 + 3179 0 0 3179 c6b util-linux/fbvnc.o 1.6 +--- /dev/null 1.7 ++++ busybox/util-linux/fbvnc.c 1.8 +@@ -0,0 +1,552 @@ 1.9 ++/* vi: set sw=4 ts=4: */ 1.10 ++/* 1.11 ++ * A small linux framebuffer VNC viewer 1.12 ++ * 1.13 ++ * pascal.bellard@ads-lu.com 1.14 ++ * 1.15 ++ * Based on Ali Gholami Rudi's fbvnc.c 1.16 ++ * http://repo.or.cz/w/fbvnc.git 1.17 ++ * 1.18 ++ * Licensed under GPLv2 or later, see file LICENSE in this source tree. 1.19 ++ */ 1.20 ++ 1.21 ++//applet:IF_FBVNC(APPLET(fbvnc, BB_DIR_BIN, BB_SUID_DROP)) 1.22 ++ 1.23 ++//kbuild:lib-$(CONFIG_FBVNC) += fbvnc.o 1.24 ++ 1.25 ++//config:config FBVNC 1.26 ++//config: bool "fbvnc" 1.27 ++//config: default n 1.28 ++//config: depends on PLATFORM_LINUX 1.29 ++//config: help 1.30 ++//config: A linux framebuffer VNC viewer. 1.31 ++ 1.32 ++//usage:#define fbvnc_trivial_usage 1.33 ++//usage: "[VNC_SERVER] [PORT]" 1.34 ++//usage:#define fbvnc_full_usage "\n\n" 1.35 ++//usage: "A linux framebuffer VNC viewer." 1.36 ++//usage: "\nTo exit, press any mouse button and press ESC." 1.37 ++ 1.38 ++#include "libbb.h" 1.39 ++#include "vnc.h" 1.40 ++#include "common_bufsiz.h" 1.41 ++ 1.42 ++/* Stuff stolen from the kernel's fb.h */ 1.43 ++#define FB_ACTIVATE_ALL 64 1.44 ++enum { 1.45 ++ FBIOGET_VSCREENINFO = 0x4600, 1.46 ++ FBIOPUT_VSCREENINFO = 0x4601, 1.47 ++ FBIOGET_FSCREENINFO = 0x4602, 1.48 ++ FBIOGETCMAP = 0x4604, 1.49 ++ FBIOPUTCMAP = 0x4605 1.50 ++}; 1.51 ++ 1.52 ++struct fb_bitfield { 1.53 ++ uint32_t offset; /* beginning of bitfield */ 1.54 ++ uint32_t length; /* length of bitfield */ 1.55 ++ uint32_t msb_right; /* !=0: Most significant bit is right */ 1.56 ++}; 1.57 ++struct fb_var_screeninfo { 1.58 ++ uint32_t xres; /* visible resolution */ 1.59 ++ uint32_t yres; 1.60 ++ uint32_t xres_virtual; /* virtual resolution */ 1.61 ++ uint32_t yres_virtual; 1.62 ++ uint32_t xoffset; /* offset from virtual to visible */ 1.63 ++ uint32_t yoffset; /* resolution */ 1.64 ++ 1.65 ++ uint32_t bits_per_pixel; 1.66 ++ uint32_t grayscale; /* !=0 Graylevels instead of colors */ 1.67 ++ 1.68 ++ struct fb_bitfield red; /* bitfield in fb mem if true color, */ 1.69 ++ struct fb_bitfield green; /* else only length is significant */ 1.70 ++ struct fb_bitfield blue; 1.71 ++ struct fb_bitfield transp; /* transparency */ 1.72 ++ 1.73 ++ uint32_t nonstd; /* !=0 Non standard pixel format */ 1.74 ++ 1.75 ++ uint32_t activate; /* see FB_ACTIVATE_x */ 1.76 ++ 1.77 ++ uint32_t height; /* height of picture in mm */ 1.78 ++ uint32_t width; /* width of picture in mm */ 1.79 ++ 1.80 ++ uint32_t accel_flags; /* acceleration flags (hints) */ 1.81 ++ 1.82 ++ /* Timing: All values in pixclocks, except pixclock (of course) */ 1.83 ++ uint32_t pixclock; /* pixel clock in ps (pico seconds) */ 1.84 ++ uint32_t left_margin; /* time from sync to picture */ 1.85 ++ uint32_t right_margin; /* time from picture to sync */ 1.86 ++ uint32_t upper_margin; /* time from sync to picture */ 1.87 ++ uint32_t lower_margin; 1.88 ++ uint32_t hsync_len; /* length of horizontal sync */ 1.89 ++ uint32_t vsync_len; /* length of vertical sync */ 1.90 ++ uint32_t sync; /* see FB_SYNC_x */ 1.91 ++ uint32_t vmode; /* see FB_VMODE_x */ 1.92 ++ uint32_t reserved[6]; /* Reserved for future compatibility */ 1.93 ++}; 1.94 ++ 1.95 ++#define DEFAULTFBDEV FB_0 1.96 ++ 1.97 ++struct fb_fix_screeninfo { 1.98 ++ char id[16]; /* identification string eg "TT Builtin" */ 1.99 ++ unsigned long smem_start; /* Start of frame buffer mem */ 1.100 ++ /* (physical address) */ 1.101 ++ uint32_t smem_len; /* Length of frame buffer mem */ 1.102 ++ uint32_t type; /* see FB_TYPE_* */ 1.103 ++ uint32_t type_aux; /* Interleave for interleaved Planes */ 1.104 ++ uint32_t visual; /* see FB_VISUAL_* */ 1.105 ++ uint16_t xpanstep; /* zero if no hardware panning */ 1.106 ++ uint16_t ypanstep; /* zero if no hardware panning */ 1.107 ++ uint16_t ywrapstep; /* zero if no hardware ywrap */ 1.108 ++ uint32_t line_length; /* length of a line in bytes */ 1.109 ++ unsigned long mmio_start; /* Start of Memory Mapped I/O */ 1.110 ++ /* (physical address) */ 1.111 ++ uint32_t mmio_len; /* Length of Memory Mapped I/O */ 1.112 ++ uint32_t accel; /* Indicate to driver which */ 1.113 ++ /* specific chip/card we have */ 1.114 ++ uint16_t reserved[3]; /* Reserved for future compatibility */ 1.115 ++}; 1.116 ++ 1.117 ++struct fb_cmap { 1.118 ++ uint32_t start; /* First entry */ 1.119 ++ uint32_t len; /* Number of entries */ 1.120 ++ uint16_t *red; /* Red values */ 1.121 ++ uint16_t *green; 1.122 ++ uint16_t *blue; 1.123 ++ uint16_t *transp; /* transparency, can be NULL */ 1.124 ++}; 1.125 ++ 1.126 ++#define FB_VISUAL_TRUECOLOR 2 /* True color */ 1.127 ++ 1.128 ++#define COLORLEVELS (1 << 8) 1.129 ++ 1.130 ++struct scroll_data { 1.131 ++ int size; 1.132 ++ int srv_size; 1.133 ++ int offset; 1.134 ++ int pos; 1.135 ++}; 1.136 ++ 1.137 ++struct globals { 1.138 ++ struct termios term_orig; 1.139 ++ struct pollfd ufds[3]; 1.140 ++#define kbd_fd ufds[0].fd 1.141 ++#define vnc_fd ufds[1].fd 1.142 ++#define rat_fd ufds[2].fd 1.143 ++ struct scroll_data scroll[2]; 1.144 ++#define cols scroll[0].size 1.145 ++#define srv_cols scroll[0].srv_size 1.146 ++#define oc scroll[0].offset 1.147 ++#define mc scroll[0].pos 1.148 ++#define rows scroll[1].size 1.149 ++#define srv_rows scroll[1].srv_size 1.150 ++#define or scroll[1].offset 1.151 ++#define mr scroll[1].pos 1.152 ++ char rat_buttons; 1.153 ++ int fb_fd; 1.154 ++ void *fb_ptr; 1.155 ++ int bpp; 1.156 ++ int nr, ng, nb; 1.157 ++ struct fb_var_screeninfo vinfo; 1.158 ++ struct fb_fix_screeninfo finfo; 1.159 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 1.160 ++}; 1.161 ++ 1.162 ++#define G (*ptr_to_globals) 1.163 ++#define INIT_G() do { \ 1.164 ++ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 1.165 ++} while (0) 1.166 ++ 1.167 ++static int fb_len(void) 1.168 ++{ 1.169 ++ return G.finfo.line_length * G.vinfo.yres_virtual; 1.170 ++} 1.171 ++ 1.172 ++static void fb_ioctl_cmap(int fct, struct fb_cmap *cmap) 1.173 ++{ 1.174 ++ if (G.finfo.visual == FB_VISUAL_TRUECOLOR) 1.175 ++ return; 1.176 ++ cmap->start = 0; 1.177 ++ cmap->len = MAX(G.nr, MAX(G.ng, G.nb)); 1.178 ++ cmap->transp = NULL; 1.179 ++ xioctl(G.fb_fd, fct, cmap); 1.180 ++} 1.181 ++ 1.182 ++static void fb_cmap_save(int save) 1.183 ++{ 1.184 ++ struct fb_cmap cmap; 1.185 ++ 1.186 ++ cmap.red = G.red; 1.187 ++ cmap.green = G.green; 1.188 ++ cmap.blue = G.blue; 1.189 ++ fb_ioctl_cmap(save ? FBIOGETCMAP : FBIOPUTCMAP, &cmap); 1.190 ++} 1.191 ++ 1.192 ++static void fb_build_cmap(unsigned short *color, int n) 1.193 ++{ 1.194 ++ int i, inc = 65535 / (n - 1); 1.195 ++ 1.196 ++ for (i = 0; n--; i += inc) 1.197 ++ *color++ = i; 1.198 ++} 1.199 ++ 1.200 ++static void fb_cmap(void) 1.201 ++{ 1.202 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 1.203 ++ struct fb_cmap cmap; 1.204 ++ 1.205 ++ fb_build_cmap(cmap.red = red, G.nr); 1.206 ++ fb_build_cmap(cmap.green = green, G.ng); 1.207 ++ fb_build_cmap(cmap.blue = blue, G.nb); 1.208 ++ fb_ioctl_cmap(FBIOPUTCMAP, &cmap); 1.209 ++} 1.210 ++ 1.211 ++static void fb_init(void) 1.212 ++{ 1.213 ++ G.fb_fd = xopen(DEFAULTFBDEV, O_RDWR); 1.214 ++ xioctl(G.fb_fd, FBIOGET_VSCREENINFO, &G.vinfo); 1.215 ++ xioctl(G.fb_fd, FBIOGET_FSCREENINFO, &G.finfo); 1.216 ++ close_on_exec_on(G.fb_fd); 1.217 ++ G.fb_ptr = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, G.fb_fd, 0); 1.218 ++ if (G.fb_ptr == MAP_FAILED) 1.219 ++ bb_perror_msg_and_die("mmap"); 1.220 ++ G.bpp = (G.vinfo.bits_per_pixel + 7) >> 3; 1.221 ++ G.nr = 1 << G.vinfo.red.length; 1.222 ++ G.nb = 1 << G.vinfo.blue.length; 1.223 ++ G.ng = 1 << G.vinfo.green.length; 1.224 ++ fb_cmap_save(1); 1.225 ++ fb_cmap(); 1.226 ++} 1.227 ++ 1.228 ++static void fb_free(void) 1.229 ++{ 1.230 ++ fb_cmap_save(0); 1.231 ++ munmap(G.fb_ptr, fb_len()); 1.232 ++ close(G.fb_fd); 1.233 ++} 1.234 ++ 1.235 ++#define fb_rows vinfo.yres 1.236 ++#define fb_cols vinfo.xres 1.237 ++ 1.238 ++static void fb_set(int r, int c, void *mem, int len) 1.239 ++{ 1.240 ++ memcpy(G.fb_ptr + (r + G.vinfo.yoffset) * G.finfo.line_length + 1.241 ++ (c + G.vinfo.xoffset) * G.bpp, mem, len * G.bpp); 1.242 ++} 1.243 ++ 1.244 ++#define line_buffer bb_common_bufsiz1 1.245 ++#define MAXPIX (COMMON_BUFSIZE/sizeof(uint32_t)) 1.246 ++ 1.247 ++static void skip(int len) 1.248 ++{ 1.249 ++ int n; 1.250 ++ while (len > 0 && (n = read(G.vnc_fd, line_buffer, 1.251 ++ MIN(len, COMMON_BUFSIZE))) > 0) 1.252 ++ len -= n; 1.253 ++} 1.254 ++ 1.255 ++static void vnc_init(void) 1.256 ++{ 1.257 ++ struct vnc_client_init clientinit; 1.258 ++ struct vnc_server_init serverinit; 1.259 ++ struct vnc_client_pixelfmt pixfmt_cmd; 1.260 ++ int connstat = VNC_CONN_FAILED; 1.261 ++ 1.262 ++ write(G.vnc_fd, "RFB 003.003\n", 12); 1.263 ++ skip(12); 1.264 ++ 1.265 ++ xread(G.vnc_fd, &connstat, sizeof(connstat)); 1.266 ++ 1.267 ++ if (ntohl(connstat) != VNC_CONN_NOAUTH) 1.268 ++ bb_perror_msg_and_die("vnc auth"); 1.269 ++ 1.270 ++ clientinit.shared = 1; 1.271 ++ write(G.vnc_fd, &clientinit, sizeof(clientinit)); 1.272 ++ read(G.vnc_fd, &serverinit, sizeof(serverinit)); 1.273 ++ 1.274 ++ fb_init(); 1.275 ++ G.srv_cols = ntohs(serverinit.w); 1.276 ++ G.srv_rows = ntohs(serverinit.h); 1.277 ++ G.cols = MIN(G.srv_cols, G.fb_cols); 1.278 ++ G.rows = MIN(G.srv_rows, G.fb_rows); 1.279 ++ G.mr = G.rows / 2; 1.280 ++ G.mc = G.cols / 2; 1.281 ++ 1.282 ++ skip(ntohl(serverinit.len)); 1.283 ++ pixfmt_cmd.type = VNC_CLIENT_PIXFMT; 1.284 ++ pixfmt_cmd.format.bigendian = 0; 1.285 ++ pixfmt_cmd.format.truecolor = 1; 1.286 ++ pixfmt_cmd.format.bpp = 1.287 ++ pixfmt_cmd.format.depth = G.bpp << 3; 1.288 ++ pixfmt_cmd.format.rmax = htons(G.nr - 1); 1.289 ++ pixfmt_cmd.format.gmax = htons(G.ng - 1); 1.290 ++ pixfmt_cmd.format.bmax = htons(G.nb - 1); 1.291 ++ pixfmt_cmd.format.rshl = G.vinfo.red.offset; 1.292 ++ pixfmt_cmd.format.gshl = G.vinfo.green.offset; 1.293 ++ pixfmt_cmd.format.bshl = G.vinfo.blue.offset; 1.294 ++ write(G.vnc_fd, &pixfmt_cmd, sizeof(pixfmt_cmd)); 1.295 ++} 1.296 ++ 1.297 ++static void vnc_refresh(int inc) 1.298 ++{ 1.299 ++ struct vnc_client_fbup fbup_req; 1.300 ++ fbup_req.type = VNC_CLIENT_FBUP; 1.301 ++ fbup_req.inc = inc; 1.302 ++ fbup_req.x = htons(G.oc); 1.303 ++ fbup_req.y = htons(G.or); 1.304 ++ fbup_req.w = htons(G.oc + G.cols); 1.305 ++ fbup_req.h = htons(G.or + G.rows); 1.306 ++ write(G.vnc_fd, &fbup_req, sizeof(fbup_req)); 1.307 ++} 1.308 ++ 1.309 ++static void cleanup(void) 1.310 ++{ 1.311 ++#define RESETSTR "\x1b[?25h\x1b[2J\x1b[H" 1.312 ++ fb_free(); 1.313 ++ tcsetattr_stdin_TCSANOW(&G.term_orig); 1.314 ++ write(STDOUT_FILENO, RESETSTR, sizeof(RESETSTR)); 1.315 ++ if (ENABLE_FEATURE_CLEAN_UP) { 1.316 ++ close(G.vnc_fd); 1.317 ++ close(G.rat_fd); 1.318 ++ } 1.319 ++} 1.320 ++ 1.321 ++static void killed(int code) NORETURN; 1.322 ++static void killed(int code) 1.323 ++{ 1.324 ++ cleanup(); 1.325 ++ if (code > EXIT_FAILURE) 1.326 ++ kill_myself_with_sig(code); 1.327 ++ exit(code); 1.328 ++} 1.329 ++ 1.330 ++static void vnc_event(void) 1.331 ++{ 1.332 ++ struct vnc_rect uprect; 1.333 ++ union { 1.334 ++ struct vnc_server_fbup fbup; 1.335 ++ struct vnc_server_cuttext cuttext; 1.336 ++ struct vnc_server_colormap colormap; 1.337 ++ } msg; 1.338 ++ int n; 1.339 ++ 1.340 ++ switch (xread_char(G.vnc_fd)) { 1.341 ++ case VNC_SERVER_FBUP: 1.342 ++ xread(G.vnc_fd, &msg.fbup.pad, sizeof(msg.fbup) - 1); 1.343 ++ n = ntohs(msg.fbup.n); 1.344 ++ while (n--) { 1.345 ++ int x, y, w, h, l, i; 1.346 ++ xread(G.vnc_fd, &uprect, sizeof(uprect)); 1.347 ++ if (uprect.enc != 0) 1.348 ++ killed(1); 1.349 ++ i = 0; 1.350 ++ x = ntohs(uprect.x) - G.oc; 1.351 ++ y = ntohs(uprect.y) - G.or; 1.352 ++ w = ntohs(uprect.w); 1.353 ++ h = ntohs(uprect.h); 1.354 ++ l = MIN(w, G.cols - x); 1.355 ++ if (x < 0) { 1.356 ++ l = MIN(w + x, G.cols); 1.357 ++ i = -x; 1.358 ++ x = 0; 1.359 ++ } 1.360 ++ for (; h--; y++) { 1.361 ++ int a, b, c = i; 1.362 ++ for (a = b = 0; w > b; b += a, c = 0) { 1.363 ++ int len; 1.364 ++ a = MIN(w - b, MAXPIX); 1.365 ++ len = MIN(a, l - b) - c; 1.366 ++ xread(G.vnc_fd, line_buffer, a * G.bpp); 1.367 ++ if (y >= 0 && y < G.rows && len > 0) 1.368 ++ fb_set(y, x + b, 1.369 ++ line_buffer + (c * G.bpp), 1.370 ++ len); 1.371 ++ } 1.372 ++ } 1.373 ++ } 1.374 ++ break; 1.375 ++ case VNC_SERVER_BELL: 1.376 ++ break; 1.377 ++ case VNC_SERVER_CUTTEXT: 1.378 ++ xread(G.vnc_fd, &msg.cuttext.pad1, sizeof(msg.cuttext) - 1); 1.379 ++ skip(ntohl(msg.cuttext.len)); 1.380 ++ break; 1.381 ++ case VNC_SERVER_COLORMAP: 1.382 ++ xread(G.vnc_fd, &msg.colormap.pad, sizeof(msg.colormap) - 1); 1.383 ++ skip(ntohs(msg.colormap.n) * 3 * 2); 1.384 ++ break; 1.385 ++ default: 1.386 ++ killed(1); 1.387 ++ } 1.388 ++} 1.389 ++ 1.390 ++static int update_scroll(struct scroll_data *s) 1.391 ++{ 1.392 ++ int shift = s->size / 5; 1.393 ++ int max = s->srv_size - s->size; 1.394 ++ int status = 0; 1.395 ++ if (s->pos < s->offset) { 1.396 ++ if ((s->offset -= shift) < 0) 1.397 ++ s->offset = 0; 1.398 ++ } 1.399 ++ else if (s->pos >= s->offset + s->size && s->offset < max) { 1.400 ++ if ((s->offset += shift) > max) 1.401 ++ s->offset = max; 1.402 ++ } 1.403 ++ else status++; 1.404 ++ s->pos = MAX(s->offset, MIN(s->offset + s->size - 1, s->pos)); 1.405 ++ return status; 1.406 ++} 1.407 ++ 1.408 ++static void rat_event(void) 1.409 ++{ 1.410 ++ static u8 btn2vnc[8] = { 1.411 ++ 0, VNC_BUTTON1_MASK, VNC_BUTTON3_MASK, 1.412 ++ VNC_BUTTON1_MASK + VNC_BUTTON3_MASK, VNC_BUTTON2_MASK, 1.413 ++ VNC_BUTTON1_MASK + VNC_BUTTON2_MASK, 1.414 ++ VNC_BUTTON2_MASK + VNC_BUTTON3_MASK, 1.415 ++ VNC_BUTTON1_MASK + VNC_BUTTON2_MASK + VNC_BUTTON3_MASK 1.416 ++ }; 1.417 ++ signed char ie[4]; 1.418 ++ struct vnc_client_ratevent me = {VNC_CLIENT_RATEVENT}; 1.419 ++ int refresh; 1.420 ++ 1.421 ++ xread(G.rat_fd, &ie, sizeof(ie)); 1.422 ++ G.mc += ie[1]; 1.423 ++ G.mr -= ie[2]; 1.424 ++ refresh = 2 - update_scroll(&G.scroll[0]) - update_scroll(&G.scroll[1]); 1.425 ++ me.mask = btn2vnc[(int)(G.rat_buttons = ie[0] & 7)]; 1.426 ++ if (ie[3] > 0) /* wheel up */ 1.427 ++ me.mask |= VNC_BUTTON4_MASK; 1.428 ++ if (ie[3] < 0) /* wheel down */ 1.429 ++ me.mask |= VNC_BUTTON5_MASK; 1.430 ++ me.y = htons(G.mr); 1.431 ++ me.x = htons(G.mc); 1.432 ++ write(G.vnc_fd, &me, sizeof(me)); 1.433 ++ if (refresh) 1.434 ++ vnc_refresh(0); 1.435 ++} 1.436 ++ 1.437 ++static int press(int key, int down) 1.438 ++{ 1.439 ++ struct vnc_client_keyevent ke = {VNC_CLIENT_KEYEVENT}; 1.440 ++ ke.key = htonl(key); 1.441 ++ ke.down = down; 1.442 ++ return write(G.vnc_fd, &ke, sizeof(ke)); 1.443 ++} 1.444 ++ 1.445 ++static void kbd_event(void) 1.446 ++{ 1.447 ++ char key[1024]; 1.448 ++ int i, nr; 1.449 ++ 1.450 ++ if ((nr = read(0, key, sizeof(key))) <= 0 ) 1.451 ++ killed(1); 1.452 ++ for (i = 0; i < nr; i++) { 1.453 ++ int j, k; 1.454 ++ int mod[4]; 1.455 ++ int nmod; 1.456 ++ 1.457 ++ k = nmod = 0; 1.458 ++ switch (key[i]) { 1.459 ++ case 0x08: 1.460 ++ case 0x7f: 1.461 ++ k = 0xff08; 1.462 ++ break; 1.463 ++ case 0x1b: 1.464 ++ if (G.rat_buttons) 1.465 ++ killed(0); 1.466 ++ if (i + 2 < nr && key[i + 1] == '[') { 1.467 ++ static const char arr2vnc[] = "HDACB"; 1.468 ++ char *p = strchr(arr2vnc, key[i + 2]); 1.469 ++ 1.470 ++ if (p) { 1.471 ++ k = p - arr2vnc + 0xff50; 1.472 ++ i += 2; 1.473 ++ break; 1.474 ++ } 1.475 ++ } 1.476 ++ if (i + 1 < nr) { 1.477 ++ mod[nmod++] = 0xffe9; 1.478 ++ i++; 1.479 ++ } 1.480 ++ case 0x09: 1.481 ++ case 0x0d: 1.482 ++ k = 0xff00; 1.483 ++ goto getkey; 1.484 ++ case 0x0c: /* Mouse button + ^L: redraw */ 1.485 ++ if (G.rat_buttons) { 1.486 ++ vnc_refresh(0); 1.487 ++ continue; 1.488 ++ } 1.489 ++ default: 1.490 ++ getkey: 1.491 ++ k += (unsigned char) key[i]; 1.492 ++ } 1.493 ++ if ((k >= 'A' && k <= 'Z') || strchr(":\"<>?{}|+_()*&^%$#@!~", k)) 1.494 ++ mod[nmod++] = 0xffe1; 1.495 ++ if (k >= 1 && k <= 26) { 1.496 ++ k += 'a' - 1; 1.497 ++ mod[nmod++] = 0xffe3; 1.498 ++ } 1.499 ++ mod[nmod] = k; 1.500 ++ for (j = 0; j <= nmod; j++) 1.501 ++ press(mod[j], 1); 1.502 ++ press(k, 0); 1.503 ++ for (j = 0; j < nmod; j++) 1.504 ++ press(mod[j], 0); 1.505 ++ } 1.506 ++} 1.507 ++ 1.508 ++static void term_setup(void) 1.509 ++{ 1.510 ++ struct termios termios; 1.511 ++#define INITSTR "\x1b[?25l\x1b[2J\x1b[H** fbvnc **" 1.512 ++ 1.513 ++ write(STDOUT_FILENO, INITSTR, sizeof(INITSTR)); 1.514 ++ tcgetattr (STDIN_FILENO, &termios); 1.515 ++ G.term_orig = termios; 1.516 ++ cfmakeraw(&termios); 1.517 ++ tcsetattr_stdin_TCSANOW(&termios); 1.518 ++} 1.519 ++ 1.520 ++int fbvnc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1.521 ++int fbvnc_main(int argc, char **argv) 1.522 ++{ 1.523 ++ char *host = (char *) "127.0.0.1"; 1.524 ++ int port, pending = 0; 1.525 ++ 1.526 ++ INIT_G(); 1.527 ++ if (argc >= 2) 1.528 ++ host = argv[1]; 1.529 ++ port = bb_lookup_port((argc >= 3) ? argv[2] : "vnc", "tcp", 5900); 1.530 ++ G.vnc_fd = create_and_connect_stream_or_die(host, port); 1.531 ++ vnc_init(); 1.532 ++ G.rat_fd = open("/dev/input/mice", O_RDWR); 1.533 ++ write(G.rat_fd, "\xf3\xc8\xf3\x64\xf3\x50", 6); /* for using mouse wheel */ 1.534 ++ read(G.rat_fd, line_buffer, 1); 1.535 ++ term_setup(); 1.536 ++ atexit(cleanup); 1.537 ++ bb_signals(BB_FATAL_SIGS, killed); 1.538 ++ 1.539 ++ G.ufds[0].events = 1.540 ++ G.ufds[1].events = 1.541 ++ G.ufds[2].events = POLLIN; 1.542 ++ vnc_refresh(0); 1.543 ++ while (1) { 1.544 ++ int status = poll(G.ufds, 3, 500); 1.545 ++ if (status == -1 && errno != EINTR) 1.546 ++ killed(1); 1.547 ++ if (!status) 1.548 ++ continue; 1.549 ++ if (G.ufds[0].revents & POLLIN) 1.550 ++ kbd_event(); 1.551 ++ if (G.ufds[1].revents & POLLIN) { 1.552 ++ vnc_event(); 1.553 ++ pending = 0; 1.554 ++ } 1.555 ++ if (G.ufds[2].revents & POLLIN) 1.556 ++ rat_event(); 1.557 ++ if (!pending++) 1.558 ++ vnc_refresh(1); 1.559 ++ } 1.560 ++} 1.561 +--- /dev/null 1.562 ++++ busybox/util-linux/vnc.h 1.563 +@@ -0,0 +1,124 @@ 1.564 ++#define VNC_CONN_FAILED 0 1.565 ++#define VNC_CONN_NOAUTH 1 1.566 ++#define VNC_CONN_AUTH 2 1.567 ++ 1.568 ++#define VNC_AUTH_OK 0 1.569 ++#define VNC_AUTH_FAILED 1 1.570 ++#define VNC_AUTH_TOOMANY 2 1.571 ++ 1.572 ++#define VNC_SERVER_FBUP 0 1.573 ++#define VNC_SERVER_COLORMAP 1 1.574 ++#define VNC_SERVER_BELL 2 1.575 ++#define VNC_SERVER_CUTTEXT 3 1.576 ++ 1.577 ++#define VNC_CLIENT_PIXFMT 0 1.578 ++#define VNC_CLIENT_COLORMAP 1 1.579 ++#define VNC_CLIENT_SETENC 2 1.580 ++#define VNC_CLIENT_FBUP 3 1.581 ++#define VNC_CLIENT_KEYEVENT 4 1.582 ++#define VNC_CLIENT_RATEVENT 5 1.583 ++#define VNC_CLIENT_CUTTEXT 6 1.584 ++ 1.585 ++#define VNC_ENC_RAW 0 1.586 ++#define VNC_ENC_COPYRECT 1 1.587 ++#define VNC_ENC_RRE 2 1.588 ++#define VNC_ENC_CORRE 4 1.589 ++#define VNC_ENC_HEXTILE 5 1.590 ++ 1.591 ++#define VNC_BUTTON1_MASK 0x01 1.592 ++#define VNC_BUTTON2_MASK 0x02 1.593 ++#define VNC_BUTTON3_MASK 0x04 1.594 ++#define VNC_BUTTON4_MASK 0x10 1.595 ++#define VNC_BUTTON5_MASK 0x08 1.596 ++ 1.597 ++typedef unsigned char u8; 1.598 ++typedef unsigned short u16; 1.599 ++typedef unsigned int u32; 1.600 ++ 1.601 ++struct vnc_pixelfmt { 1.602 ++ u8 bpp; 1.603 ++ u8 depth; 1.604 ++ u8 bigendian; 1.605 ++ u8 truecolor; 1.606 ++ u16 rmax; 1.607 ++ u16 gmax; 1.608 ++ u16 bmax; 1.609 ++ u8 rshl; 1.610 ++ u8 gshl; 1.611 ++ u8 bshl; 1.612 ++ 1.613 ++ u8 pad1; 1.614 ++ u16 pad2; 1.615 ++}; 1.616 ++ 1.617 ++struct vnc_client_init { 1.618 ++ u8 shared; 1.619 ++}; 1.620 ++ 1.621 ++struct vnc_server_init { 1.622 ++ u16 w; 1.623 ++ u16 h; 1.624 ++ struct vnc_pixelfmt fmt; 1.625 ++ u32 len; 1.626 ++ /* char name[len]; */ 1.627 ++}; 1.628 ++ 1.629 ++struct vnc_rect { 1.630 ++ u16 x, y; 1.631 ++ u16 w, h; 1.632 ++ u32 enc; 1.633 ++ /* rect bytes */ 1.634 ++}; 1.635 ++ 1.636 ++struct vnc_server_fbup { 1.637 ++ u8 type; 1.638 ++ u8 pad; 1.639 ++ u16 n; 1.640 ++ /* struct vnc_rect rects[n]; */ 1.641 ++}; 1.642 ++ 1.643 ++struct vnc_server_cuttext { 1.644 ++ u8 type; 1.645 ++ u8 pad1; 1.646 ++ u16 pad2; 1.647 ++ u32 len; 1.648 ++ /* char text[length] */ 1.649 ++}; 1.650 ++ 1.651 ++struct vnc_server_colormap { 1.652 ++ u8 type; 1.653 ++ u8 pad; 1.654 ++ u16 first; 1.655 ++ u16 n; 1.656 ++ /* u8 colors[n * 3 * 2]; */ 1.657 ++}; 1.658 ++ 1.659 ++struct vnc_client_pixelfmt { 1.660 ++ u8 type; 1.661 ++ u8 pad1; 1.662 ++ u16 pad2; 1.663 ++ struct vnc_pixelfmt format; 1.664 ++}; 1.665 ++ 1.666 ++struct vnc_client_fbup { 1.667 ++ u8 type; 1.668 ++ u8 inc; 1.669 ++ u16 x; 1.670 ++ u16 y; 1.671 ++ u16 w; 1.672 ++ u16 h; 1.673 ++}; 1.674 ++ 1.675 ++struct vnc_client_keyevent { 1.676 ++ u8 type; 1.677 ++ u8 down; 1.678 ++ u16 pad; 1.679 ++ u32 key; 1.680 ++}; 1.681 ++ 1.682 ++struct vnc_client_ratevent { 1.683 ++ u8 type; 1.684 ++ u8 mask; 1.685 ++ u16 x; 1.686 ++ u16 y; 1.687 ++};