diff options
author | runge <runge> | 2006-05-07 00:50:13 +0000 |
---|---|---|
committer | runge <runge> | 2006-05-07 00:50:13 +0000 |
commit | 279f35495a122c9892198545f83e03c6fc50fa08 (patch) | |
tree | 7ce00691a9f77432cead7a5f4ae702fc62878019 /x11vnc/scan.c | |
parent | 0d734ad8967eafab1fb058280a0db04e7470e569 (diff) | |
download | libtdevnc-279f35495a122c9892198545f83e03c6fc50fa08.tar.gz libtdevnc-279f35495a122c9892198545f83e03c6fc50fa08.zip |
x11vnc: support for video4linux webcams & tv-tuners, -24to32 bpp option, -rawfb console.
Diffstat (limited to 'x11vnc/scan.c')
-rw-r--r-- | x11vnc/scan.c | 124 |
1 files changed, 119 insertions, 5 deletions
diff --git a/x11vnc/scan.c b/x11vnc/scan.c index c6dc481..32ac5b5 100644 --- a/x11vnc/scan.c +++ b/x11vnc/scan.c @@ -11,6 +11,7 @@ #include "pointer.h" #include "cleanup.h" #include "unixpw.h" +#include "screen.h" /* * routines for scanning and reading the X11 display for changes, and @@ -223,7 +224,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h, X_LOCK; - if (! using_shm) { + if (! using_shm || xform24to32 || raw_fb) { /* we only need the XImage created */ xim = XCreateImage_wr(dpy, default_visual, depth, ZPixmap, 0, NULL, w, h, raw_fb ? 32 : BitmapPad(dpy), 0); @@ -260,6 +261,11 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h, return 1; } + if (! dpy) { + X_UNLOCK; + return 0; + } + xim = XShmCreateImage_wr(dpy, default_visual, depth, ZPixmap, NULL, shm, w, h); @@ -347,7 +353,20 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) { } #endif if (xim != NULL) { - XDestroyImage(xim); +#if 0 + /* + * This would be needed if you want to crazily switch + * back and forth between rawfb and X. You will also + * need to supply -noviewonly. xim->f is public ABI, + * but we choose not to use it. One could also + * clean up the switch. + */ + if (xim->f.destroy_image) { +#else + { +#endif + XDestroyImage(xim); + } xim = NULL; } X_UNLOCK; @@ -444,7 +463,7 @@ void initialize_polling_images(void) { } } if (!quiet) { - if (using_shm) { + if (using_shm && ! xform24to32) { rfbLog("created %d tile_row shm polling images.\n", tile_shm_count); } else { @@ -1959,6 +1978,7 @@ int copy_screen(void) { if (! main_fb) { return 0; } + fbp = main_fb; y = 0; @@ -1986,13 +2006,106 @@ int copy_screen(void) { return 0; } -int copy_snap(void) { +static void snap_all_rawfb(void) { int pixelsize = bpp/8; + int n, sz; + char *dst; + static char *unclipped_dst = NULL; + static int unclipped_len = 0; + + dst = snap->data; + + if (xform24to32 && bpp == 32) { + pixelsize = 3; + } + sz = dpy_x * dpy_y * pixelsize; + + if (wdpy_x > dpy_x || wdpy_y > dpy_y) { + sz = wdpy_x * wdpy_y * pixelsize; + if (sz > unclipped_len || unclipped_dst == NULL) { + if (unclipped_dst) { + free(unclipped_dst); + } + unclipped_dst = (char *) malloc(sz+4); + unclipped_len = sz; + } + dst = unclipped_dst; + } + + if (! raw_fb_seek) { + memcpy(dst, raw_fb_addr + raw_fb_offset, sz); + + } else { + int len = sz, del = 0; + off_t off = (off_t) raw_fb_offset; + + lseek(raw_fb_fd, off, SEEK_SET); + while (len > 0) { + n = read(raw_fb_fd, dst + del, len); + if (n > 0) { + del += n; + len -= n; + } else if (n == 0) { + break; + } else if (errno != EINTR && errno != EAGAIN) { + break; + } + } + } + + if (dst == unclipped_dst) { + char *src; + int h; + int x = off_x + coff_x; + int y = off_y + coff_y; + + src = unclipped_dst + y * wdpy_x * pixelsize + + x * pixelsize; + dst = snap->data; + + for (h = 0; h < dpy_y; h++) { + memcpy(dst, src, dpy_x * pixelsize); + src += wdpy_x * pixelsize; + dst += dpy_x * pixelsize; + } + } +} + +int copy_snap(void) { + int db = 1, pixelsize = bpp/8; char *fbp; int i, y, block_size; double dt; - static int first = 1; + static int first = 1, snapcnt = 0; + + if (raw_fb_str) { + int read_all_at_once = 1; + double start = dnow(); + if (rawfb_reset < 0) { + if (getenv("SNAPFB_RAWFB_RESET")) { + rawfb_reset = 1; + } else { + rawfb_reset = 0; + } + } + if (snap_fb == NULL || snap == NULL) { + rfbLog("copy_snap: rawfb mode and null snap fb\n"); + clean_up_exit(1); + } + if (rawfb_reset) { + initialize_raw_fb(1); + } + if (read_all_at_once) { + snap_all_rawfb(); + } else { + /* this goes line by line, XXX not working for video */ + copy_raw_fb(snap, 0, 0, dpy_x, dpy_y); + } +if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - start); + return 0; + } + if (! fs_factor) { return 0; } @@ -2005,6 +2118,7 @@ int copy_snap(void) { fbp = snap_fb; y = 0; + dtime0(&dt); X_LOCK; |