diff options
author | runge <runge> | 2009-01-04 03:10:39 +0000 |
---|---|---|
committer | runge <runge> | 2009-01-04 03:10:39 +0000 |
commit | 4fdb4cc67f1563156593e5b3deca80acf35f39ed (patch) | |
tree | 18a6d6ddc102aa3c91ed8bd24c863893b8f8de1b /x11vnc/scan.c | |
parent | 6876b85df3abc71feb26ce85bf2ef3bfae001af2 (diff) | |
download | libvncserver-4fdb4cc67f1563156593e5b3deca80acf35f39ed.zip libvncserver-4fdb4cc67f1563156593e5b3deca80acf35f39ed.tar.gz |
x11vnc: add -rmflag option, -rawfb vt support, bpp < 8 support
for rawfb, find /dev/video better. Fix reverse SSL connection
for DH. Some improvements for CUPS TS helper, restart if needed.
Diffstat (limited to 'x11vnc/scan.c')
-rw-r--r-- | x11vnc/scan.c | 222 |
1 files changed, 221 insertions, 1 deletions
diff --git a/x11vnc/scan.c b/x11vnc/scan.c index 12b94d9..864e16a 100644 --- a/x11vnc/scan.c +++ b/x11vnc/scan.c @@ -2421,6 +2421,224 @@ int copy_screen(void) { return 0; } +#include <rfb/default8x16.h> + +/* + * Color values from the vcsadump program. + * void dumpcss(FILE *fp, char *attribs_used) + * char *colormap[] = { + * "#000000", "#0000AA", "#00AA00", "#00AAAA", "#AA0000", "#AA00AA", "#AA5500", "#AAAAAA", + * "#555555", "#5555AA", "#55FF55", "#55FFFF", "#FF5555", "#FF55FF", "#FFFF00", "#FFFFFF" }; + */ + +static unsigned char console_cmap[16*3]={ +/* 0 */ 0x00, 0x00, 0x00, +/* 1 */ 0x00, 0x00, 0xAA, +/* 2 */ 0x00, 0xAA, 0x00, +/* 3 */ 0x00, 0xAA, 0xAA, +/* 4 */ 0xAA, 0x00, 0x00, +/* 5 */ 0xAA, 0x00, 0xAA, +/* 6 */ 0xAA, 0x55, 0x00, +/* 7 */ 0xAA, 0xAA, 0xAA, +/* 8 */ 0x55, 0x55, 0x55, +/* 9 */ 0x55, 0x55, 0xAA, +/* 10 */ 0x55, 0xFF, 0x55, +/* 11 */ 0x55, 0xFF, 0xFF, +/* 12 */ 0xFF, 0x55, 0x55, +/* 13 */ 0xFF, 0x55, 0xFF, +/* 14 */ 0xFF, 0xFF, 0x00, +/* 15 */ 0xFF, 0xFF, 0xFF +}; + +static void snap_vcsa_rawfb(void) { + int n; + char *dst; + char buf[32]; + int i, len, del; + unsigned char rows, cols, xpos, ypos; + static int prev_rows = -1, prev_cols = -1; + static unsigned char prev_xpos = -1, prev_ypos = -1; + static char *vcsabuf = NULL; + static char *vcsabuf0 = NULL; + static unsigned int color_tab[16]; + static int Cw = 8, Ch = 16; + static int db = -1, first = 1; + int created = 0; + rfbScreenInfo s; + rfbScreenInfoPtr fake_screen = &s; + int Bpp = raw_fb_native_bpp / 8; + + if (db < 0) { + if (getenv("X11VNC_DEBUG_VCSA")) { + db = atoi(getenv("X11VNC_DEBUG_VCSA")); + } else { + db = 0; + } + } + + if (first) { + unsigned int rm = raw_fb_native_red_mask; + unsigned int gm = raw_fb_native_green_mask; + unsigned int bm = raw_fb_native_blue_mask; + unsigned int rs = raw_fb_native_red_shift; + unsigned int gs = raw_fb_native_green_shift; + unsigned int bs = raw_fb_native_blue_shift; + unsigned int rx = raw_fb_native_red_max; + unsigned int gx = raw_fb_native_green_max; + unsigned int bx = raw_fb_native_blue_max; + + for (i=0; i < 16; i++) { + int r = console_cmap[3*i+0]; + int g = console_cmap[3*i+1]; + int b = console_cmap[3*i+2]; + r = rx * r / 255; + g = gx * g / 255; + b = bx * b / 255; + color_tab[i] = (r << rs) | (g << gs) | (b << bs); + if (db) fprintf(stderr, "cmap[%02d] 0x%08x %04d %04d %04d\n", i, color_tab[i], r, g, b); + if (i != 0 && getenv("RAWFB_VCSA_BW")) { + color_tab[i] = rm | gm | bm; + } + } + } + first = 0; + + lseek(raw_fb_fd, 0, SEEK_SET); + len = 4; + del = 0; + memset(buf, 0, sizeof(buf)); + while (len > 0) { + n = read(raw_fb_fd, buf + del, len); + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + + rows = (unsigned char) buf[0]; + cols = (unsigned char) buf[1]; + xpos = (unsigned char) buf[2]; + ypos = (unsigned char) buf[3]; + + if (db) fprintf(stderr, "rows=%d cols=%d xpos=%d ypos=%d Bpp=%d\n", rows, cols, xpos, ypos, Bpp); + if (rows == 0 || cols == 0) { + usleep(100 * 1000); + return; + } + + if (vcsabuf == NULL || prev_rows != rows || prev_cols != cols) { + if (vcsabuf) { + free(vcsabuf); + free(vcsabuf0); + } + vcsabuf = (char *) calloc(2 * rows * cols, 1); + vcsabuf0 = (char *) calloc(2 * rows * cols, 1); + created = 1; + + if (prev_rows != -1 && prev_cols != -1) { + do_new_fb(1); + } + + prev_rows = rows; + prev_cols = cols; + } + + if (!rfbEndianTest) { + unsigned char tc = rows; + rows = cols; + cols = tc; + + tc = xpos; + xpos = ypos; + ypos = tc; + } + + len = 2 * rows * cols; + del = 0; + memset(vcsabuf, 0, len); + while (len > 0) { + n = read(raw_fb_fd, vcsabuf + del, len); + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + + fake_screen->frameBuffer = snap->data; + fake_screen->paddedWidthInBytes = snap->bytes_per_line; + fake_screen->serverFormat.bitsPerPixel = raw_fb_native_bpp; + + for (i=0; i < rows * cols; i++) { + int ix, iy, x, y, w, h; + unsigned char chr = 0; + unsigned char attr; + unsigned int fore, back; + unsigned short *usp; + unsigned int *uip; + chr = (unsigned char) vcsabuf[2*i]; + attr = vcsabuf[2*i+1]; + + iy = i / cols; + ix = i - iy * cols; + + if (ix == prev_xpos && iy == prev_ypos) { + ; + } else if (ix == xpos && iy == ypos) { + ; + } else if (!created && chr == vcsabuf0[2*i] && attr == vcsabuf0[2*i+1]) { + continue; + } + + if (!rfbEndianTest) { + unsigned char tc = chr; + chr = attr; + attr = tc; + } + + y = iy * Ch; + x = ix * Cw; + dst = snap->data + y * snap->bytes_per_line + x * Bpp; + + fore = color_tab[attr & 0xf]; + back = color_tab[(attr >> 4) & 0x7]; + + if (ix == xpos && iy == ypos) { + unsigned int ti = fore; + fore = back; + back = ti; + } + + for (h = 0; h < Ch; h++) { + if (Bpp == 1) { + memset(dst, back, Cw); + } else if (Bpp == 2) { + for (w = 0; w < Cw; w++) { + usp = (unsigned short *) (dst + w*Bpp); + *usp = (unsigned short) back; + } + } else if (Bpp == 4) { + for (w = 0; w < Cw; w++) { + uip = (unsigned int *) (dst + w*Bpp); + *uip = (unsigned int) back; + } + } + dst += snap->bytes_per_line; + } + rfbDrawChar(fake_screen, &default8x16Font, x, y + Ch, chr, fore); + } + memcpy(vcsabuf0, vcsabuf, 2 * rows * cols); + prev_xpos = xpos; + prev_ypos = ypos; +} + static void snap_all_rawfb(void) { int pixelsize = bpp/8; int n, sz; @@ -2513,7 +2731,9 @@ int copy_snap(void) { if (raw_fb_bytes_per_line != snap->bytes_per_line) { read_all_at_once = 0; } - if (read_all_at_once) { + if (raw_fb_full_str && strstr(raw_fb_full_str, "/dev/vcsa")) { + snap_vcsa_rawfb(); + } else if (read_all_at_once) { snap_all_rawfb(); } else { /* this goes line by line, XXX not working for video */ |