diff options
Diffstat (limited to 'x11vnc/screen.c')
-rw-r--r-- | x11vnc/screen.c | 204 |
1 files changed, 157 insertions, 47 deletions
diff --git a/x11vnc/screen.c b/x11vnc/screen.c index 05da0df..2d7ed73 100644 --- a/x11vnc/screen.c +++ b/x11vnc/screen.c @@ -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); } |