wok-next diff busybox/stuff/busybox-1.23-fbvnc.u @ rev 18392
Add: WIP open-vm-tools kernel modules
author | Nathan Neulinger <nneul@neulinger.org> |
---|---|
date | Fri Sep 18 23:50:52 2015 +0000 (2015-09-18) |
parents | |
children | dbf4eeed945f |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/busybox/stuff/busybox-1.23-fbvnc.u Fri Sep 18 23:50:52 2015 +0000 1.3 @@ -0,0 +1,681 @@ 1.4 + text data bss dec hex filename 1.5 + 3118 0 0 3118 c2e 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, move mouse to upper left corner 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 ++ int fb_fd; 1.152 ++ void *fb_ptr; 1.153 ++ int bpp; 1.154 ++ int nr, ng, nb; 1.155 ++ struct fb_var_screeninfo vinfo; 1.156 ++ struct fb_fix_screeninfo finfo; 1.157 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 1.158 ++}; 1.159 ++ 1.160 ++#define G (*ptr_to_globals) 1.161 ++#define INIT_G() do { \ 1.162 ++ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 1.163 ++} while (0) 1.164 ++ 1.165 ++static int fb_len(void) 1.166 ++{ 1.167 ++ return G.finfo.line_length * G.vinfo.yres_virtual; 1.168 ++} 1.169 ++ 1.170 ++static void fb_ioctl_cmap(int fct, struct fb_cmap *cmap) 1.171 ++{ 1.172 ++ if (G.finfo.visual == FB_VISUAL_TRUECOLOR) 1.173 ++ return; 1.174 ++ cmap->start = 0; 1.175 ++ cmap->len = MAX(G.nr, MAX(G.ng, G.nb)); 1.176 ++ cmap->transp = NULL; 1.177 ++ xioctl(G.fb_fd, fct, cmap); 1.178 ++} 1.179 ++ 1.180 ++static void fb_cmap_save(int save) 1.181 ++{ 1.182 ++ struct fb_cmap cmap; 1.183 ++ 1.184 ++ cmap.red = G.red; 1.185 ++ cmap.green = G.green; 1.186 ++ cmap.blue = G.blue; 1.187 ++ fb_ioctl_cmap(save ? FBIOGETCMAP : FBIOPUTCMAP, &cmap); 1.188 ++} 1.189 ++ 1.190 ++static void fb_build_cmap(unsigned short *color, int n) 1.191 ++{ 1.192 ++ int i, inc = 65535 / (n - 1); 1.193 ++ 1.194 ++ for (i = 0; n--; i += inc) 1.195 ++ *color++ = i; 1.196 ++} 1.197 ++ 1.198 ++static void fb_cmap(void) 1.199 ++{ 1.200 ++ unsigned short red[COLORLEVELS], green[COLORLEVELS], blue[COLORLEVELS]; 1.201 ++ struct fb_cmap cmap; 1.202 ++ 1.203 ++ fb_build_cmap(cmap.red = red, G.nr); 1.204 ++ fb_build_cmap(cmap.green = green, G.ng); 1.205 ++ fb_build_cmap(cmap.blue = blue, G.nb); 1.206 ++ fb_ioctl_cmap(FBIOPUTCMAP, &cmap); 1.207 ++} 1.208 ++ 1.209 ++static void fb_init(void) 1.210 ++{ 1.211 ++ G.fb_fd = xopen(DEFAULTFBDEV, O_RDWR); 1.212 ++ xioctl(G.fb_fd, FBIOGET_VSCREENINFO, &G.vinfo); 1.213 ++ xioctl(G.fb_fd, FBIOGET_FSCREENINFO, &G.finfo); 1.214 ++ close_on_exec_on(G.fb_fd); 1.215 ++ G.fb_ptr = mmap(NULL, fb_len(), PROT_READ | PROT_WRITE, MAP_SHARED, G.fb_fd, 0); 1.216 ++ if (G.fb_ptr == MAP_FAILED) 1.217 ++ bb_perror_msg_and_die("mmap"); 1.218 ++ G.bpp = (G.vinfo.bits_per_pixel + 7) >> 3; 1.219 ++ G.nr = 1 << G.vinfo.red.length; 1.220 ++ G.nb = 1 << G.vinfo.blue.length; 1.221 ++ G.ng = 1 << G.vinfo.green.length; 1.222 ++ fb_cmap_save(1); 1.223 ++ fb_cmap(); 1.224 ++} 1.225 ++ 1.226 ++static void fb_free(void) 1.227 ++{ 1.228 ++ fb_cmap_save(0); 1.229 ++ munmap(G.fb_ptr, fb_len()); 1.230 ++ close(G.fb_fd); 1.231 ++} 1.232 ++ 1.233 ++#define fb_rows vinfo.yres 1.234 ++#define fb_cols vinfo.xres 1.235 ++ 1.236 ++static void fb_set(int r, int c, void *mem, int len) 1.237 ++{ 1.238 ++ memcpy(G.fb_ptr + (r + G.vinfo.yoffset) * G.finfo.line_length + 1.239 ++ (c + G.vinfo.xoffset) * G.bpp, mem, len * G.bpp); 1.240 ++} 1.241 ++ 1.242 ++#define line_buffer bb_common_bufsiz1 1.243 ++#define MAXPIX (sizeof(line_buffer)/sizeof(uint32_t)) 1.244 ++ 1.245 ++static void skip(int len) 1.246 ++{ 1.247 ++ int n; 1.248 ++ while (len > 0 && (n = read(G.vnc_fd, line_buffer, 1.249 ++ MIN(len, sizeof(line_buffer)))) > 0) 1.250 ++ len -= n; 1.251 ++} 1.252 ++ 1.253 ++static void vnc_init(void) 1.254 ++{ 1.255 ++ struct vnc_client_init clientinit; 1.256 ++ struct vnc_server_init serverinit; 1.257 ++ struct vnc_client_pixelfmt pixfmt_cmd; 1.258 ++ int connstat = VNC_CONN_FAILED; 1.259 ++ 1.260 ++ write(G.vnc_fd, "RFB 003.003\n", 12); 1.261 ++ skip(12); 1.262 ++ 1.263 ++ xread(G.vnc_fd, &connstat, sizeof(connstat)); 1.264 ++ 1.265 ++ if (ntohl(connstat) != VNC_CONN_NOAUTH) 1.266 ++ bb_perror_msg_and_die("vnc auth"); 1.267 ++ 1.268 ++ clientinit.shared = 1; 1.269 ++ write(G.vnc_fd, &clientinit, sizeof(clientinit)); 1.270 ++ read(G.vnc_fd, &serverinit, sizeof(serverinit)); 1.271 ++ 1.272 ++ fb_init(); 1.273 ++ G.srv_cols = ntohs(serverinit.w); 1.274 ++ G.srv_rows = ntohs(serverinit.h); 1.275 ++ G.cols = MIN(G.srv_cols, G.fb_cols); 1.276 ++ G.rows = MIN(G.srv_rows, G.fb_rows); 1.277 ++ G.mr = G.rows / 2; 1.278 ++ G.mc = G.cols / 2; 1.279 ++ 1.280 ++ skip(ntohl(serverinit.len)); 1.281 ++ pixfmt_cmd.type = VNC_CLIENT_PIXFMT; 1.282 ++ pixfmt_cmd.format.bigendian = 0; 1.283 ++ pixfmt_cmd.format.truecolor = 1; 1.284 ++ pixfmt_cmd.format.bpp = 1.285 ++ pixfmt_cmd.format.depth = G.bpp << 3; 1.286 ++ pixfmt_cmd.format.rmax = htons(G.nr - 1); 1.287 ++ pixfmt_cmd.format.gmax = htons(G.ng - 1); 1.288 ++ pixfmt_cmd.format.bmax = htons(G.nb - 1); 1.289 ++ pixfmt_cmd.format.rshl = G.vinfo.red.offset; 1.290 ++ pixfmt_cmd.format.gshl = G.vinfo.green.offset; 1.291 ++ pixfmt_cmd.format.bshl = G.vinfo.blue.offset; 1.292 ++ write(G.vnc_fd, &pixfmt_cmd, sizeof(pixfmt_cmd)); 1.293 ++} 1.294 ++ 1.295 ++static void vnc_refresh(int inc) 1.296 ++{ 1.297 ++ struct vnc_client_fbup fbup_req; 1.298 ++ fbup_req.type = VNC_CLIENT_FBUP; 1.299 ++ fbup_req.inc = inc; 1.300 ++ fbup_req.x = htons(G.oc); 1.301 ++ fbup_req.y = htons(G.or); 1.302 ++ fbup_req.w = htons(G.oc + G.cols); 1.303 ++ fbup_req.h = htons(G.or + G.rows); 1.304 ++ write(G.vnc_fd, &fbup_req, sizeof(fbup_req)); 1.305 ++} 1.306 ++ 1.307 ++static void cleanup(void) 1.308 ++{ 1.309 ++ const char *reset = "\x1b[?25h" "\x1b[2J\x1b[H"; 1.310 ++ fb_free(); 1.311 ++ tcsetattr_stdin_TCSANOW(&G.term_orig); 1.312 ++ write(STDOUT_FILENO, reset, strlen(reset)); 1.313 ++ if (ENABLE_FEATURE_CLEAN_UP) { 1.314 ++ close(G.vnc_fd); 1.315 ++ close(G.rat_fd); 1.316 ++ } 1.317 ++} 1.318 ++ 1.319 ++static void killed(int code) NORETURN; 1.320 ++static void killed(int code) 1.321 ++{ 1.322 ++ cleanup(); 1.323 ++ if (code > EXIT_FAILURE) 1.324 ++ kill_myself_with_sig(code); 1.325 ++ exit(code); 1.326 ++} 1.327 ++ 1.328 ++static void vnc_event(void) 1.329 ++{ 1.330 ++ struct vnc_rect uprect; 1.331 ++ union { 1.332 ++ struct vnc_server_fbup fbup; 1.333 ++ struct vnc_server_cuttext cuttext; 1.334 ++ struct vnc_server_colormap colormap; 1.335 ++ } msg; 1.336 ++ int n; 1.337 ++ 1.338 ++ switch (xread_char(G.vnc_fd)) { 1.339 ++ case VNC_SERVER_FBUP: 1.340 ++ xread(G.vnc_fd, &msg.fbup.pad, sizeof(msg.fbup) - 1); 1.341 ++ n = ntohs(msg.fbup.n); 1.342 ++ while (n--) { 1.343 ++ int x, y, w, h, l, i; 1.344 ++ xread(G.vnc_fd, &uprect, sizeof(uprect)); 1.345 ++ if (uprect.enc != 0) 1.346 ++ killed(1); 1.347 ++ i = 0; 1.348 ++ x = ntohs(uprect.x) - G.oc; 1.349 ++ y = ntohs(uprect.y) - G.or; 1.350 ++ w = ntohs(uprect.w); 1.351 ++ h = ntohs(uprect.h); 1.352 ++ l = MIN(w, G.cols - x); 1.353 ++ if (x < 0) { 1.354 ++ l = MIN(w + x, G.cols); 1.355 ++ i = -x; 1.356 ++ x = 0; 1.357 ++ } 1.358 ++ for (; h--; y++) { 1.359 ++ int a, b, c = i; 1.360 ++ for (a = b = 0; w > b; b += a, c = 0) { 1.361 ++ int len; 1.362 ++ a = MIN(w - b, MAXPIX); 1.363 ++ len = MIN(a, l - b) - c; 1.364 ++ xread(G.vnc_fd, line_buffer, a * G.bpp); 1.365 ++ if (y >= 0 && y < G.rows && len > 0) 1.366 ++ fb_set(y, x + b, 1.367 ++ line_buffer + (c * G.bpp), 1.368 ++ len); 1.369 ++ } 1.370 ++ } 1.371 ++ } 1.372 ++ break; 1.373 ++ case VNC_SERVER_BELL: 1.374 ++ break; 1.375 ++ case VNC_SERVER_CUTTEXT: 1.376 ++ xread(G.vnc_fd, &msg.cuttext.pad1, sizeof(msg.cuttext) - 1); 1.377 ++ skip(ntohl(msg.cuttext.len)); 1.378 ++ break; 1.379 ++ case VNC_SERVER_COLORMAP: 1.380 ++ xread(G.vnc_fd, &msg.colormap.pad, sizeof(msg.colormap) - 1); 1.381 ++ skip(ntohs(msg.colormap.n) * 3 * 2); 1.382 ++ break; 1.383 ++ default: 1.384 ++ killed(1); 1.385 ++ } 1.386 ++} 1.387 ++ 1.388 ++static int update_scroll(struct scroll_data *s) 1.389 ++{ 1.390 ++ int shift = s->size / 5; 1.391 ++ int max = s->srv_size - s->size; 1.392 ++ int status = 0; 1.393 ++ if (s->pos < s->offset) { 1.394 ++ if ((s->offset -= shift) < 0) 1.395 ++ s->offset = 0; 1.396 ++ } 1.397 ++ else if (s->pos >= s->offset + s->size && s->offset < max) { 1.398 ++ if ((s->offset += shift) > max) 1.399 ++ s->offset = max; 1.400 ++ } 1.401 ++ else status++; 1.402 ++ s->pos = MAX(s->offset, MIN(s->offset + s->size - 1, s->pos)); 1.403 ++ return status; 1.404 ++} 1.405 ++ 1.406 ++static void rat_event(void) 1.407 ++{ 1.408 ++ signed char ie[3]; 1.409 ++ struct vnc_client_ratevent me = {VNC_CLIENT_RATEVENT}; 1.410 ++ int mask = 0; 1.411 ++ int refresh; 1.412 ++ 1.413 ++ xread(G.rat_fd, &ie, sizeof(ie)); 1.414 ++ G.mc += ie[1]; 1.415 ++ G.mr -= ie[2]; 1.416 ++ refresh = 2 - update_scroll(&G.scroll[0]) - update_scroll(&G.scroll[1]); 1.417 ++ if (ie[0] & 0x01) 1.418 ++ mask |= VNC_BUTTON1_MASK; 1.419 ++ if (ie[0] & 0x04) 1.420 ++ mask |= VNC_BUTTON2_MASK; 1.421 ++ if (ie[0] & 0x02) 1.422 ++ mask |= VNC_BUTTON3_MASK; 1.423 ++ me.y = htons(G.mr); 1.424 ++ me.x = htons(G.mc); 1.425 ++ me.mask = mask; 1.426 ++ write(G.vnc_fd, &me, sizeof(me)); 1.427 ++ if (refresh) 1.428 ++ vnc_refresh(0); 1.429 ++} 1.430 ++ 1.431 ++static int press(int key, int down) 1.432 ++{ 1.433 ++ struct vnc_client_keyevent ke = {VNC_CLIENT_KEYEVENT}; 1.434 ++ ke.key = htonl(key); 1.435 ++ ke.down = down; 1.436 ++ return write(G.vnc_fd, &ke, sizeof(ke)); 1.437 ++} 1.438 ++ 1.439 ++static void kbd_event(void) 1.440 ++{ 1.441 ++ char key[1024]; 1.442 ++ int i, nr; 1.443 ++ 1.444 ++ if ((nr = read(0, key, sizeof(key))) <= 0 ) 1.445 ++ killed(1); 1.446 ++ for (i = 0; i < nr; i++) { 1.447 ++ int k = -1; 1.448 ++ int mod[4]; 1.449 ++ int nmod = 0; 1.450 ++ switch (key[i]) { 1.451 ++ case 0x08: 1.452 ++ case 0x7f: 1.453 ++ k = 0xff08; 1.454 ++ break; 1.455 ++ case 0x09: 1.456 ++ k = 0xff09; 1.457 ++ break; 1.458 ++ case 0x1b: 1.459 ++ if (G.oc + G.mc + G.or + G.mr == 0) 1.460 ++ killed(0); 1.461 ++ if (i + 2 < nr && key[i + 1] == '[') { 1.462 ++ if (key[i + 2] == 'A') 1.463 ++ k = 0xff52; 1.464 ++ if (key[i + 2] == 'B') 1.465 ++ k = 0xff54; 1.466 ++ if (key[i + 2] == 'C') 1.467 ++ k = 0xff53; 1.468 ++ if (key[i + 2] == 'D') 1.469 ++ k = 0xff51; 1.470 ++ if (key[i + 2] == 'H') 1.471 ++ k = 0xff50; 1.472 ++ if (k > 0) { 1.473 ++ i += 2; 1.474 ++ break; 1.475 ++ } 1.476 ++ } 1.477 ++ k = 0xff1b; 1.478 ++ if (i + 1 < nr) { 1.479 ++ mod[nmod++] = 0xffe9; 1.480 ++ k = key[++i]; 1.481 ++ } 1.482 ++ break; 1.483 ++ case 0x0d: 1.484 ++ k = 0xff0d; 1.485 ++ break; 1.486 ++ case 0x0c: /* ^L: redraw */ 1.487 ++ vnc_refresh(0); 1.488 ++ default: 1.489 ++ k = (unsigned char) key[i]; 1.490 ++ } 1.491 ++ if ((k >= 'A' && k <= 'Z') || strchr(":\"<>?{}|+_()*&^%$#@!~", k)) 1.492 ++ mod[nmod++] = 0xffe1; 1.493 ++ if (k >= 1 && k <= 26) { 1.494 ++ k += 'a' - 1; 1.495 ++ mod[nmod++] = 0xffe3; 1.496 ++ } 1.497 ++ if (k > 0) { 1.498 ++ int j; 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 ++ 1.509 ++static void term_setup(void) 1.510 ++{ 1.511 ++ struct termios termios; 1.512 ++ const char *init = "\x1b[?25l" "\x1b[2J\x1b[H" "** fbvnc **"; 1.513 ++ 1.514 ++ write(STDOUT_FILENO, init, strlen(init)); 1.515 ++ tcgetattr (STDIN_FILENO, &termios); 1.516 ++ G.term_orig = termios; 1.517 ++ cfmakeraw(&termios); 1.518 ++ tcsetattr_stdin_TCSANOW(&termios); 1.519 ++} 1.520 ++ 1.521 ++int fbvnc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1.522 ++int fbvnc_main(int argc, char **argv) 1.523 ++{ 1.524 ++ char *host = (char *) "127.0.0.1"; 1.525 ++ int port, pending = 0; 1.526 ++ 1.527 ++ INIT_G(); 1.528 ++ if (argc >= 2) 1.529 ++ host = argv[1]; 1.530 ++ port = bb_lookup_port((argc >= 3) ? argv[2] : "vnc", "tcp", 5900); 1.531 ++ G.vnc_fd = create_and_connect_stream_or_die(host, port); 1.532 ++ vnc_init(); 1.533 ++ G.rat_fd = open("/dev/input/mice", O_RDONLY); 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,122 @@ 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 0x1 1.591 ++#define VNC_BUTTON2_MASK 0x2 1.592 ++#define VNC_BUTTON3_MASK 0x4 1.593 ++ 1.594 ++typedef unsigned char u8; 1.595 ++typedef unsigned short u16; 1.596 ++typedef unsigned int u32; 1.597 ++ 1.598 ++struct vnc_pixelfmt { 1.599 ++ u8 bpp; 1.600 ++ u8 depth; 1.601 ++ u8 bigendian; 1.602 ++ u8 truecolor; 1.603 ++ u16 rmax; 1.604 ++ u16 gmax; 1.605 ++ u16 bmax; 1.606 ++ u8 rshl; 1.607 ++ u8 gshl; 1.608 ++ u8 bshl; 1.609 ++ 1.610 ++ u8 pad1; 1.611 ++ u16 pad2; 1.612 ++}; 1.613 ++ 1.614 ++struct vnc_client_init { 1.615 ++ u8 shared; 1.616 ++}; 1.617 ++ 1.618 ++struct vnc_server_init { 1.619 ++ u16 w; 1.620 ++ u16 h; 1.621 ++ struct vnc_pixelfmt fmt; 1.622 ++ u32 len; 1.623 ++ /* char name[len]; */ 1.624 ++}; 1.625 ++ 1.626 ++struct vnc_rect { 1.627 ++ u16 x, y; 1.628 ++ u16 w, h; 1.629 ++ u32 enc; 1.630 ++ /* rect bytes */ 1.631 ++}; 1.632 ++ 1.633 ++struct vnc_server_fbup { 1.634 ++ u8 type; 1.635 ++ u8 pad; 1.636 ++ u16 n; 1.637 ++ /* struct vnc_rect rects[n]; */ 1.638 ++}; 1.639 ++ 1.640 ++struct vnc_server_cuttext { 1.641 ++ u8 type; 1.642 ++ u8 pad1; 1.643 ++ u16 pad2; 1.644 ++ u32 len; 1.645 ++ /* char text[length] */ 1.646 ++}; 1.647 ++ 1.648 ++struct vnc_server_colormap { 1.649 ++ u8 type; 1.650 ++ u8 pad; 1.651 ++ u16 first; 1.652 ++ u16 n; 1.653 ++ /* u8 colors[n * 3 * 2]; */ 1.654 ++}; 1.655 ++ 1.656 ++struct vnc_client_pixelfmt { 1.657 ++ u8 type; 1.658 ++ u8 pad1; 1.659 ++ u16 pad2; 1.660 ++ struct vnc_pixelfmt format; 1.661 ++}; 1.662 ++ 1.663 ++struct vnc_client_fbup { 1.664 ++ u8 type; 1.665 ++ u8 inc; 1.666 ++ u16 x; 1.667 ++ u16 y; 1.668 ++ u16 w; 1.669 ++ u16 h; 1.670 ++}; 1.671 ++ 1.672 ++struct vnc_client_keyevent { 1.673 ++ u8 type; 1.674 ++ u8 down; 1.675 ++ u16 pad; 1.676 ++ u32 key; 1.677 ++}; 1.678 ++ 1.679 ++struct vnc_client_ratevent { 1.680 ++ u8 type; 1.681 ++ u8 mask; 1.682 ++ u16 x; 1.683 ++ u16 y; 1.684 ++};