wok rev 17271
busybox: add fbvnc
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Oct 24 16:26:40 2014 +0200 (2014-10-24) |
parents | 7c22b4192384 |
children | d03507a03d90 |
files | busybox/receipt busybox/stuff/busybox-1.22-fbvnc.u busybox/stuff/busybox-1.22.config busybox/stuff/busybox-1.22.config-ssfs busybox/stuff/busybox-1.22.config-static |
line diff
1.1 --- a/busybox/receipt Fri Oct 24 12:46:53 2014 +0200 1.2 +++ b/busybox/receipt Fri Oct 24 16:26:40 2014 +0200 1.3 @@ -44,7 +44,7 @@ 1.4 diet.u 1.5 losetup.u 1.6 fatattr.u 1.7 -dpkg_deb-xz.u 1.8 +fbvnc.u 1.9 EOT 1.10 cp $stuff/$PACKAGE-${VERSION%.*}.config .config 1.11 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/busybox/stuff/busybox-1.22-fbvnc.u Fri Oct 24 16:26:40 2014 +0200 2.3 @@ -0,0 +1,681 @@ 2.4 + text data bss dec hex filename 2.5 + 3118 0 0 3118 c2e util-linux/fbvnc.o 2.6 +--- /dev/null 2.7 ++++ busybox/util-linux/fbvnc.c 2.8 +@@ -0,0 +1,551 @@ 2.9 ++/* vi: set sw=4 ts=4: */ 2.10 ++/* 2.11 ++ * A small linux framebuffer VNC viewer 2.12 ++ * 2.13 ++ * pascal.bellard@ads-lu.com 2.14 ++ * 2.15 ++ * Based on Ali Gholami Rudi's fbvnc.c 2.16 ++ * http://repo.or.cz/w/fbvnc.git 2.17 ++ * 2.18 ++ * Licensed under GPLv2 or later, see file LICENSE in this source tree. 2.19 ++ */ 2.20 ++ 2.21 ++//applet:IF_FBVNC(APPLET(fbvnc, BB_DIR_BIN, BB_SUID_DROP)) 2.22 ++ 2.23 ++//kbuild:lib-$(CONFIG_FBVNC) += fbvnc.o 2.24 ++ 2.25 ++//config:config FBVNC 2.26 ++//config: bool "fbvnc" 2.27 ++//config: default n 2.28 ++//config: depends on PLATFORM_LINUX 2.29 ++//config: help 2.30 ++//config: A linux framebuffer VNC viewer. 2.31 ++ 2.32 ++//usage:#define fbvnc_trivial_usage 2.33 ++//usage: "[VNC_SERVER] [PORT]" 2.34 ++//usage:#define fbvnc_full_usage "\n\n" 2.35 ++//usage: "A linux framebuffer VNC viewer." 2.36 ++//usage: "\nTo exit, move mouse to upper left corner and press ESC." 2.37 ++ 2.38 ++#include "libbb.h" 2.39 ++#include "vnc.h" 2.40 ++ 2.41 ++/* Stuff stolen from the kernel's fb.h */ 2.42 ++#define FB_ACTIVATE_ALL 64 2.43 ++enum { 2.44 ++ FBIOGET_VSCREENINFO = 0x4600, 2.45 ++ FBIOPUT_VSCREENINFO = 0x4601, 2.46 ++ FBIOGET_FSCREENINFO = 0x4602, 2.47 ++ FBIOGETCMAP = 0x4604, 2.48 ++ FBIOPUTCMAP = 0x4605 2.49 ++}; 2.50 ++ 2.51 ++struct fb_bitfield { 2.52 ++ uint32_t offset; /* beginning of bitfield */ 2.53 ++ uint32_t length; /* length of bitfield */ 2.54 ++ uint32_t msb_right; /* !=0: Most significant bit is right */ 2.55 ++}; 2.56 ++struct fb_var_screeninfo { 2.57 ++ uint32_t xres; /* visible resolution */ 2.58 ++ uint32_t yres; 2.59 ++ uint32_t xres_virtual; /* virtual resolution */ 2.60 ++ uint32_t yres_virtual; 2.61 ++ uint32_t xoffset; /* offset from virtual to visible */ 2.62 ++ uint32_t yoffset; /* resolution */ 2.63 ++ 2.64 ++ uint32_t bits_per_pixel; 2.65 ++ uint32_t grayscale; /* !=0 Graylevels instead of colors */ 2.66 ++ 2.67 ++ struct fb_bitfield red; /* bitfield in fb mem if true color, */ 2.68 ++ struct fb_bitfield green; /* else only length is significant */ 2.69 ++ struct fb_bitfield blue; 2.70 ++ struct fb_bitfield transp; /* transparency */ 2.71 ++ 2.72 ++ uint32_t nonstd; /* !=0 Non standard pixel format */ 2.73 ++ 2.74 ++ uint32_t activate; /* see FB_ACTIVATE_x */ 2.75 ++ 2.76 ++ uint32_t height; /* height of picture in mm */ 2.77 ++ uint32_t width; /* width of picture in mm */ 2.78 ++ 2.79 ++ uint32_t accel_flags; /* acceleration flags (hints) */ 2.80 ++ 2.81 ++ /* Timing: All values in pixclocks, except pixclock (of course) */ 2.82 ++ uint32_t pixclock; /* pixel clock in ps (pico seconds) */ 2.83 ++ uint32_t left_margin; /* time from sync to picture */ 2.84 ++ uint32_t right_margin; /* time from picture to sync */ 2.85 ++ uint32_t upper_margin; /* time from sync to picture */ 2.86 ++ uint32_t lower_margin; 2.87 ++ uint32_t hsync_len; /* length of horizontal sync */ 2.88 ++ uint32_t vsync_len; /* length of vertical sync */ 2.89 ++ uint32_t sync; /* see FB_SYNC_x */ 2.90 ++ uint32_t vmode; /* see FB_VMODE_x */ 2.91 ++ uint32_t reserved[6]; /* Reserved for future compatibility */ 2.92 ++}; 2.93 ++ 2.94 ++#define DEFAULTFBDEV FB_0 2.95 ++ 2.96 ++struct fb_fix_screeninfo { 2.97 ++ char id[16]; /* identification string eg "TT Builtin" */ 2.98 ++ unsigned long smem_start; /* Start of frame buffer mem */ 2.99 ++ /* (physical address) */ 2.100 ++ uint32_t smem_len; /* Length of frame buffer mem */ 2.101 ++ uint32_t type; /* see FB_TYPE_* */ 2.102 ++ uint32_t type_aux; /* Interleave for interleaved Planes */ 2.103 ++ uint32_t visual; /* see FB_VISUAL_* */ 2.104 ++ uint16_t xpanstep; /* zero if no hardware panning */ 2.105 ++ uint16_t ypanstep; /* zero if no hardware panning */ 2.106 ++ uint16_t ywrapstep; /* zero if no hardware ywrap */ 2.107 ++ uint32_t line_length; /* length of a line in bytes */ 2.108 ++ unsigned long mmio_start; /* Start of Memory Mapped I/O */ 2.109 ++ /* (physical address) */ 2.110 ++ uint32_t mmio_len; /* Length of Memory Mapped I/O */ 2.111 ++ uint32_t accel; /* Indicate to driver which */ 2.112 ++ /* specific chip/card we have */ 2.113 ++ uint16_t reserved[3]; /* Reserved for future compatibility */ 2.114 ++}; 2.115 ++ 2.116 ++struct fb_cmap { 2.117 ++ uint32_t start; /* First entry */ 2.118 ++ uint32_t len; /* Number of entries */ 2.119 ++ uint16_t *red; /* Red values */ 2.120 ++ uint16_t *green; 2.121 ++ uint16_t *blue; 2.122 ++ uint16_t *transp; /* transparency, can be NULL */ 2.123 ++}; 2.124 ++ 2.125 ++#define FB_VISUAL_TRUECOLOR 2 /* True color */ 2.126 ++ 2.127 ++#define COLORLEVELS (1 << 8) 2.128 ++ 2.129 ++struct scroll_data { 2.130 ++ int size; 2.131 ++ int srv_size; 2.132 ++ int offset; 2.133 ++ int pos; 2.134 ++}; 2.135 ++ 2.136 ++struct globals { 2.137 ++ struct termios term_orig; 2.138 ++ struct pollfd ufds[3]; 2.139 ++#define kbd_fd ufds[0].fd 2.140 ++#define vnc_fd ufds[1].fd 2.141 ++#define rat_fd ufds[2].fd 2.142 ++ struct scroll_data scroll[2]; 2.143 ++#define cols scroll[0].size 2.144 ++#define srv_cols scroll[0].srv_size 2.145 ++#define oc scroll[0].offset 2.146 ++#define mc scroll[0].pos 2.147 ++#define rows scroll[1].size 2.148 ++#define srv_rows scroll[1].srv_size 2.149 ++#define or scroll[1].offset 2.150 ++#define mr scroll[1].pos 2.151 ++ int fb_fd; 2.152 ++ void *fb_ptr; 2.153 ++ int bpp; 2.154 ++ int nr, ng, nb; 2.155 ++ struct fb_var_screeninfo vinfo; 2.156 ++ struct fb_fix_screeninfo finfo; 2.157 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 2.158 ++}; 2.159 ++ 2.160 ++#define G (*ptr_to_globals) 2.161 ++#define INIT_G() do { \ 2.162 ++ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 2.163 ++} while (0) 2.164 ++ 2.165 ++static int fb_len(void) 2.166 ++{ 2.167 ++ return G.finfo.line_length * G.vinfo.yres_virtual; 2.168 ++} 2.169 ++ 2.170 ++static void fb_ioctl_cmap(int fct, struct fb_cmap *cmap) 2.171 ++{ 2.172 ++ if (G.finfo.visual == FB_VISUAL_TRUECOLOR) 2.173 ++ return; 2.174 ++ cmap->start = 0; 2.175 ++ cmap->len = MAX(G.nr, MAX(G.ng, G.nb)); 2.176 ++ cmap->transp = NULL; 2.177 ++ xioctl(G.fb_fd, fct, cmap); 2.178 ++} 2.179 ++ 2.180 ++static void fb_cmap_save(int save) 2.181 ++{ 2.182 ++ struct fb_cmap cmap; 2.183 ++ 2.184 ++ cmap.red = G.red; 2.185 ++ cmap.green = G.green; 2.186 ++ cmap.blue = G.blue; 2.187 ++ fb_ioctl_cmap(save ? FBIOGETCMAP : FBIOPUTCMAP, &cmap); 2.188 ++} 2.189 ++ 2.190 ++static void fb_build_cmap(unsigned short *color, int n) 2.191 ++{ 2.192 ++ int i, inc = 65535 / (n - 1); 2.193 ++ 2.194 ++ for (i = 0; n--; i += inc) 2.195 ++ *color++ = i; 2.196 ++} 2.197 ++ 2.198 ++static void fb_cmap(void) 2.199 ++{ 2.200 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 2.201 ++ struct fb_cmap cmap; 2.202 ++ 2.203 ++ fb_build_cmap(cmap.red = red, G.nr); 2.204 ++ fb_build_cmap(cmap.green = green, G.ng); 2.205 ++ fb_build_cmap(cmap.blue = blue, G.nb); 2.206 ++ fb_ioctl_cmap(FBIOPUTCMAP, &cmap); 2.207 ++} 2.208 ++ 2.209 ++static void fb_init(void) 2.210 ++{ 2.211 ++ G.fb_fd = xopen(DEFAULTFBDEV, O_RDWR); 2.212 ++ xioctl(G.fb_fd, FBIOGET_VSCREENINFO, &G.vinfo); 2.213 ++ xioctl(G.fb_fd, FBIOGET_FSCREENINFO, &G.finfo); 2.214 ++ close_on_exec_on(G.fb_fd); 2.215 ++ G.fb_ptr = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, G.fb_fd, 0); 2.216 ++ if (G.fb_ptr == MAP_FAILED) 2.217 ++ bb_perror_msg_and_die("mmap"); 2.218 ++ G.bpp = (G.vinfo.bits_per_pixel + 7) >> 3; 2.219 ++ G.nr = 1 << G.vinfo.red.length; 2.220 ++ G.nb = 1 << G.vinfo.blue.length; 2.221 ++ G.ng = 1 << G.vinfo.green.length; 2.222 ++ fb_cmap_save(1); 2.223 ++ fb_cmap(); 2.224 ++} 2.225 ++ 2.226 ++static void fb_free(void) 2.227 ++{ 2.228 ++ fb_cmap_save(0); 2.229 ++ munmap(G.fb_ptr, fb_len()); 2.230 ++ close(G.fb_fd); 2.231 ++} 2.232 ++ 2.233 ++#define fb_rows vinfo.yres 2.234 ++#define fb_cols vinfo.xres 2.235 ++ 2.236 ++static void fb_set(int r, int c, void *mem, int len) 2.237 ++{ 2.238 ++ memcpy(G.fb_ptr + (r + G.vinfo.yoffset) * G.finfo.line_length + 2.239 ++ (c + G.vinfo.xoffset) * G.bpp, mem, len * G.bpp); 2.240 ++} 2.241 ++ 2.242 ++#define line_buffer bb_common_bufsiz1 2.243 ++#define MAXPIX (sizeof(line_buffer)/sizeof(uint32_t)) 2.244 ++ 2.245 ++static void skip(int len) 2.246 ++{ 2.247 ++ int n; 2.248 ++ while (len > 0 && (n = read(G.vnc_fd, line_buffer, 2.249 ++ MIN(len, sizeof(line_buffer)))) > 0) 2.250 ++ len -= n; 2.251 ++} 2.252 ++ 2.253 ++static void vnc_init(void) 2.254 ++{ 2.255 ++ struct vnc_client_init clientinit; 2.256 ++ struct vnc_server_init serverinit; 2.257 ++ struct vnc_client_pixelfmt pixfmt_cmd; 2.258 ++ int connstat = VNC_CONN_FAILED; 2.259 ++ 2.260 ++ write(G.vnc_fd, "RFB 003.003\n", 12); 2.261 ++ skip(12); 2.262 ++ 2.263 ++ xread(G.vnc_fd, &connstat, sizeof(connstat)); 2.264 ++ 2.265 ++ if (ntohl(connstat) != VNC_CONN_NOAUTH) 2.266 ++ bb_perror_msg_and_die("vnc auth"); 2.267 ++ 2.268 ++ clientinit.shared = 1; 2.269 ++ write(G.vnc_fd, &clientinit, sizeof(clientinit)); 2.270 ++ read(G.vnc_fd, &serverinit, sizeof(serverinit)); 2.271 ++ 2.272 ++ fb_init(); 2.273 ++ G.srv_cols = ntohs(serverinit.w); 2.274 ++ G.srv_rows = ntohs(serverinit.h); 2.275 ++ G.cols = MIN(G.srv_cols, G.fb_cols); 2.276 ++ G.rows = MIN(G.srv_rows, G.fb_rows); 2.277 ++ G.mr = G.rows / 2; 2.278 ++ G.mc = G.cols / 2; 2.279 ++ 2.280 ++ skip(ntohl(serverinit.len)); 2.281 ++ pixfmt_cmd.type = VNC_CLIENT_PIXFMT; 2.282 ++ pixfmt_cmd.format.bigendian = 0; 2.283 ++ pixfmt_cmd.format.truecolor = 1; 2.284 ++ pixfmt_cmd.format.bpp = 2.285 ++ pixfmt_cmd.format.depth = G.bpp << 3; 2.286 ++ pixfmt_cmd.format.rmax = htons(G.nr - 1); 2.287 ++ pixfmt_cmd.format.gmax = htons(G.ng - 1); 2.288 ++ pixfmt_cmd.format.bmax = htons(G.nb - 1); 2.289 ++ pixfmt_cmd.format.rshl = G.vinfo.red.offset; 2.290 ++ pixfmt_cmd.format.gshl = G.vinfo.green.offset; 2.291 ++ pixfmt_cmd.format.bshl = G.vinfo.blue.offset; 2.292 ++ write(G.vnc_fd, &pixfmt_cmd, sizeof(pixfmt_cmd)); 2.293 ++} 2.294 ++ 2.295 ++static void vnc_refresh(int inc) 2.296 ++{ 2.297 ++ struct vnc_client_fbup fbup_req; 2.298 ++ fbup_req.type = VNC_CLIENT_FBUP; 2.299 ++ fbup_req.inc = inc; 2.300 ++ fbup_req.x = htons(G.oc); 2.301 ++ fbup_req.y = htons(G.or); 2.302 ++ fbup_req.w = htons(G.oc + G.cols); 2.303 ++ fbup_req.h = htons(G.or + G.rows); 2.304 ++ write(G.vnc_fd, &fbup_req, sizeof(fbup_req)); 2.305 ++} 2.306 ++ 2.307 ++static void cleanup(void) 2.308 ++{ 2.309 ++ const char *reset = "\x1b[?25h" "\x1b[2J\x1b[H"; 2.310 ++ fb_free(); 2.311 ++ tcsetattr_stdin_TCSANOW(&G.term_orig); 2.312 ++ write(STDOUT_FILENO, reset, strlen(reset)); 2.313 ++ if (ENABLE_FEATURE_CLEAN_UP) { 2.314 ++ close(G.vnc_fd); 2.315 ++ close(G.rat_fd); 2.316 ++ } 2.317 ++} 2.318 ++ 2.319 ++static void killed(int code) NORETURN; 2.320 ++static void killed(int code) 2.321 ++{ 2.322 ++ cleanup(); 2.323 ++ if (code > EXIT_FAILURE) 2.324 ++ kill_myself_with_sig(code); 2.325 ++ exit(code); 2.326 ++} 2.327 ++ 2.328 ++static void vnc_event(void) 2.329 ++{ 2.330 ++ struct vnc_rect uprect; 2.331 ++ union { 2.332 ++ struct vnc_server_fbup fbup; 2.333 ++ struct vnc_server_cuttext cuttext; 2.334 ++ struct vnc_server_colormap colormap; 2.335 ++ } msg; 2.336 ++ int n; 2.337 ++ 2.338 ++ switch (xread_char(G.vnc_fd)) { 2.339 ++ case VNC_SERVER_FBUP: 2.340 ++ xread(G.vnc_fd, &msg.fbup.pad, sizeof(msg.fbup) - 1); 2.341 ++ n = ntohs(msg.fbup.n); 2.342 ++ while (n--) { 2.343 ++ int x, y, w, h, l, i; 2.344 ++ xread(G.vnc_fd, &uprect, sizeof(uprect)); 2.345 ++ if (uprect.enc != 0) 2.346 ++ killed(1); 2.347 ++ i = 0; 2.348 ++ x = ntohs(uprect.x) - G.oc; 2.349 ++ y = ntohs(uprect.y) - G.or; 2.350 ++ w = ntohs(uprect.w); 2.351 ++ h = ntohs(uprect.h); 2.352 ++ l = MIN(w, G.cols - x); 2.353 ++ if (x < 0) { 2.354 ++ l = MIN(w + x, G.cols); 2.355 ++ i = -x; 2.356 ++ x = 0; 2.357 ++ } 2.358 ++ for (; h--; y++) { 2.359 ++ int a, b, c = i; 2.360 ++ for (a = b = 0; w > b; b += a, c = 0) { 2.361 ++ int len; 2.362 ++ a = MIN(w - b, MAXPIX); 2.363 ++ len = MIN(a, l - b) - c; 2.364 ++ xread(G.vnc_fd, line_buffer, a * G.bpp); 2.365 ++ if (y >= 0 && y < G.rows && len > 0) 2.366 ++ fb_set(y, x + b, 2.367 ++ line_buffer + (c * G.bpp), 2.368 ++ len); 2.369 ++ } 2.370 ++ } 2.371 ++ } 2.372 ++ break; 2.373 ++ case VNC_SERVER_BELL: 2.374 ++ break; 2.375 ++ case VNC_SERVER_CUTTEXT: 2.376 ++ xread(G.vnc_fd, &msg.cuttext.pad1, sizeof(msg.cuttext) - 1); 2.377 ++ skip(ntohl(msg.cuttext.len)); 2.378 ++ break; 2.379 ++ case VNC_SERVER_COLORMAP: 2.380 ++ xread(G.vnc_fd, &msg.colormap.pad, sizeof(msg.colormap) - 1); 2.381 ++ skip(ntohs(msg.colormap.n) * 3 * 2); 2.382 ++ break; 2.383 ++ default: 2.384 ++ killed(1); 2.385 ++ } 2.386 ++} 2.387 ++ 2.388 ++static int update_scroll(struct scroll_data *s) 2.389 ++{ 2.390 ++ int shift = s->size / 5; 2.391 ++ int max = s->srv_size - s->size; 2.392 ++ int status = 0; 2.393 ++ if (s->pos < s->offset) { 2.394 ++ if ((s->offset -= shift) < 0) 2.395 ++ s->offset = 0; 2.396 ++ } 2.397 ++ else if (s->pos >= s->offset + s->size && s->offset < max) { 2.398 ++ if ((s->offset += shift) > max) 2.399 ++ s->offset = max; 2.400 ++ } 2.401 ++ else status++; 2.402 ++ s->pos = MAX(s->offset, MIN(s->offset + s->size - 1, s->pos)); 2.403 ++ return status; 2.404 ++} 2.405 ++ 2.406 ++static void rat_event(void) 2.407 ++{ 2.408 ++ signed char ie[3]; 2.409 ++ struct vnc_client_ratevent me = {VNC_CLIENT_RATEVENT}; 2.410 ++ int mask = 0; 2.411 ++ int refresh; 2.412 ++ 2.413 ++ xread(G.rat_fd, &ie, sizeof(ie)); 2.414 ++ G.mc += ie[1]; 2.415 ++ G.mr -= ie[2]; 2.416 ++ refresh = 2 - update_scroll(&G.scroll[0]) - update_scroll(&G.scroll[1]); 2.417 ++ if (ie[0] & 0x01) 2.418 ++ mask |= VNC_BUTTON1_MASK; 2.419 ++ if (ie[0] & 0x04) 2.420 ++ mask |= VNC_BUTTON2_MASK; 2.421 ++ if (ie[0] & 0x02) 2.422 ++ mask |= VNC_BUTTON3_MASK; 2.423 ++ me.y = htons(G.mr); 2.424 ++ me.x = htons(G.mc); 2.425 ++ me.mask = mask; 2.426 ++ write(G.vnc_fd, &me, sizeof(me)); 2.427 ++ if (refresh) 2.428 ++ vnc_refresh(0); 2.429 ++} 2.430 ++ 2.431 ++static int press(int key, int down) 2.432 ++{ 2.433 ++ struct vnc_client_keyevent ke = {VNC_CLIENT_KEYEVENT}; 2.434 ++ ke.key = htonl(key); 2.435 ++ ke.down = down; 2.436 ++ return write(G.vnc_fd, &ke, sizeof(ke)); 2.437 ++} 2.438 ++ 2.439 ++static void kbd_event(void) 2.440 ++{ 2.441 ++ char key[1024]; 2.442 ++ int i, nr; 2.443 ++ 2.444 ++ if ((nr = read(0, key, sizeof(key))) <= 0 ) 2.445 ++ killed(1); 2.446 ++ for (i = 0; i < nr; i++) { 2.447 ++ int k = -1; 2.448 ++ int mod[4]; 2.449 ++ int nmod = 0; 2.450 ++ switch (key[i]) { 2.451 ++ case 0x08: 2.452 ++ case 0x7f: 2.453 ++ k = 0xff08; 2.454 ++ break; 2.455 ++ case 0x09: 2.456 ++ k = 0xff09; 2.457 ++ break; 2.458 ++ case 0x1b: 2.459 ++ if (G.oc + G.mc + G.or + G.mr == 0) 2.460 ++ killed(0); 2.461 ++ if (i + 2 < nr && key[i + 1] == '[') { 2.462 ++ if (key[i + 2] == 'A') 2.463 ++ k = 0xff52; 2.464 ++ if (key[i + 2] == 'B') 2.465 ++ k = 0xff54; 2.466 ++ if (key[i + 2] == 'C') 2.467 ++ k = 0xff53; 2.468 ++ if (key[i + 2] == 'D') 2.469 ++ k = 0xff51; 2.470 ++ if (key[i + 2] == 'H') 2.471 ++ k = 0xff50; 2.472 ++ if (k > 0) { 2.473 ++ i += 2; 2.474 ++ break; 2.475 ++ } 2.476 ++ } 2.477 ++ k = 0xff1b; 2.478 ++ if (i + 1 < nr) { 2.479 ++ mod[nmod++] = 0xffe9; 2.480 ++ k = key[++i]; 2.481 ++ } 2.482 ++ break; 2.483 ++ case 0x0d: 2.484 ++ k = 0xff0d; 2.485 ++ break; 2.486 ++ case 0x0c: /* ^L: redraw */ 2.487 ++ vnc_refresh(0); 2.488 ++ default: 2.489 ++ k = (unsigned char) key[i]; 2.490 ++ } 2.491 ++ if ((k >= 'A' && k <= 'Z') || strchr(":\"<>?{}|+_()*&^%$#@!~", k)) 2.492 ++ mod[nmod++] = 0xffe1; 2.493 ++ if (k >= 1 && k <= 26) { 2.494 ++ k += 'a' - 1; 2.495 ++ mod[nmod++] = 0xffe3; 2.496 ++ } 2.497 ++ if (k > 0) { 2.498 ++ int j; 2.499 ++ mod[nmod] = k; 2.500 ++ for (j = 0; j <= nmod; j++) 2.501 ++ press(mod[j], 1); 2.502 ++ press(k, 0); 2.503 ++ for (j = 0; j < nmod; j++) 2.504 ++ press(mod[j], 0); 2.505 ++ } 2.506 ++ } 2.507 ++} 2.508 ++ 2.509 ++static void term_setup(void) 2.510 ++{ 2.511 ++ struct termios termios; 2.512 ++ const char *init = "\x1b[?25l" "\x1b[2J\x1b[H" "** fbvnc **"; 2.513 ++ 2.514 ++ write(STDOUT_FILENO, init, strlen(init)); 2.515 ++ tcgetattr (STDIN_FILENO, &termios); 2.516 ++ G.term_orig = termios; 2.517 ++ cfmakeraw(&termios); 2.518 ++ tcsetattr_stdin_TCSANOW(&termios); 2.519 ++} 2.520 ++ 2.521 ++int fbvnc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2.522 ++int fbvnc_main(int argc, char **argv) 2.523 ++{ 2.524 ++ char *host = (char *) "127.0.0.1"; 2.525 ++ int port, pending = 0; 2.526 ++ 2.527 ++ INIT_G(); 2.528 ++ if (argc >= 2) 2.529 ++ host = argv[1]; 2.530 ++ port = bb_lookup_port((argc >= 3) ? argv[2] : "vnc", "tcp", 5900); 2.531 ++ G.vnc_fd = create_and_connect_stream_or_die(host, port); 2.532 ++ vnc_init(); 2.533 ++ G.rat_fd = open("/dev/input/mice", O_RDONLY); 2.534 ++ term_setup(); 2.535 ++ atexit(cleanup); 2.536 ++ bb_signals(BB_FATAL_SIGS, killed); 2.537 ++ 2.538 ++ G.ufds[0].events = 2.539 ++ G.ufds[1].events = 2.540 ++ G.ufds[2].events = POLLIN; 2.541 ++ vnc_refresh(0); 2.542 ++ while (1) { 2.543 ++ int status = poll(G.ufds, 3, 500); 2.544 ++ if (status == -1 && errno != EINTR) 2.545 ++ killed(1); 2.546 ++ if (!status) 2.547 ++ continue; 2.548 ++ if (G.ufds[0].revents & POLLIN) 2.549 ++ kbd_event(); 2.550 ++ if (G.ufds[1].revents & POLLIN) { 2.551 ++ vnc_event(); 2.552 ++ pending = 0; 2.553 ++ } 2.554 ++ if (G.ufds[2].revents & POLLIN) 2.555 ++ rat_event(); 2.556 ++ if (!pending++) 2.557 ++ vnc_refresh(1); 2.558 ++ } 2.559 ++} 2.560 +--- /dev/null 2.561 ++++ busybox/util-linux/vnc.h 2.562 +@@ -0,0 +1,122 @@ 2.563 ++#define VNC_CONN_FAILED 0 2.564 ++#define VNC_CONN_NOAUTH 1 2.565 ++#define VNC_CONN_AUTH 2 2.566 ++ 2.567 ++#define VNC_AUTH_OK 0 2.568 ++#define VNC_AUTH_FAILED 1 2.569 ++#define VNC_AUTH_TOOMANY 2 2.570 ++ 2.571 ++#define VNC_SERVER_FBUP 0 2.572 ++#define VNC_SERVER_COLORMAP 1 2.573 ++#define VNC_SERVER_BELL 2 2.574 ++#define VNC_SERVER_CUTTEXT 3 2.575 ++ 2.576 ++#define VNC_CLIENT_PIXFMT 0 2.577 ++#define VNC_CLIENT_COLORMAP 1 2.578 ++#define VNC_CLIENT_SETENC 2 2.579 ++#define VNC_CLIENT_FBUP 3 2.580 ++#define VNC_CLIENT_KEYEVENT 4 2.581 ++#define VNC_CLIENT_RATEVENT 5 2.582 ++#define VNC_CLIENT_CUTTEXT 6 2.583 ++ 2.584 ++#define VNC_ENC_RAW 0 2.585 ++#define VNC_ENC_COPYRECT 1 2.586 ++#define VNC_ENC_RRE 2 2.587 ++#define VNC_ENC_CORRE 4 2.588 ++#define VNC_ENC_HEXTILE 5 2.589 ++ 2.590 ++#define VNC_BUTTON1_MASK 0x1 2.591 ++#define VNC_BUTTON2_MASK 0x2 2.592 ++#define VNC_BUTTON3_MASK 0x4 2.593 ++ 2.594 ++typedef unsigned char u8; 2.595 ++typedef unsigned short u16; 2.596 ++typedef unsigned int u32; 2.597 ++ 2.598 ++struct vnc_pixelfmt { 2.599 ++ u8 bpp; 2.600 ++ u8 depth; 2.601 ++ u8 bigendian; 2.602 ++ u8 truecolor; 2.603 ++ u16 rmax; 2.604 ++ u16 gmax; 2.605 ++ u16 bmax; 2.606 ++ u8 rshl; 2.607 ++ u8 gshl; 2.608 ++ u8 bshl; 2.609 ++ 2.610 ++ u8 pad1; 2.611 ++ u16 pad2; 2.612 ++}; 2.613 ++ 2.614 ++struct vnc_client_init { 2.615 ++ u8 shared; 2.616 ++}; 2.617 ++ 2.618 ++struct vnc_server_init { 2.619 ++ u16 w; 2.620 ++ u16 h; 2.621 ++ struct vnc_pixelfmt fmt; 2.622 ++ u32 len; 2.623 ++ /* char name[len]; */ 2.624 ++}; 2.625 ++ 2.626 ++struct vnc_rect { 2.627 ++ u16 x, y; 2.628 ++ u16 w, h; 2.629 ++ u32 enc; 2.630 ++ /* rect bytes */ 2.631 ++}; 2.632 ++ 2.633 ++struct vnc_server_fbup { 2.634 ++ u8 type; 2.635 ++ u8 pad; 2.636 ++ u16 n; 2.637 ++ /* struct vnc_rect rects[n]; */ 2.638 ++}; 2.639 ++ 2.640 ++struct vnc_server_cuttext { 2.641 ++ u8 type; 2.642 ++ u8 pad1; 2.643 ++ u16 pad2; 2.644 ++ u32 len; 2.645 ++ /* char text[length] */ 2.646 ++}; 2.647 ++ 2.648 ++struct vnc_server_colormap { 2.649 ++ u8 type; 2.650 ++ u8 pad; 2.651 ++ u16 first; 2.652 ++ u16 n; 2.653 ++ /* u8 colors[n * 3 * 2]; */ 2.654 ++}; 2.655 ++ 2.656 ++struct vnc_client_pixelfmt { 2.657 ++ u8 type; 2.658 ++ u8 pad1; 2.659 ++ u16 pad2; 2.660 ++ struct vnc_pixelfmt format; 2.661 ++}; 2.662 ++ 2.663 ++struct vnc_client_fbup { 2.664 ++ u8 type; 2.665 ++ u8 inc; 2.666 ++ u16 x; 2.667 ++ u16 y; 2.668 ++ u16 w; 2.669 ++ u16 h; 2.670 ++}; 2.671 ++ 2.672 ++struct vnc_client_keyevent { 2.673 ++ u8 type; 2.674 ++ u8 down; 2.675 ++ u16 pad; 2.676 ++ u32 key; 2.677 ++}; 2.678 ++ 2.679 ++struct vnc_client_ratevent { 2.680 ++ u8 type; 2.681 ++ u8 mask; 2.682 ++ u16 x; 2.683 ++ u16 y; 2.684 ++};
3.1 --- a/busybox/stuff/busybox-1.22.config Fri Oct 24 12:46:53 2014 +0200 3.2 +++ b/busybox/stuff/busybox-1.22.config Fri Oct 24 16:26:40 2014 +0200 3.3 @@ -527,6 +527,7 @@ 3.4 # Linux System Utilities 3.5 # 3.6 CONFIG_BLOCKDEV=y 3.7 +CONFIG_FBVNC=y 3.8 CONFIG_FSTRIM=y 3.9 # CONFIG_MDEV is not set 3.10 # CONFIG_FEATURE_MDEV_CONF is not set
4.1 --- a/busybox/stuff/busybox-1.22.config-ssfs Fri Oct 24 12:46:53 2014 +0200 4.2 +++ b/busybox/stuff/busybox-1.22.config-ssfs Fri Oct 24 16:26:40 2014 +0200 4.3 @@ -527,6 +527,7 @@ 4.4 # Linux System Utilities 4.5 # 4.6 # CONFIG_BLOCKDEV is not set 4.7 +# CONFIG_FBVNC is not set 4.8 # CONFIG_FSTRIM is not set 4.9 # CONFIG_MDEV is not set 4.10 # CONFIG_FEATURE_MDEV_CONF is not set
5.1 --- a/busybox/stuff/busybox-1.22.config-static Fri Oct 24 12:46:53 2014 +0200 5.2 +++ b/busybox/stuff/busybox-1.22.config-static Fri Oct 24 16:26:40 2014 +0200 5.3 @@ -527,6 +527,7 @@ 5.4 # Linux System Utilities 5.5 # 5.6 # CONFIG_BLOCKDEV is not set 5.7 +# CONFIG_FBVNC is not set 5.8 # CONFIG_FSTRIM is not set 5.9 # CONFIG_MDEV is not set 5.10 # CONFIG_FEATURE_MDEV_CONF is not set