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