x11vnc: support for video4linux webcams & tv-tuners, -24to32 bpp option, -rawfb console.

pull/1/head
runge 18 years ago
parent 0d734ad896
commit 279f35495a

@ -1,3 +1,6 @@
2006-05-06 Karl Runge <runge@karlrunge.com>
* configure.ac: add linux/videodev.h and linux/fb.h detection.
2006-05-04 Steven Carr <scarr@jsa-usa.com>
* rfbEncodingSupportedEncodings - What encodings are supported?
* rfbEncodingSupportedMessages - What message types are supported?

@ -60,6 +60,8 @@ AH_TEMPLATE(HAVE_RECORD, [RECORD extension build environment present])
AH_TEMPLATE(HAVE_SOLARIS_XREADSCREEN, [Solaris XReadScreen available])
AH_TEMPLATE(HAVE_IRIX_XREADDISPLAY, [IRIX XReadDisplay available])
AH_TEMPLATE(HAVE_FBPM, [FBPM extension build environment present])
AH_TEMPLATE(HAVE_LINUX_VIDEODEV_H, [video4linux build environment present])
AH_TEMPLATE(HAVE_LINUX_FB_H, [linux fb device build environment present])
AC_ARG_WITH(xkeyboard,
[ --without-xkeyboard disable xkeyboard extension support],,)
@ -77,6 +79,10 @@ AC_ARG_WITH(xrecord,
[ --without-xrecord disable xrecord extension support],,)
AC_ARG_WITH(fbpm,
[ --without-fbpm disable fbpm extension support],,)
AC_ARG_WITH(v4l,
[ --without-v4l disable video4linux support],,)
AC_ARG_WITH(fbdev,
[ --without-fbdev disable linux fb device support],,)
if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(X11, XGetImage, HAVE_X="true",
@ -223,6 +229,15 @@ if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
fi
fi
if test "x$with_v4l" != "xno"; then
AC_CHECK_HEADER(linux/videodev.h,
[AC_DEFINE(HAVE_LINUX_VIDEODEV_H)],,)
fi
if test "x$with_fbdev" != "xno"; then
AC_CHECK_HEADER(linux/fb.h,
[AC_DEFINE(HAVE_LINUX_FB_H)],,)
fi
X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS"
fi
fi
@ -237,7 +252,8 @@ Make sure any required X development packages are installed. If they are
installed in non-standard locations, one can use the --x-includes=DIR
and --x-libraries=DIR configure options or set the CPPFLAGS and LDFLAGS
environment variables to indicate where the X window system header files
and libraries may be found.
and libraries may be found. On 64+32 bit machines you may need to point
to lib64 or lib32 directories to pick up the correct word size.
==========================================================================
])
fi

@ -70,6 +70,8 @@ static void set_root_cmap(void) {
static XColor color[NCOLOR];
int redo = 0;
RAWFB_RET_VOID
if (now > last_set + 10) {
redo = 1;
}
@ -134,6 +136,8 @@ static int check_pointer_in_depth24(void) {
c = window;
RAWFB_RET(0)
if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
return 0;
}
@ -251,6 +255,8 @@ void check_for_multivis(void) {
double now = dnow();
double delay;
RAWFB_RET_VOID
if (now > last_parse + 1.0) {
last_parse = now;
parse_cmap8to24();
@ -743,6 +749,7 @@ if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bp
}
static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
RAWFB_RET(NULL)
if (xi == NULL || *w < dpy_x) {
char *d;
if (xi) {
@ -782,6 +789,8 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
int mx1, mx2, my1, my2;
int ns = NSCAN/2;
RAWFB_RET(1)
if (win == None) {
return 1;
}
@ -1269,6 +1278,8 @@ static int get_cmap(int j, Colormap cmap) {
int i, ncells;
XErrorHandler old_handler = NULL;
RAWFB_RET(0)
if (0) {
/* not working properly for depth 24... */
X_LOCK;
@ -1401,7 +1412,7 @@ static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
if (xi) {
XDestroyImage(xi);
}
if (! valid_window(win, &attr, 1)) {
if (! dpy || ! valid_window(win, &attr, 1)) {
return (XImage *) NULL;
}
if (attr.depth != win_depth) {
@ -1434,6 +1445,8 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rect.y1, rect.x2, rect.y2, cm);
RAWFB_RET_VOID
/* now transform the pixels in this rectangle: */
n_off = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
@ -1653,6 +1666,8 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
double now;
double dt, d0 = 0.0, t2;
RAWFB_RET_VOID
if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */
return;
@ -1877,6 +1892,8 @@ void mark_8bpp(int mode) {
int i, cnt = 0;
Window top = None;
RAWFB_RET_VOID
if (! cmap8to24 || !cmap8to24_fb) {
return;
}

@ -1,3 +1,11 @@
2006-05-06 Karl Runge <runge@karlrunge.com>
* x11vnc: improved support for webcams and tv tuners with
video4linux /dev/video: -rawfb video, -freqtab etc.
Convenience option for linux VT's: -rawfb cons (LinuxVNC
method). -pipeinput builtins for video and console.
-24to32 option to avoid 24bpp problems. "snap:" method for
-rawfb.
2006-04-26 Karl Runge <runge@karlrunge.com>
* x11vnc: skip exit in check_openssl() if not compiled with
libssl. set SKIP_HELP (again) in small footprint builds.

@ -13,7 +13,7 @@ endif
if HAVE_X
bin_PROGRAMS=x11vnc
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h unixpw.h user.h userinput.h util.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c linuxfb.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c v4l.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h linuxfb.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h unixpw.h user.h userinput.h util.h v4l.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
INCLUDES=@X_CFLAGS@
x11vnc_LDADD=$(LDADD) @X_LIBS@ $(LD_CYGIPC)
endif

File diff suppressed because it is too large Load Diff

@ -13,6 +13,7 @@
#include "scan.h"
#include "sslcmds.h"
#include "sslhelper.h"
#include "xwrappers.h"
/*
* routines for handling incoming, outgoing, etc connections
@ -864,7 +865,7 @@ static unsigned char t2x2_bits[] = {
KeyCode key_o;
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (! accept) {
sprintf(str_y, "OK");
@ -951,7 +952,7 @@ static unsigned char t2x2_bits[] = {
XSetDashes(dpy, gc, 0, dash_list, list_length);
XMapWindow(dpy, awin);
XFlush(dpy);
XFlush_wr(dpy);
if (accept) {
snprintf(strh, 100, "x11vnc: accept connection from %s?", addr);
@ -1107,7 +1108,7 @@ static unsigned char t2x2_bits[] = {
XUnmapWindow(dpy, awin);
XFreeGC(dpy, gc);
XDestroyWindow(dpy, awin);
XFlush(dpy);
XFlush_wr(dpy);
break;
}
}
@ -1438,7 +1439,12 @@ static void check_connect_file(char *file) {
} else {
rfbLog("read connect file: %s\n", str);
}
client_connect = str;
if (!strcmp(str, "cmd=stop") &&
dnow() - x11vnc_start < 3.0) {
rfbLog("ignoring stale cmd=stop\n");
} else {
client_connect = str;
}
}
}
}
@ -1586,11 +1592,13 @@ void reverse_connect(char *str) {
* for changes. The vncconnect(1) will set it on our X display.
*/
void set_vnc_connect_prop(char *str) {
RAWFB_RET_VOID
XChangeProperty(dpy, rootwin, vnc_connect_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
void set_x11vnc_remote_prop(char *str) {
RAWFB_RET_VOID
XChangeProperty(dpy, rootwin, x11vnc_remote_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
@ -1609,6 +1617,7 @@ void read_vnc_connect_prop(int nomsg) {
/* not active or problem with VNC_CONNECT atom */
return;
}
RAWFB_RET_VOID
/* read the property value into vnc_connect_str: */
do {
@ -1654,6 +1663,7 @@ void read_x11vnc_remote_prop(int nomsg) {
/* not active or problem with X11VNC_REMOTE atom */
return;
}
RAWFB_RET_VOID
/* read the property value into x11vnc_remote_str: */
do {

@ -824,6 +824,8 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
int nm_info = 1;
XErrorHandler old_handler;
RAWFB_RET_VOID
X_LOCK;
if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
@ -1208,7 +1210,7 @@ static int get_xfixes_cursor(int init) {
return -1;
}
if (xfixes_present) {
if (xfixes_present && dpy) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
int use, oldest, i;
time_t oldtime, now;
@ -1388,6 +1390,7 @@ void initialize_cursors_mode(void) {
int get_which_cursor(void) {
int which = CURS_ARROW;
int db = 0;
if (show_multiple_cursors) {
int depth;
@ -1416,6 +1419,7 @@ int get_which_cursor(void) {
}
if (mode == 3 && xfixes_present && use_xfixes) {
if (db) fprintf(stderr, "get_which_cursor call get_xfixes_cursor\n");
return get_xfixes_cursor(0);
}
@ -1444,7 +1448,7 @@ int get_which_cursor(void) {
int which0 = which;
/* apply crude heuristics to choose a cursor... */
if (win) {
if (win && dpy) {
int ratio = 10, x, y;
unsigned int w, h, bw, d;
Window r;
@ -1495,6 +1499,7 @@ int get_which_cursor(void) {
}
}
}
if (db) fprintf(stderr, "get_which_cursor which: %d\n", which);
return which;
}
@ -1768,7 +1773,7 @@ int check_x11_pointer(void) {
int x, y;
unsigned int mask;
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (unixpw_in_progress) return 0;

@ -70,6 +70,8 @@ int tray_embed(Window iconwin, int remove) {
long info[2] = {XEMBED_VERSION, XEMBED_MAPPED};
long data = 0;
RAWFB_RET(0)
if (remove) {
if (!valid_window(iconwin, &attr, 1)) {
return 0;
@ -156,6 +158,8 @@ static int tray_manager_running(Display *d, Window *manager) {
Atom tray_manager;
Window tray_win;
RAWFB_RET(0)
if (manager) {
*manager = None;
}

@ -228,9 +228,22 @@ void print_help(int mode) {
" this machine -overlay is supported and gives better\n"
" response.\n"
"\n"
" Debugging for this mode can be enabled by setting \n"
" Debugging for this mode can be enabled by setting\n"
" \"dbg=1\", \"dbg=2\", or \"dbg=3\".\n"
"\n"
"-24to32 Very rare problem: if the framebuffer (X display\n"
" or -rawfb) is 24bpp instead of the usual 32bpp, then\n"
" dynamically transform the pixels to 32bpp. This will be\n"
" slower, but can be used to work around problems where\n"
" VNC viewers cannot handle 24bpp (e.g. \"main: setPF:\n"
" not 8, 16 or 32 bpp?\"). See the FAQ for more info.\n"
"\n"
" In the case of -rawfb mode, the pixels are directly\n"
" modified by inserting a 0 byte to pad them out to 32bpp.\n"
" For X displays, a kludge is done that is equivalent to\n"
" \"-noshm -visual TrueColor:32\". (If better performance\n"
" is needed for the latter, feel free to ask).\n"
"\n"
"-scale fraction Scale the framebuffer by factor \"fraction\". Values\n"
" less than 1 shrink the fb, larger ones expand it. Note:\n"
" image may not be sharp and response may be slower.\n"
@ -2154,13 +2167,17 @@ void print_help(int mode) {
" or where window tearing is a problem.\n"
"\n"
"-rawfb string Experimental option, instead of polling X, poll the\n"
" memory object specified in \"string\". For shared\n"
" memory segments it is of the form: \"shm:N@WxHxB\"\n"
" which specifies a shmid N and framebuffer Width, Height,\n"
" and Bits per pixel. To memory map mmap(2) a file use:\n"
" memory object specified in \"string\".\n"
"\n"
" For shared memory segments string is of the\n"
" form: \"shm:N@WxHxB\" which specifies a shmid\n"
" N and framebuffer Width, Height, and Bits\n"
" per pixel. To memory map mmap(2) a file use:\n"
" \"map:/path/to/a/file@WxHxB\". If there is trouble\n"
" with mmap, use \"file:/...\" for slower lseek(2)\n"
" based reading. If you do not supply a type \"map\"\n"
" with mmap, use \"file:/...\" for slower lseek(2) based\n"
" reading. Use \"snap:...\" to imply -snapfb mode and the\n"
" \"file:\" access (this is for devices that only provide\n"
" the fb all at once). If you do not supply a type \"map\"\n"
" is assumed if the file exists.\n"
"\n"
" If string is \"setup:cmd\", then the command \"cmd\"\n"
@ -2169,6 +2186,14 @@ void print_help(int mode) {
" determining WxHxB, etc. These are often done as root\n"
" so take care.\n"
"\n"
" If the string begins with \"video\", see the video4linux\n"
" discusion below where the device may be queried for\n"
" (and possibly set) the framebuffer parameters.\n"
"\n"
" If the strings begins with \"cons\", see the linux\n"
" console discussion below where the framebuffer device\n"
" is opened and keystrokes are inserted into the console.\n"
"\n"
" Optional suffixes are \":R/G/B\" and \"+O\" to specify\n"
" red, green, and blue masks and an offset into the\n"
" memory object. If the masks are not provided x11vnc\n"
@ -2179,6 +2204,11 @@ void print_help(int mode) {
" -rawfb map:/dev/fb0@1024x768x32\n"
" -rawfb map:/tmp/Xvfb_screen0@640x480x8+3232\n"
" -rawfb file:/tmp/my.pnm@250x200x24+37\n"
" -rawfb file:/dev/urandom@128x128x8\n"
" -rawfb snap:/dev/video0@320x240x24 -24to32\n"
" -rawfb video0\n"
" -rawfb video -pipeinput VID\n"
" -rawfb console\n"
"\n"
" (see ipcs(1) and fbset(1) for the first two examples)\n"
"\n"
@ -2186,16 +2216,157 @@ void print_help(int mode) {
" -pipeinput option). Most of the X11 (screen, keyboard,\n"
" mouse) options do not make sense and many will cause\n"
" this mode to crash, so please think twice before\n"
" setting/changing them.\n"
" setting or changing them in a running x11vnc.\n"
"\n"
" If you DO NOT want x11vnc to close the X DISPLAY in\n"
" rawfb mode, prepend a \"+\" e.g. +file:/dev/fb0...\n"
" Keeping the display open enables the default\n"
" remote-control channel, which could be useful.\n"
" Alternatively, if you specify -noviewonly, then the\n"
" mouse and keyboard input are STILL sent to the X\n"
" display, this usage should be very rare, i.e. doing\n"
" something strange with /dev/fb0.\n"
"\n"
" If the device is not \"seekable\" try reading it all\n"
" at once in full snaps via the \"snap:\" mode (note:\n"
" this is a resource hog). If you are using file: or\n"
" map: and the device needs to be reopened for *every*\n"
" snapfb snapshot, set the environment variable:\n"
" SNAPFB_RAWFB_RESET=1 as well.\n"
"\n"
" If you want x11vnc to dynamically transform a 24bpp\n"
" rawfb to 32bpp (note that this will be slower) use\n"
" the -24to32 option. This would be useful for, say,\n"
" for a video camera that delivers the pixel data as\n"
" 24bpp packed RGB. This is the default under \"video\"\n"
" mode if the bpp is 24.\n"
"\n"
" video4linux: on Linux some attempt is made to handle\n"
" video devices (webcams or tv tuners) automatically.\n"
" The idea is the WxHxB will be extracted from the\n"
" device itself. So if you do not supply \"@WxHxB...\n"
" parameters x11vnc will try to determine them. It first\n"
" tries the v4l API if that support has been compiled in.\n"
" Otherwise it will run the v4l-info(1) external program\n"
" if it is available.\n"
"\n"
" The simplest examples are \"-rawfb video\" and \"-rawfb\n"
" video1\" which imply the device file /dev/video and\n"
" /dev/video1, respectively. You can also supply the\n"
" /dev if you like, e.g. \"-rawfb /dev/video0\"\n"
"\n"
" Since the video capture device framebuffer usually\n"
" changes continuously (e.g. brightness fluctuations),\n"
" you may want to use the -wait, -slow_fb, or -defer\n"
" options to lower the \"framerate\" to cut down on\n"
" network VNC traffic.\n"
"\n"
" A more sophisticated video device scheme allows\n"
" initializing the device's settings using:\n"
"\n"
" -rawfb video:<settings>\n"
"\n"
" The prefix could also be, as above, e.g. \"video1:\" to\n"
" specify the device file. The v4l API must be available\n"
" for this to work. Otherwise, you will need to try\n"
" to initialize the device with an external program,\n"
" e.g. xawtv, spcaview, and hope they persist when x11vnc\n"
" re-opens the device.\n"
"\n"
" <settings> is a comma separated list of key=value pairs.\n"
" The device's brightness, color, contrast, and hue can\n"
" be set to percentages, e.g. br=80,co=50,cn=44,hu=60.\n"
"\n"
" The device filename can be set too if needed (if it\n"
" does not start with \"video\"), e.g. fn=/dev/qcam.\n"
"\n"
" The width, height and bpp of the framebuffer can be\n"
" set via, e.g., w=160,h=120,bpp=16.\n"
"\n"
" Related to the bpp above, the pixel format can be set\n"
" via the fmt=XXX, where XXX can be one of: GREY, HI240,\n"
" RGB555, RGB565, RGB24, and RGB32 (with bpp 8, 8, 16, 16,\n"
" 24, and 32 respectively). See http://www.linuxtv.org\n"
" for more info (V4L api).\n"
"\n"
" For tv/rf tuner cards one can set the tuning mode\n"
" via tun=XXX where XXX can be one of PAL, NTSC, SECAM,\n"
" or AUTO.\n"
"\n"
" One can switch the input channel by the inp=XXX setting,\n"
" where XXX is the name of the input channel (Television,\n"
" Composite1, S-Video, etc). Use the name that is in the\n"
" information about the device that is printed at startup.\n"
"\n"
" For input channels with tuners (e.g. Television) one\n"
" can change which station is selected by the sta=XXX\n"
" setting. XXX is the station number. Currently only\n"
" the ntsc-cable-us (US cable) channels are built into\n"
" x11vnc. See the -freqtab option below to supply one\n"
" from xawtv. If XXX is greater than 500, then it is\n"
" interpreted as a raw frequency in KHz.\n"
"\n"
" Example:\n"
"\n"
" -rawfb video:br=80,w=320,h=240,fmt=RGB32,tun=NTSC,sta=47\n"
"\n"
" one might need to add inp=Television too for the input\n"
" channel to be TV if the card doesn't come up by default\n"
" in that one.\n"
"\n"
" Note that not all video capture devices will support\n"
" all of the above settings.\n"
"\n"
" See the -pipeinput VID option below for a way to control\n"
" the settings through the VNC Viewer via keystrokes.\n"
"\n"
" As above, if you specify a \"@WxHxB...\" after the\n"
" <settings> string they are used verbatim: the device\n"
" is not queried for the current values. Otherwise the\n"
" device will be queried.\n"
"\n"
" Linux console: If the libvncserver LinuxVNC command is\n"
" on your system use that instead of the following method\n"
" because it will be faster and more accurate for Linux\n"
" text console.\n"
"\n"
" If the rawfb string begins with \"cons\" the framebuffer\n"
" device /dev/fb0 is opened (this requires the appropriate\n"
" kernel modules) and so is /dev/tty0. The latter is\n"
" used to inject keystrokes (not all are supported,\n"
" but the basic ones are). You will need to be root to\n"
" inject keystrokes. /dev/tty0 refers to the active VT,\n"
" to indicate one explicitly, use \"cons2\", etc. using\n"
" the VT number. Note you can change VT remotely using\n"
" the chvt(1) command. Sometimes switching out and back\n"
" corrects the framebuffer. To skip injecting entirely\n"
" use \"consx\".\n"
"\n"
" The strings \"console\", or \"/dev/fb0\" can be used\n"
" instead of \"cons\". The latter can be used to specify\n"
" a different framebuffer device, e.g. /dev/fb1. If the\n"
" name is something nonstandard, use \"cons:/dev/foofb\"\n"
"\n"
" If you do not want x11vnc to guess the framebuffer's\n"
" WxHxB and masks automatically, specify them with a\n"
" @WxHxB at the end of the string.\n"
"\n"
" If you don't want x11vnc to close the X DISPLAY in\n"
" rawfb mode, then capitalize the prefix, SHM:, MAP:,\n"
" FILE: Keeping the display open enables the default\n"
" remote-control channel, which could be useful. Also,\n"
" if you also specify -noviewonly, then the mouse and\n"
" keyboard input are STILL sent to the X display, this\n"
" usage should be very rare, i.e. doing something strange\n"
" with /dev/fb0.\n"
" Examples:\n"
" -rawfb cons (same as -rawfb console)\n"
" -rawfb /dev/fb0 (same)\n"
" -rawfb cons3 (force /dev/tty3)\n"
" -rawfb consx (no keystrokes)\n"
" -rawfb console:/dev/nonstd\n"
"\n"
"-freqtab file For use with \"-rawfb video\" for TV tuner devices to\n"
" specify station frequencies. Instead of using the built\n"
" in ntsc-cable-us mapping of station number to frequency,\n"
" use the data in file. For stations that are not\n"
" numeric, e.g. SE20, they are placed above the highest\n"
" numbered station in the order they are found. Example:\n"
" \"-freqtab /usr/X11R6/share/xawtv/europe-west.list\"\n"
" You can make your own freqtab by copying the xawtv\n"
" format.\n"
"\n"
"-pipeinput cmd Another experimental option: it lets you supply an\n"
" external command in \"cmd\" that x11vnc will pipe\n"
@ -2214,6 +2385,22 @@ void print_help(int mode) {
" value is stored in X11VNC_RAWFB_STR for the pipe command\n"
" to use if it wants. Do 'env | grep X11VNC' for more.\n"
"\n"
" If cmd is \"VID\" and you are using the -rawfb for a\n"
" video capture device, then an internal list of keyboard\n"
" mappings is used to set parameters of the video.\n"
" The mappings are:\n"
"\n"
" \"B\" and \"b\" adjust the brightness up and down.\n"
" \"H\" and \"h\" adjust the hue.\n"
" \"C\" and \"c\" adjust the colour.\n"
" \"N\" and \"n\" adjust the contrast.\n"
" \"S\" and \"s\" adjust the size of the capture screen.\n"
" \"I\" and \"i\" cycle through input channels.\n"
" Up and Down arrows adjust the station (if a tuner)\n"
" F1, F2, ..., F6 will switch the video capture pixel\n"
" format to HI240, RGB565, RGB24, RGB32, RGB555, and\n"
" GREY respectively. See -rawfb video for details.\n"
"\n"
"-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote\n"
" control options -remote/-query described below.\n"
" Requires the \"wish\" program to be installed on the\n"
@ -2365,6 +2552,8 @@ void print_help(int mode) {
" 8to24 enable -8to24 mode (if applicable).\n"
" no8to24 disable -8to24 mode.\n"
" 8to24_opts:str set the -8to24 opts to \"str\".\n"
" 24to32 enable -24to32 mode (if applicable).\n"
" no24to32 disable -24to32 mode.\n"
" visual:vis set -visual to \"vis\"\n"
" scale:frac set -scale to \"frac\"\n"
" scale_cursor:f set -scale_cursor to \"f\"\n"
@ -2639,15 +2828,15 @@ void print_help(int mode) {
" truecolor notruecolor overlay nooverlay overlay_cursor\n"
" overlay_yescursor nooverlay_nocursor nooverlay_cursor\n"
" nooverlay_yescursor overlay_nocursor 8to24 no8to24\n"
" 8to24_opts visual scale scale_cursor viewonly noviewonly\n"
" shared noshared forever noforever once timeout filexfer\n"
" nofilexfer deny lock nodeny unlock connect allowonce\n"
" allow localhost nolocalhost listen lookup nolookup\n"
" accept afteraccept gone shm noshm flipbyteorder\n"
" noflipbyteorder onetile noonetile solid_color\n"
" solid nosolid blackout xinerama noxinerama xtrap\n"
" noxtrap xrandr noxrandr xrandr_mode padgeom quiet q\n"
" noquiet modtweak nomodtweak xkb noxkb skip_keycodes\n"
" 8to24_opts 24to32 no24to32 visual scale scale_cursor\n"
" viewonly noviewonly shared noshared forever noforever\n"
" once timeout filexfer nofilexfer deny lock nodeny\n"
" unlock connect allowonce allow localhost nolocalhost\n"
" listen lookup nolookup accept afteraccept gone shm\n"
" noshm flipbyteorder noflipbyteorder onetile noonetile\n"
" solid_color solid nosolid blackout xinerama noxinerama\n"
" xtrap noxtrap xrandr noxrandr xrandr_mode padgeom quiet\n"
" q noquiet modtweak nomodtweak xkb noxkb skip_keycodes\n"
" sloppy_keys nosloppy_keys skip_dups noskip_dups\n"
" add_keysyms noadd_keysyms clear_mods noclear_mods\n"
" clear_keys noclear_keys remap repeat norepeat fb nofb\n"

@ -11,6 +11,8 @@
#include "cleanup.h"
#include "allowed_input_t.h"
#include "unixpw.h"
#include "v4l.h"
#include "linuxfb.h"
void get_keystate(int *keystate);
void clear_modifiers(int init);
@ -54,6 +56,8 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
void get_keystate(int *keystate) {
int i, k;
char keys[32];
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
XQueryKeymap(dpy, keys);
@ -85,6 +89,8 @@ void clear_modifiers(int init) {
KeySym keysym;
KeyCode keycode;
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
if (first) {
/*
@ -134,7 +140,7 @@ void clear_modifiers(int init) {
}
XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
}
XFlush(dpy);
XFlush_wr(dpy);
}
static KeySym simple_mods[] = {
@ -211,6 +217,8 @@ int track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set) {
*/
void clear_keys(void) {
int k, keystate[256];
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
get_keystate(keystate);
@ -221,7 +229,7 @@ void clear_keys(void) {
XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
}
}
XFlush(dpy);
XFlush_wr(dpy);
}
/*
@ -238,6 +246,9 @@ static int save_auto_repeat = -1;
int get_autorepeat_state(void) {
XKeyboardState kstate;
RAWFB_RET(0)
X_LOCK;
XGetKeyboardControl(dpy, &kstate);
X_UNLOCK;
@ -255,7 +266,7 @@ void autorepeat(int restore, int bequiet) {
int global_auto_repeat;
XKeyboardControl kctrl;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (restore) {
if (save_auto_repeat < 0) {
@ -271,7 +282,7 @@ void autorepeat(int restore, int bequiet) {
kctrl.auto_repeat_mode = save_auto_repeat;
XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (! bequiet && ! quiet) {
@ -291,7 +302,7 @@ void autorepeat(int restore, int bequiet) {
X_LOCK;
kctrl.auto_repeat_mode = AutoRepeatModeOff;
XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (! bequiet && ! quiet) {
@ -352,7 +363,7 @@ int add_keysym(KeySym keysym) {
first = 0;
}
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (keysym == NoSymbol) {
return 0;
@ -419,7 +430,7 @@ int add_keysym(KeySym keysym) {
}
}
XFlush(dpy);
XFlush_wr(dpy);
added_keysyms[kc] = keysym;
ret = kc;
break;
@ -434,7 +445,7 @@ static void delete_keycode(KeyCode kc, int bequiet) {
KeySym ksym, new[8];
char *str;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
XDisplayKeycodes(dpy, &minkey, &maxkey);
keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
@ -454,7 +465,7 @@ static void delete_keycode(KeyCode kc, int bequiet) {
}
XFree(keymap);
XFlush(dpy);
XFlush_wr(dpy);
}
static int count_added_keycodes(void) {
@ -599,7 +610,7 @@ static void add_dead_keysyms(char *str) {
inmap = 1;
}
#if LIBVNCSERVER_HAVE_XKEYBOARD
if (! inmap && xkb_present) {
if (! inmap && xkb_present && dpy) {
int kc, grp, lvl;
for (kc = 0; kc < 0x100; kc++) {
for (grp = 0; grp < 4; grp++) {
@ -753,6 +764,8 @@ int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new) {
if (!sloppy_keys) {
return 0;
}
RAWFB_RET(0)
if (!down && !keycode_state[key] && !IsModifierKey(keysym)) {
int i, cnt = 0, downkey = -1;
@ -863,6 +876,7 @@ void switch_to_xkb_if_better(void) {
/* already using it */
return;
}
RAWFB_RET_VOID
XDisplayKeycodes(dpy, &minkey, &maxkey);
@ -1110,6 +1124,8 @@ xkbmodifiers[] For the KeySym bound to this (keycode,group,level) store
*
*/
RAWFB_RET_VOID
/* initialize all the arrays: */
for (kc = 0; kc < 0x100; kc++) {
multi_key[kc] = 0;
@ -1414,6 +1430,8 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if (client) {} /* unused vars warning: */
RAWFB_RET_VOID
X_LOCK;
if (debug_keyboard) {
@ -2144,6 +2162,8 @@ void initialize_modtweak(void) {
keycodes[i] = NoSymbol;
}
RAWFB_RET_VOID
X_LOCK;
XDisplayKeycodes(dpy, &minkey, &maxkey);
@ -2230,6 +2250,8 @@ static void tweak_mod(signed char mod, rfbBool down) {
Bool dn = (Bool) down;
KeyCode altgr = altgr_code;
RAWFB_RET_VOID
if (mod < 0) {
if (debug_keyboard) {
rfbLog("tweak_mod: Skip: down=%d index=%d\n", down,
@ -2281,6 +2303,8 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
KeyCode k;
int tweak = 0;
RAWFB_RET_VOID
if (use_xkb_modtweak) {
xkb_tweak_keyboard(down, keysym, client);
return;
@ -2344,7 +2368,7 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
void initialize_keyboard_and_pointer(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (use_modifier_tweak) {
initialize_modtweak();
@ -2417,6 +2441,12 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
char *name;
ClientData *cd = (ClientData *) client->clientData;
if (pipeinput_int == PIPEINPUT_VID) {
v4l_key_command(down, keysym, client);
}
if (pipeinput_int == PIPEINPUT_CONS) {
console_key_command(down, keysym, client);
}
if (pipeinput_fh == NULL) {
return;
}
@ -2698,7 +2728,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
skipped_last_down = 0;
last_rfb_key_accepted = TRUE;
if (pipeinput_fh != NULL) {
if (pipeinput_fh != NULL || pipeinput_int) {
pipe_keyboard(down, keysym, client);
if (! pipeinput_tee) {
if (! view_only || raw_fb) { /* raw_fb hack */
@ -2742,7 +2772,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
got_user_input++;
got_keyboard_input++;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (keyremaps) {
keyremap_t *remap = keyremaps;
@ -2810,7 +2840,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
do_button_mask_change(mask, button); /* down */
mask = 0;
do_button_mask_change(mask, button); /* up */
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return;
}
@ -2818,7 +2848,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
if (use_modifier_tweak) {
modifier_tweak_keyboard(down, keysym, client);
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return;
}
@ -2842,7 +2872,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
if ( k != NoSymbol ) {
XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
}
X_UNLOCK;

@ -0,0 +1,234 @@
/* -- linuxfb.c -- */
#include "x11vnc.h"
#include "cleanup.h"
#include "scan.h"
#include "xinerama.h"
#include "screen.h"
#include "pointer.h"
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if LIBVNCSERVER_HAVE_LINUX_FB_H
#include <linux/fb.h>
#endif
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);
char *console_guess(char *str, int *fd) {
char *q, *in = strdup(str);
char *atparms = NULL, *file = NULL;
int tty = -1;
if (strstr(in, "/dev/fb") == in) {
free(in);
in = (char *) malloc(strlen("cons:") + strlen(str) + 1);
sprintf(in, "cons:%s", str);
} else if (strstr(in, "fb") == in) {
free(in);
in = (char *) malloc(strlen("cons:/dev/") + strlen(str) + 1);
sprintf(in, "cons:/dev/%s", str);
}
if (strstr(in, "cons") != in) {
rfbLog("console_guess: unrecognized console/fb format: %s\n", str);
free(in);
return NULL;
}
q = strrchr(in, '@');
if (q) {
atparms = strdup(q+1);
*q = '\0';
}
q = strrchr(in, ':');
if (q) {
file = strdup(q+1);
*q = '\0';
}
if (! file || file[0] == '\0') {
file = strdup("/dev/fb");
}
if (strstr(file, "fb") == file) {
q = (char *) malloc(strlen("/dev/") + strlen(file) + 1);
sprintf(q, "/dev/%s", file);
free(file);
file = q;
}
if (!strcmp(file, "/dev/fb")) {
/* sometimes no sylink fb -> fb0 */
struct stat sbuf;
if (stat(file, &sbuf) != 0) {
free(file);
file = strdup("/dev/fb0");
}
}
rfbLog("console_guess: file is %s\n", file);
if (!strcmp(in, "cons") || !strcmp(in, "console")) {
/* current active VT: */
tty = 0;
} else {
int n;
if (sscanf(in, "cons%d", &n) == 1) {
tty = n;
} else if (sscanf(in, "console%d", &n) != 1) {
tty = n;
}
}
if (tty >=0 && tty < 64) {
if (pipeinput_str == NULL) {
pipeinput_str = (char *) malloc(10);
sprintf(pipeinput_str, "CONS%d", tty);
rfbLog("console_guess: file pipeinput %s\n", pipeinput_str);
initialize_pipeinput();
}
}
if (! atparms) {
#if LIBVNCSERVER_HAVE_LINUX_FB_H
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
struct fb_var_screeninfo var_info;
int d = open(file, O_RDWR);
if (d >= 0) {
int w, h, b;
unsigned long rm = 0, gm = 0, bm = 0;
if (ioctl(d, FBIOGET_VSCREENINFO, &var_info) != -1) {
w = (int) var_info.xres;
h = (int) var_info.yres;
b = (int) var_info.bits_per_pixel;
rm = (1 << var_info.red.length) - 1;
gm = (1 << var_info.green.length) - 1;
bm = (1 << var_info.blue.length) - 1;
rm = rm << var_info.red.offset;
gm = gm << var_info.green.offset;
bm = bm << var_info.blue.offset;
if (b == 8 && rm == 0xff && gm == 0xff && bm == 0xff) {
/* I don't believe it... */
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
/* @66666x66666x32:0xffffffff:... */
atparms = (char *) malloc(200);
sprintf(atparms, "%dx%dx%d:%lx/%lx/%lx",
w, h, b, rm, gm, bm);
*fd = d;
} else {
perror("ioctl");
close(d);
}
} else {
rfbLog("could not open: %s\n", file);
perror("open");
close(d);
}
#endif
#endif
}
if (! atparms) {
rfbLog("console_guess: could not get @ parameters.\n");
return NULL;
}
q = (char *) malloc(strlen("map:") + strlen(file) + 1 + strlen(atparms) + 1);
sprintf(q, "map:%s@%s", file, atparms);
return q;
}
void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
static int control = 0;
if (debug_keyboard) fprintf(stderr, "console_key_command: %d %s\n", (int) keysym, down ? "down" : "up");
if (pipeinput_cons_fd < 0) {
return;
}
/* From LinuxVNC.c: */
if (keysym == XK_Control_L || keysym == XK_Control_R) {
if (! down) {
if (control > 0) {
control--;
}
} else {
control++;
}
return;
}
if (!down) {
return;
}
if (keysym == XK_Escape) {
keysym = 27;
}
if (control) {
if (keysym >= 'a' && keysym <= 'z') {
keysym -= ('a' - 1);
} else if (keysym >= 'A' && keysym <= 'Z') {
keysym -= ('A' - 1);
} else {
keysym = 0xffff;
}
}
if (keysym == XK_Tab) {
keysym = '\t';
} else if (keysym == XK_Return) {
keysym = '\r';
} else if (keysym == XK_BackSpace) {
keysym = 8;
} else if (keysym == XK_Home || keysym == XK_KP_Home) {
keysym = 1;
} else if (keysym == XK_End || keysym == XK_KP_End) {
keysym = 5;
} else if (keysym == XK_Up || keysym == XK_KP_Up) {
keysym = 16;
} else if (keysym == XK_Down || keysym == XK_KP_Down) {
keysym = 14;
} else if (keysym == XK_Right || keysym == XK_KP_Right) {
keysym = 6;
} else if (keysym == XK_Next || keysym == XK_KP_Next) {
keysym = 6;
} else if (keysym == XK_Left || keysym == XK_KP_Left) {
keysym = 2;
} else if (keysym == XK_Prior || keysym == XK_KP_Prior) {
keysym = 2;
}
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSTI)
if (keysym < 0x100) {
if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) != -1) {
return;
}
perror("ioctl");
close(pipeinput_cons_fd);
pipeinput_cons_fd = -1;
if (! pipeinput_cons_dev) {
return;
}
pipeinput_cons_fd = open(pipeinput_cons_dev, O_WRONLY);
if (pipeinput_cons_fd < 0) {
rfbLog("pipeinput: could not reopen %s\n",
pipeinput_cons_dev);
perror("open");
return;
}
if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) == -1) {
perror("ioctl");
close(pipeinput_cons_fd);
pipeinput_cons_fd = -1;
rfbLog("pipeinput: could not reopen %s\n",
pipeinput_cons_dev);
}
}
#endif
if (client) {}
}
void console_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (mask || x || y || client) {}
}

@ -0,0 +1,10 @@
#ifndef _X11VNC_LINUXFB_H
#define _X11VNC_LINUXFB_H
/* -- linuxfb.h -- */
extern char *console_guess(char *str, int *fd);
extern void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
extern void console_pointer_command(int mask, int x, int y, rfbClientPtr client);
#endif /* _X11VNC_LINUXFB_H */

@ -11,6 +11,7 @@ int debug = 0;
char *use_dpy = NULL; /* -display */
char *auth_file = NULL; /* -auth/-xauth */
char *visual_str = NULL; /* -visual */
int set_visual_str_to_something = 0;
char *logfile = NULL; /* -o, -logfile */
int logfile_append = 0;
char *flagfile = NULL; /* -flag */
@ -102,6 +103,7 @@ int flash_cmap = 0; /* follow installed colormaps */
int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */
int force_indexed_color = 0; /* whether to force indexed color for 8bpp */
int cmap8to24 = 0; /* -8to24 */
int xform24to32 = 0; /* -24to32 */
char *cmap8to24_str = NULL;
int launch_gui = 0; /* -gui */
@ -110,10 +112,15 @@ int use_iso_level3 = 0; /* ISO_Level3_Shift instead of Mode_switch */
int clear_mods = 0; /* -clear_mods (1) and -clear_keys (2) */
int nofb = 0; /* do not send any fb updates */
char *raw_fb_str = NULL; /* used under -rawfb */
char *raw_fb_pixfmt = NULL;
char *freqtab = NULL;
char *pipeinput_str = NULL; /* -pipeinput [tee,reopen,keycodes:]cmd */
char *pipeinput_opts = NULL;
FILE *pipeinput_fh = NULL;
int pipeinput_tee = 0;
int pipeinput_int = 0;
int pipeinput_cons_fd = -1;
char *pipeinput_cons_dev = NULL;
unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0;

@ -11,6 +11,7 @@ extern int debug;
extern char *use_dpy;
extern char *auth_file;
extern char *visual_str;
extern int set_visual_str_to_something;
extern char *logfile;
extern int logfile_append;
extern char *flagfile;
@ -78,6 +79,7 @@ extern int shift_cmap;
extern int force_indexed_color;
extern int cmap8to24;
extern char *cmap8to24_str;
extern int xform24to32;
extern int launch_gui;
extern int use_modifier_tweak;
@ -85,10 +87,15 @@ extern int use_iso_level3;
extern int clear_mods;
extern int nofb;
extern char *raw_fb_str;
extern char *raw_fb_pixfmt;
extern char *freqtab;
extern char *pipeinput_str;
extern char *pipeinput_opts;
extern FILE *pipeinput_fh;
extern int pipeinput_tee;
extern int pipeinput_int;
extern int pipeinput_cons_fd;
extern char *pipeinput_cons_dev;
extern unsigned long subwin;
extern int subwin_wait_mapped;

@ -35,4 +35,8 @@
#define MAXN 256
#define PIPEINPUT_NONE 0x0
#define PIPEINPUT_VID 0x1
#define PIPEINPUT_CONS 0x2
#endif /* _X11VNC_PARAMS_H */

@ -25,7 +25,7 @@ static void check_fbpm(void) {
CARD16 level;
BOOL enabled;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! init_fbpm) {
if (FBPMCapable(dpy)) {
@ -83,7 +83,7 @@ static void check_fbpm(void) {
if (db) fprintf(stderr, "FBPMInfo failed.\n");
}
#else
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! init_fbpm) {
rfbLog("X FBPM extension not supported.\n");
init_fbpm = 1;

@ -11,6 +11,8 @@
#include "connections.h"
#include "cleanup.h"
#include "unixpw.h"
#include "v4l.h"
#include "linuxfb.h"
int pointer_queued_sent = 0;
@ -26,7 +28,6 @@ static void update_x11_pointer_position(int x, int y);
static void update_x11_pointer_mask(int mask);
static void pipe_pointer(int mask, int x, int y, rfbClientPtr client);
/*
* pointer event (motion and button click) handling routines.