Commit 4fdb4cc6 authored by runge's avatar runge

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.
parent 6876b85d
2009-01-03 Karl Runge <runge@karlrunge.com>
* 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.
2008-12-10 Karl Runge <runge@karlrunge.com>
* x11vnc: 0.9.6 release. Some strtok bugfixes. rename -tlsvnc
to -anontls. Disable ssl caching. No cert creation prompting
......
This diff is collapsed.
......@@ -155,7 +155,13 @@ void clean_up_exit(int ret) {
pipeinput_fh = NULL;
}
if (! dpy) exit(ret); /* raw_rb hack */
if (! dpy) { /* raw_rb hack */
if (rm_flagfile) {
unlink(rm_flagfile);
rm_flagfile = NULL;
}
exit(ret);
}
/* X keyboard cleanups */
delete_added_keycodes(0);
......@@ -195,6 +201,12 @@ void clean_up_exit(int ret) {
X_UNLOCK;
fflush(stderr);
if (rm_flagfile) {
unlink(rm_flagfile);
rm_flagfile = NULL;
}
exit(ret);
}
......@@ -452,6 +464,10 @@ static void interrupted (int sig) {
} else if (exit_flag <= 2) {
return;
}
if (rm_flagfile) {
unlink(rm_flagfile);
rm_flagfile = NULL;
}
exit(4);
}
exit_flag++;
......@@ -482,6 +498,10 @@ static void interrupted (int sig) {
if (sig == -1) {
/* not worth trying any more cleanup, X server probably gone */
if (rm_flagfile) {
unlink(rm_flagfile);
rm_flagfile = NULL;
}
exit(3);
}
......@@ -512,6 +532,10 @@ static void interrupted (int sig) {
}
if (sig) {
if (rm_flagfile) {
unlink(rm_flagfile);
rm_flagfile = NULL;
}
exit(2);
}
}
......
......@@ -2263,8 +2263,6 @@ char *get_repeater_string(char *str, int *len) {
* Do a reverse connect for a single "host" or "host:port"
*/
extern int ssl_client_mode;
static int do_reverse_connect(char *str_in) {
rfbClientPtr cl;
char *host, *p, *str = str_in, *s = NULL;
......
This diff is collapsed.
......@@ -22,6 +22,9 @@ char *console_guess(char *str, int *fd);
void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
void console_pointer_command(int mask, int x, int y, rfbClientPtr client);
void linux_dev_fb_msg(char *);
char *console_guess(char *str, int *fd) {
char *q, *in = strdup(str);
char *atparms = NULL, *file = NULL;
......@@ -40,6 +43,10 @@ char *console_guess(char *str, int *fd) {
free(in);
in = (char *) malloc(strlen("console:/dev/") + strlen(str) + 1);
sprintf(in, "console:/dev/%s", str);
} else if (strstr(in, "vt") == in) {
free(in);
in = (char *) malloc(strlen("console_") + strlen(str) + 1);
sprintf(in, "console_%s", str);
}
if (strstr(in, "console") != in) {
......@@ -75,7 +82,6 @@ char *console_guess(char *str, int *fd) {
file = strdup("/dev/fb0");
}
}
rfbLog("console_guess: file is %s\n", file);
do_input = 1;
if (pipeinput_str) {
......@@ -84,9 +90,15 @@ char *console_guess(char *str, int *fd) {
} else {
have_uinput = check_uinput();
}
if (strstr(in, "console_vt")) {
have_uinput = 0;
}
if (!strcmp(in, "consolex")) {
do_input = 0;
} else if (strstr(in, "console_vtx")) {
have_uinput = 0;
do_input = 0;
} else if (!strcmp(in, "console")) {
/* current active VT: */
if (! have_uinput) {
......@@ -94,11 +106,44 @@ char *console_guess(char *str, int *fd) {
}
} else {
int n;
if (sscanf(in, "console%d", &n) != 1) {
if (sscanf(in, "console%d", &n) == 1) {
tty = n;
have_uinput = 0;
} else if (sscanf(in, "console_vt%d", &n) == 1) {
tty = n;
have_uinput = 0;
}
}
if (strstr(in, "console_vt") == in) {
char tmp[100];
int fd, rows = 30, cols = 80, w, h;
sprintf(tmp, "/dev/vcsa%d", tty);
file = strdup(tmp);
fd = open(file, O_RDWR);
if (fd >= 0) {
read(fd, tmp, 4);
rows = (unsigned char) tmp[0];
cols = (unsigned char) tmp[1];
close(fd);
}
w = cols * 8;
h = rows * 16;
rfbLog("%s %dx%d\n", file, cols, rows);
if (getenv("RAWFB_VCSA_BPP")) {
/* 8bpp, etc */
int bt = atoi(getenv("RAWFB_VCSA_BPP"));
if (bt > 0 && bt <=32) {
sprintf(tmp, "%dx%dx%d", w, h, bt);
} else {
sprintf(tmp, "%dx%dx16", w, h);
}
} else {
/* default 16bpp */
sprintf(tmp, "%dx%dx16", w, h);
}
atparms = strdup(tmp);
}
rfbLog("console_guess: file is %s\n", file);
if (! atparms) {
#if LIBVNCSERVER_HAVE_LINUX_FB_H
......@@ -126,6 +171,13 @@ char *console_guess(char *str, int *fd) {
gm = 0x38;
bm = 0xc0;
}
if (b <= 8 && (rm == gm && gm == bm)) {
if (b == 4) {
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
}
/* @66666x66666x32:0xffffffff:... */
atparms = (char *) malloc(200);
......@@ -138,7 +190,8 @@ char *console_guess(char *str, int *fd) {
}
} else {
rfbLog("could not open: %s\n", file);
perror("open");
rfbLogPerror("open");
linux_dev_fb_msg(file);
close(d);
}
#endif
......@@ -174,8 +227,12 @@ char *console_guess(char *str, int *fd) {
return NULL;
}
q = (char *) malloc(strlen("map:") + strlen(file) + 1 + strlen(atparms) + 1);
sprintf(q, "map:%s@%s", file, atparms);
q = (char *) malloc(strlen("mmap:") + strlen(file) + 1 + strlen(atparms) + 1);
if (strstr(in, "console_vt")) {
sprintf(q, "snap:%s@%s", file, atparms);
} else {
sprintf(q, "map:%s@%s", file, atparms);
}
return q;
}
......
......@@ -17,6 +17,7 @@ int set_visual_str_to_something = 0;
char *logfile = NULL; /* -o, -logfile */
int logfile_append = 0;
char *flagfile = NULL; /* -flag */
char *rm_flagfile = NULL; /* -rmflag */
char *passwdfile = NULL; /* -passwdfile */
int unixpw = 0; /* -unixpw */
int unixpw_nis = 0; /* -unixpw_nis */
......@@ -145,6 +146,7 @@ int clear_mods = 0; /* -clear_mods (1) and -clear_keys (2) -clear_locks (3) */
int nofb = 0; /* do not send any fb updates */
char *raw_fb_str = NULL; /* used under -rawfb */
char *raw_fb_pixfmt = NULL;
char *raw_fb_full_str = NULL;
char *freqtab = NULL;
char *pipeinput_str = NULL; /* -pipeinput [tee,reopen,keycodes:]cmd */
char *pipeinput_opts = NULL;
......
......@@ -17,6 +17,7 @@ extern int set_visual_str_to_something;
extern char *logfile;
extern int logfile_append;
extern char *flagfile;
extern char *rm_flagfile;
extern char *passwdfile;
extern int unixpw;
extern int unixpw_nis;
......@@ -117,6 +118,7 @@ extern int clear_mods;
extern int nofb;
extern char *raw_fb_str;
extern char *raw_fb_pixfmt;
extern char *raw_fb_full_str;
extern char *freqtab;
extern char *pipeinput_str;
extern char *pipeinput_opts;
......
......@@ -993,6 +993,8 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
} else {
rfbLog("pipeinput: could not open: %s\n", dev);
rfbLogPerror("open");
rfbLog("You may need to be root to open %s.\n", dev);
rfbLog("\n");
}
return;
} else if (strstr(p, "UINPUT") == p) {
......
......@@ -5248,6 +5248,10 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(flagfile));
goto qry;
}
if (!strcmp(p, "rmflag")) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(rm_flagfile));
goto qry;
}
if (!strcmp(p, "rc")) {
char *s = rc_rcfile;
if (rc_rcfile_default) {
......
......@@ -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 */
......
......@@ -1165,6 +1165,24 @@ void vnc_reflect_process_client(void) {
}
}
void linux_dev_fb_msg(char* q) {
if (strstr(q, "/dev/fb") && strstr(UT.sysname, "Linux")) {
rfbLog("\n");
rfbLog("On Linux you may need to load a kernel module to enable\n");
rfbLog("the framebuffer device /dev/fb*; e.g.:\n");
rfbLog(" vga=0x303 (and others) kernel boot parameter\n");
rfbLog(" modprobe uvesafb\n");
rfbLog(" modprobe radeonfb (card specific)\n");
rfbLog(" modprobe nvidiafb (card specific, others)\n");
rfbLog(" modprobe vesafb (?)\n");
rfbLog(" modprobe vga16fb\n");
rfbLog("\n");
rfbLog("You may also need root permission to open /dev/fb*\n");
rfbLog("and/or /dev/tty*.\n");
rfbLog("\n");
}
}
#define RAWFB_MMAP 1
#define RAWFB_FILE 2
#define RAWFB_SHM 3
......@@ -1414,7 +1432,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
} else if (strstr(str, "dev/video")) {
rawfb_dev_video = 1;
} else if (strstr(str, "console") == str || strstr(str, "fb") == str ||
strstr(str, "/dev/fb") == str) {
strstr(str, "/dev/fb") == str || strstr(str, "vt") == str) {
char *str2 = console_guess(str, &raw_fb_fd);
if (str2 == NULL) {
rfbLog("console_guess failed for: %s\n", str);
......@@ -1467,6 +1485,11 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
* -rawfb file:/path/to/file@640x480x32:ff/ff00/ff0000
*/
if (raw_fb_full_str) {
free(raw_fb_full_str);
}
raw_fb_full_str = strdup(str);
/* +O offset */
if ((q = strrchr(str, '+')) != NULL) {
......@@ -1509,6 +1532,93 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
*q = '\0';
if (rm == 0 && gm == 0 && bm == 0) {
/* guess masks... */
if (b == 24 || b == 32) {
rm = 0xff0000;
gm = 0x00ff00;
bm = 0x0000ff;
} else if (b == 16) {
rm = 0xf800;
gm = 0x07e0;
bm = 0x001f;
} else if (b == 8) {
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
}
/* we can fake -flipbyteorder to some degree... */
if (flip_byte_order) {
if (b == 24 || b == 32) {
tm = rm;
rm = bm;
bm = tm;
} else if (b == 16) {
unsigned short s1, s2;
s1 = (unsigned short) rm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
rm = (unsigned long) s2;
s1 = (unsigned short) gm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
gm = (unsigned long) s2;
s1 = (unsigned short) bm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
bm = (unsigned long) s2;
}
}
/* native fb stuff for bpp < 8 only */
raw_fb_native_bpp = b;
raw_fb_native_red_mask = rm;
raw_fb_native_green_mask = gm;
raw_fb_native_blue_mask = bm;
raw_fb_native_red_shift = 100;
raw_fb_native_green_shift = 100;
raw_fb_native_blue_shift = 100;
raw_fb_native_red_max = 1;
raw_fb_native_green_max = 1;
raw_fb_native_blue_max = 1;
m = 1;
for (i=0; i<32; i++) {
if (raw_fb_native_red_mask & m) {
if (raw_fb_native_red_shift == 100) {
raw_fb_native_red_shift = i;
}
raw_fb_native_red_max *= 2;
}
if (raw_fb_native_green_mask & m) {
if (raw_fb_native_green_shift == 100) {
raw_fb_native_green_shift = i;
}
raw_fb_native_green_max *= 2;
}
if (raw_fb_native_blue_mask & m) {
if (raw_fb_native_blue_shift == 100) {
raw_fb_native_blue_shift = i;
}
raw_fb_native_blue_max *= 2;
}
m = m << 1;
}
raw_fb_native_red_max -= 1;
raw_fb_native_green_max -= 1;
raw_fb_native_blue_max -= 1;
if (b < 8) {
/* e.g. VGA16 */
rfbLog("raw_fb_native_bpp: %d 0x%02lx 0x%02lx 0x%02lx %d/%d/%d %d/%d/%d\n", raw_fb_native_bpp,
raw_fb_native_red_mask, raw_fb_native_green_mask, raw_fb_native_blue_mask,
raw_fb_native_red_max, raw_fb_native_green_max, raw_fb_native_blue_max,
raw_fb_native_red_shift, raw_fb_native_green_shift, raw_fb_native_blue_shift);
raw_fb_expand_bytes = 1;
b = 8;
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
/* end of stuff for bpp < 8 */
dpy_x = wdpy_x = w;
dpy_y = wdpy_y = h;
off_x = 0;
......@@ -1609,11 +1719,14 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
rfbLogEnable(1);
rfbLog("failed to open file: %s, %s\n", q, str);
rfbLogPerror("open");
linux_dev_fb_msg(q);
clean_up_exit(1);
}
raw_fb_fd = fd;
if (xform24to32) {
if (raw_fb_native_bpp < 8) {
size = w*h*raw_fb_native_bpp/8 + raw_fb_offset;
} else if (xform24to32) {
size = w*h*24/8 + raw_fb_offset;
} else {
size = w*h*b/8 + raw_fb_offset;
......@@ -1650,14 +1763,20 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
rfbLog("failed to mmap file: %s, %s\n", q, str);
rfbLog(" raw_fb_addr: %p\n", raw_fb_addr);
rfbLogPerror("mmap");
clean_up_exit(1);
}
raw_fb_mmap = size;
rfbLog("rawfb: mmap file: %s\n", q);
rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
b, raw_fb_addr, size);
last_mode = RAWFB_MMAP;
raw_fb_addr = NULL;
rfbLog("mmap(2) failed, trying slower lseek(2)\n");
raw_fb_seek = size;
last_mode = RAWFB_FILE;
} else {
raw_fb_mmap = size;
rfbLog("rawfb: mmap file: %s\n", q);
rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
b, raw_fb_addr, size);
last_mode = RAWFB_MMAP;
}
#else
rfbLog("mmap(2) not supported on system, using"
" slower lseek(2)\n");
......@@ -1739,42 +1858,6 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
snap->bitmap_unit = -1;
}
if (rm == 0 && gm == 0 && bm == 0) {
/* guess masks... */
if (b == 24 || b == 32) {
rm = 0xff0000;
gm = 0x00ff00;
bm = 0x0000ff;
} else if (b == 16) {
rm = 0xf800;
gm = 0x07e0;
bm = 0x001f;
} else if (b == 8) {
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
}
/* we can fake -flipbyteorder to some degree... */
if (flip_byte_order) {
if (b == 24 || b == 32) {
tm = rm;
rm = bm;
bm = tm;
} else if (b == 16) {
unsigned short s1, s2;
s1 = (unsigned short) rm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
rm = (unsigned long) s2;
s1 = (unsigned short) gm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
gm = (unsigned long) s2;
s1 = (unsigned short) bm;
s2 = ((0xff & s1) << 8) | ((0xff00 & s1) >> 8);
bm = (unsigned long) s2;
}
}
raw_fb_image->red_mask = rm;
raw_fb_image->green_mask = gm;
......@@ -1794,6 +1877,9 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
m = m << 1;
}
if (raw_fb_native_bpp < 8) {
raw_fb_image->depth = raw_fb_expand_bytes * 8;
}
if (! raw_fb_image->depth) {
raw_fb_image->depth = (b == 32) ? 24 : b;
}
......@@ -1805,7 +1891,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
depth++;
}
if (clipshift) {
if (clipshift || raw_fb_native_bpp < 8) {
memset(raw_fb, 0xff, dpy_y * raw_fb_image->bytes_per_line);
} else if (raw_fb_addr && ! xform24to32) {
memcpy(raw_fb, raw_fb_addr + raw_fb_offset, dpy_y * raw_fb_image->bytes_per_line);
......@@ -1814,7 +1900,6 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
if (verbose) {
rfbLog("\n");
rfbLog("rawfb: raw_fb %p\n", raw_fb);
rfbLog(" format %d\n", raw_fb_image->format);
......@@ -3273,6 +3358,31 @@ void set_vnc_desktop_name(void) {
flagfile);
}
}
if (rm_flagfile) {
int create = 0;
struct stat sb;
if (strstr(rm_flagfile, "create:") == rm_flagfile) {
char *s = rm_flagfile;
create = 1;
rm_flagfile = strdup(rm_flagfile + strlen("create:"));
free(s);
}
if (strstr(rm_flagfile, "nocreate:") == rm_flagfile) {
char *s = rm_flagfile;
create = 0;
rm_flagfile = strdup(rm_flagfile + strlen("nocreate:"));
free(s);
} else if (stat(rm_flagfile, &sb) != 0) {
create = 1;
}
if (create) {
FILE *flag = fopen(rm_flagfile, "w");
if (flag) {
fprintf(flag, "%d\n", getpid());
fclose(flag);
}
}
}
}
fflush(stdout);
}
......
......@@ -980,6 +980,7 @@ void openssl_init(int isclient) {
" be used in -sslCRL mode.\n");
clean_up_exit(1);
}
/* n.b. new ctx */
if (!switch_to_anon_dh()) {
rfbLog("openssl_init: Anonymous Diffie-Hellman setup"
" failed.\n");
......@@ -2746,10 +2747,17 @@ static int switch_to_anon_dh(void) {
rfbLog("Using Anonymous Diffie-Hellman mode.\n");
rfbLog("WARNING: Anonymous Diffie-Hellman uses encryption but is\n");
rfbLog("WARNING: susceptible to a Man-In-The-Middle attack.\n");
ctx = SSL_CTX_new( SSLv23_server_method() );
if (ssl_client_mode) {
ctx = SSL_CTX_new( SSLv23_client_method() );
} else {
ctx = SSL_CTX_new( SSLv23_server_method() );
}
if (ctx == NULL) {
return 0;
}
if (ssl_client_mode) {
return 1;
}
if (!SSL_CTX_set_cipher_list(ctx, "ADH:@STRENGTH")) {
return 0;
}
......@@ -2959,10 +2967,12 @@ static int check_vnc_tls_mode(int s_in, int s_out) {
if (ssl_client_mode) {
/* XXX check if this can be done in SSL client mode. */
if (vencrypt_mode == VENCRYPT_FORCE || anontls_mode == ANONTLS_FORCE) {
rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE prevents normal SSL\n");
return 0;
rfbLog("check_vnc_tls_mode: VENCRYPT_FORCE/ANONTLS_FORCE in client\n");
rfbLog("check_vnc_tls_mode: connect mode prevents normal SSL.\n");
//return 0;
} else {
return 1;
}
return 1;
}
if (ssl_verify && vencrypt_mode != VENCRYPT_FORCE && anontls_mode == ANONTLS_FORCE) {
rfbLog("check_vnc_tls_mode: Cannot use ANONTLS_FORCE with -sslverify (Anon DH only)\n");
......@@ -3194,14 +3204,15 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) {
if (db > 1) fprintf(stderr, "ssl_init: 4\n");
while (1) {
if (db) fprintf(stderr, "calling SSL_accept...\n");
signal(SIGALRM, ssl_timeout);
alarm(timeout);
if (ssl_client_mode) {
if (db) fprintf(stderr, "calling SSL_connect...\n");
rc = SSL_connect(ssl);
} else {
if (db) fprintf(stderr, "calling SSL_accept...\n");
rc = SSL_accept(ssl);
}
err = SSL_get_error(ssl, rc);
......@@ -3209,7 +3220,11 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) {
alarm(0);
signal(SIGALRM, SIG_DFL);
if (db) fprintf(stderr, "SSL_accept %d/%d\n", rc, err);
if (ssl_client_mode) {
if (db) fprintf(stderr, "SSL_connect %d/%d\n", rc, err);
} else {
if (db) fprintf(stderr, "SSL_accept %d/%d\n", rc, err);
}
if (err == SSL_ERROR_NONE) {
break;
} else if (err == SSL_ERROR_WANT_READ) {
......@@ -3283,7 +3298,11 @@ static int ssl_init(int s_in, int s_out, int skip_vnc_tls) {
usleep(10 * 1000);
}
rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s:%d\n", getpid(), name, peerport);
if (ssl_client_mode) {
rfbLog("SSL: ssl_helper[%d]: SSL_connect() succeeded for: %s:%d\n", getpid(), name, peerport);
} else {
rfbLog("SSL: ssl_helper[%d]: SSL_accept() succeeded for: %s:%d\n", getpid(), name, peerport);
}
pr_ssl_info(0);
......@@ -3848,13 +3867,13 @@ void raw_xfer(int csock, int s_in, int s_out) {
/* change buf size some direction. */
}
/* this is for testing, no SSL just socket redir */
if (pid < 0) {
exit(1);
}
if (getenv("X11VNC_DEBUG_RAW_XFER")) {
db = atoi(getenv("X11VNC_DEBUG_RAW_XFER"));
}
if (pid < 0) {
exit(1);
}
/* this is for testing or special helper usage, no SSL just socket redir */
if (pid) {
if (db) rfbLog("raw_xfer start: %d -> %d/%d\n", csock, s_in, s_out);
......
......@@ -1287,12 +1287,24 @@ static void parse_str(char *str, char **dev, char **settings, char **atparms) {
}
if (*dev == NULL) {
s = (char *) malloc(strlen("/dev/") + strlen(str) + 1);
struct stat sbuf;
s = (char *) malloc(strlen("/dev/") + strlen(str) + 2);
if (strstr(str, "/dev/") == str) {
sprintf(s, "%s", str);
} else {
sprintf(s, "/dev/%s", str);
}
rfbLog("Checking existence of '%s'\n", s);
if (stat(s, &sbuf) != 0) {
rfbLogPerror("stat");
strcat(s, "0");
rfbLog("switching to '%s'\n", s);
}
if (stat(s, &sbuf) != 0) {
rfbLogPerror("stat");
rfbLog("You will need to specify the video device more explicity.\n");
}
*dev = s;
rfbLog("set video device to: '%s'\n", *dev);
}
......
This diff is collapsed.
......@@ -194,17 +194,19 @@ int tsdo(int port, int lsock, int *conn) {
*conn = csock;
} else {
csock = *conn;
if (db) rfbLog("tsdo: using exiting csock: %d, port: %d\n", csock, port);
if (db) rfbLog("tsdo: using existing csock: %d, port: %d\n", csock, port);
}
rsock = rfbConnectToTcpAddr("127.0.0.1", port);
if (rsock < 0) {
if (db) rfbLog("tsdo: rfbConnectToTcpAddr(port=%d) failed.\n", port);
close(csock);
return 2;
}
pid = fork();
if (pid < 0) {
close(csock);
close(rsock);
return 3;
}
......@@ -212,8 +214,8 @@ int tsdo(int port, int lsock, int *conn) {
ts_taskn = (ts_taskn+1) % TASKMAX;
ts_tasks[ts_taskn] = pid;
close(csock);
*conn = -1;
close(rsock);
*conn = -1;
return 0;
}
if (pid == 0) {
......@@ -225,15 +227,21 @@ int tsdo(int port, int lsock, int *conn) {
#if LIBVNCSERVER_HAVE_SETSID
if (setsid() == -1) {
perror("setsid");
close(csock);
close(rsock);
exit(1);
}
#else
if (setpgrp() == -1) {
perror("setpgrp");
close(csock);
close(rsock);
exit(1);
}
#endif /* SETSID */
raw_xfer(rsock, csock, csock);
close(csock);
close(rsock);
exit(0);
}
return 0;
......@@ -245,11 +253,13 @@ void set_redir_properties(void);
#define TSSTK 16
void terminal_services(char *list) {
int i, j, n = 0, db = 1;
char *p, *q, *r, *str = strdup(list);
int i, j, n, db = 1;
char *p, *q, *r, *str;
#if !NO_X11
char *tag[TSMAX];
int listen[TSMAX], redir[TSMAX][TSSTK], socks[TSMAX], tstk[TSSTK];
double rate_start;
int rate_count;
Atom at, atom[TSMAX];
fd_set rd;
Window rwin;
......@@ -265,6 +275,7 @@ void terminal_services(char *list) {
if (! dpy) {
return;
}
rwin = RootWindow(dpy, DefaultScreen(dpy));
at = XInternAtom(dpy, "TS_REDIR_LIST", False);
......@@ -275,15 +286,24 @@ void terminal_services(char *list) {
}
if (db) fprintf(stderr, "TS_REDIR_LIST Atom: %d.\n");
oh_restart_it_all:
for (i=0; i<TASKMAX; i++) {
ts_tasks[i] = 0;
}
for (i=0; i<TSMAX; i++) {
socks[i] = -1;
listen[i] = -1;
for (j=0; j<TSSTK; j++) {
redir[i][j] = 0;
}
}
rate_start = 0.0;
rate_count = 0;
n = 0;
str = strdup(list);
p = strtok(str, ",");
while (p) {
int m1, m2;
......@@ -339,6 +359,7 @@ void terminal_services(char *list) {
}
for (i=0; i<n; i++) {
int k;
atom[i] = XInternAtom(dpy, tag[i], False);
if (db) fprintf(stderr, "tag: %s atom: %d\n", tag[i], (int) atom[i]);
if (atom[i] == None) {
......@@ -350,7 +371,15 @@ void terminal_services(char *list) {
PropModeReplace, (unsigned char *)num, strlen(num));
XSync(dpy, False);
socks[i] = rfbListenOnTCPPort(listen[i], htonl(INADDR_LOOPBACK));
for (k=1; k <= 5; k++) {
socks[i] = rfbListenOnTCPPort(listen[i], htonl(INADDR_LOOPBACK));
if (socks[i] >= 0) {
if (db) fprintf(stderr, " listen succeeded: %d\n", listen[i]);
break;
}
if (db) fprintf(stderr, " listen failed***: %d\n", listen[i]);
usleep(k * 2000*1000);
}
}
if (getenv("TSD_RESTART")) {
......@@ -385,6 +414,7 @@ void terminal_services(char *list) {
continue;
}
if (nfd > 0) {
int did_ts = 0;
for(i=0; i<n; i++) {
int k = 0;
for (j = 0; j < TSSTK; j++) {
......@@ -439,7 +469,16 @@ if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], t
redir[i][j] = 0;
continue;
}
if (dnow() > rate_start + 10.0) {
rate_start = dnow();
rate_count = 0;
}
rate_count++;
rc = tsdo(p, s, &conn);
did_ts++;
if (rc == 0) {
/* AOK */
if (db) fprintf(stderr, "tsdo[%d] OK: %d\n", i, p);
......@@ -452,16 +491,18 @@ if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], t
break;
} else if (rc == 1) {
/* accept failed */
if (db) fprintf(stderr, "tsdo[%d] accept failed: %d\n", i, p);
if (db) fprintf(stderr, "tsdo[%d] accept failed: %d, sleep 50ms\n", i, p);
usleep(50*1000);
break;
} else if (rc == 2) {
/* connect failed */
if (db) fprintf(stderr, "tsdo[%d] connect failed: %d\n", i, p);
if (db) fprintf(stderr, "tsdo[%d] connect failed: %d, sleep 50ms rate: %d/10s\n", i, p, rate_count);
redir[i][j] = 0;
usleep(50*1000);
continue;
} else if (rc == 3) {
/* fork failed */
usleep(250*1000);
usleep(500*1000);
break;
}
}
......@@ -470,6 +511,41 @@ if (tstk[j] != 0) fprintf(stderr, "B redir[%d][%d] = %d %s\n", i, j, tstk[j], t
}
}
}
if (did_ts && rate_count > 100) {
int k, db_netstat = 1;
char dcmd[100];
if (no_external_cmds) {
db_netstat = 0;
}
rfbLog("terminal_services: throttling high connect rate %d/10s\n", rate_count);
usleep(2*1000*1000);
rfbLog("terminal_services: stopping ts services.\n");
for(i=0; i<n; i++) {
int s = socks[i];
if (s < 0) {
continue;
}
rfbLog("terminal_services: closing listen=%d sock=%d.\n", listen[i], socks[i]);
if (listen[i] >= 0 && db_netstat) {
sprintf(dcmd, "netstat -an | grep -w '%d'", listen[i]);
fprintf(stderr, "#1 %s\n", dcmd);
system(dcmd);
}
close(s);
socks[i] = -1;
usleep(2*1000*1000);
if (listen[i] >= 0 && db_netstat) {
fprintf(stderr, "#2 %s\n", dcmd);
system(dcmd);
}
}
usleep(10*1000*1000);
rfbLog("terminal_services: restarting ts services\n");
goto oh_restart_it_all;
}
}
for (i=0; i<TASKMAX; i++) {
pid_t p = ts_tasks[i];
......@@ -1408,6 +1484,8 @@ static void print_settings(int try_http, int bg, char *gui_str) {
fprintf(stderr, " logappend: %d\n", logfile_append);
fprintf(stderr, " flag: %s\n", flagfile ? flagfile
: "null");
fprintf(stderr, " rm_flag: %s\n", rm_flagfile ? rm_flagfile
: "null");
fprintf(stderr, " rc_file: \"%s\"\n", rc_rcfile ? rc_rcfile
: "null");
fprintf(stderr, " norc: %d\n", rc_norc);
......@@ -2768,6 +2846,11 @@ int main(int argc, char* argv[]) {
flagfile = strdup(argv[++i]);
continue;
}
if (!strcmp(arg, "-rmflag")) {
CHECK_ARGC
rm_flagfile = strdup(argv[++i]);
continue;
}
if (!strcmp(arg, "-rc")) {
i++; /* done above */
continue;
......
......@@ -438,6 +438,12 @@ extern int raw_fb_seek;
extern int raw_fb_fd;
extern int raw_fb_back_to_X;
extern int raw_fb_native_bpp;
extern int raw_fb_expand_bytes;
extern unsigned long raw_fb_native_red_mask, raw_fb_native_green_mask, raw_fb_native_blue_mask;
extern unsigned short raw_fb_native_red_max, raw_fb_native_green_max, raw_fb_native_blue_max;
extern unsigned short raw_fb_native_red_shift, raw_fb_native_green_shift, raw_fb_native_blue_shift;
extern int rfb_bytes_per_line;
extern int main_bytes_per_line;
extern int rot_bytes_per_line;
......
......@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.6 lastmod: 2008-12-08";
char lastmod[] = "0.9.7 lastmod: 2009-01-03";
/* X display info */
......@@ -75,6 +75,12 @@ int raw_fb_seek = 0;
int raw_fb_fd = -1;
int raw_fb_back_to_X = 0; /* kludge for testing rawfb -> X */
int raw_fb_native_bpp = 0;
int raw_fb_expand_bytes = 1;
unsigned long raw_fb_native_red_mask = 0, raw_fb_native_green_mask = 0, raw_fb_native_blue_mask = 0;
unsigned short raw_fb_native_red_max = 0, raw_fb_native_green_max = 0, raw_fb_native_blue_max = 0;
unsigned short raw_fb_native_red_shift = 0, raw_fb_native_green_shift = 0, raw_fb_native_blue_shift = 0;
int rfb_bytes_per_line = 0;
int main_bytes_per_line = 0;
int rot_bytes_per_line = 0;
......
......@@ -352,6 +352,164 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
#endif /* NO_X11 */
}
static void copy_raw_fb_low_bpp(XImage *dest, int x, int y, unsigned int w,
unsigned int h) {
char *src, *dst;
unsigned int line;
static char *buf = NULL;
static int buflen = -1;
int bpl = wdpy_x * raw_fb_native_bpp / 8;
int n, ix, len, del, sz = wdpy_x * raw_fb_expand_bytes;
unsigned int rm_n = raw_fb_native_red_mask;
unsigned int gm_n = raw_fb_native_green_mask;
unsigned int bm_n = raw_fb_native_blue_mask;
unsigned int rm_f = main_red_mask;
unsigned int gm_f = main_green_mask;
unsigned int bm_f = main_blue_mask;
unsigned int rs_n = raw_fb_native_red_shift;
unsigned int gs_n = raw_fb_native_green_shift;
unsigned int bs_n = raw_fb_native_blue_shift;
unsigned int rs_f = main_red_shift;
unsigned int gs_f = main_green_shift;
unsigned int bs_f = main_blue_shift;
unsigned int rx_n = raw_fb_native_red_max;
unsigned int gx_n = raw_fb_native_green_max;
unsigned int bx_n = raw_fb_native_blue_max;
unsigned int rx_f = main_red_max;
unsigned int gx_f = main_green_max;
unsigned int bx_f = main_blue_max;
static unsigned int msk[8];
static int last_bpp = -1;
static int cga = -1;
if (cga < 0) {
if (getenv("RAWFB_CGA")) {
cga = 1;
} else {
cga = 0;
}
}
if (sz > buflen || buf == NULL) {
if (buf) {
free(buf);
}
buflen = sz + 1000;
buf = (char *) malloc(buflen);
}
if (clipshift && ! use_snapfb) {
x += coff_x;
y += coff_y;
}
if (last_bpp != raw_fb_native_bpp) {
int br;
for (br = 0; br < 8; br++) {
unsigned int pbit, k, m = 0;
for (k=0; k < raw_fb_native_bpp; k++) {
pbit = 1 << (br+k);
m |= pbit;
}
msk[br] = m;
}
last_bpp = raw_fb_native_bpp;
}
dst = dest->data;
if (0) fprintf(stderr, "x=%d y=%d w=%d h=%d bpl=%d d_bpl=%d-%dx%dx%d/%d %p\n",
x, y, w, h, bpl, dest->bytes_per_line, dest->width, dest->height, dest->bits_per_pixel, dest->depth, dst);
for (line = 0; line < h; line++) {
//fprintf(stderr, "w=%d h=%d x=%d y+line=%d\n", w, h, x, y+line);
if (! raw_fb_seek) {
/* mmap */
src = raw_fb_addr + raw_fb_offset + bpl*(y+line);
memcpy(buf, src, bpl);
} else {
/* lseek */
off_t off;
off = (off_t) (raw_fb_offset + bpl*(y+line));
lseek(raw_fb_fd, off, SEEK_SET);
len = bpl;
del = 0;
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;
}
}
}
for (ix = 0; ix < w; ix++) {
int bx = (x + ix) * raw_fb_native_bpp;
int ib = bx / 8;
int br = bx - ib * 8;
unsigned char val;
//fprintf(stderr, "%d\n", ix);
val = *((unsigned char*) (buf + ib));
val = msk[br] & val;
val = val >> br;
if (cga) {
/* this is expt for CGA */
double r, g, b;
int ir, ig, ib;
r = (2./3)*(val & 4) + (1./3)*(val & 8);
g = (2./3)*(val & 2) + (1./3)*(val & 8);
b = (2./3)*(val & 1) + (1./3)*(val & 8);
if (val == 6) {
g = g/2.;
}
ir = rx_f * r;
ig = gx_f * g;
ib = bx_f * b;
val = (ib << bs_f) | (ig << gs_f) | (ir << rs_f);
} else {
unsigned char rval, gval, bval;
rval = (val & rm_n) >> rs_n;
gval = (val & gm_n) >> gs_n;
bval = (val & bm_n) >> bs_n;
rval = (rx_f * rval) / rx_n;
gval = (gx_f * gval) / gx_n;
bval = (bx_f * bval) / bx_n;
rval = rval << rs_f;
gval = gval << gs_f;
bval = bval << bs_f;
val = rval | gval | bval;
}
*(dst+ix) = (char) val;
}
//fprintf(stderr, "\n", ix);
dst += dest->bytes_per_line;
}
}
static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w,
unsigned int h) {
/*
......@@ -491,6 +649,10 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
copy_raw_fb_24_to_32(dest, x, y, w, h);
return;
}
if (raw_fb_native_bpp < 8) {
copy_raw_fb_low_bpp(dest, x, y, w, h);
return;
}
if (clipshift && ! use_snapfb) {
x += coff_x;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment