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.
*/
@ -116,7 +117,7 @@ static void buttonparse(int from, char **s) {
"keysym: %s\n", t);
n--;
}
} else {
} else if (dpy) {
/*
* XXX may not work with -modtweak or -xkb
*/
@ -214,9 +215,13 @@ void initialize_pointer_map(char *pointer_remap) {
* from -buttonmap option.
*/
X_LOCK;
num_buttons = XGetPointerMapping(dpy, map, MAX_BUTTONS);
X_UNLOCK;
if (!raw_fb_str) {
X_LOCK;
num_buttons = XGetPointerMapping(dpy, map, MAX_BUTTONS);
X_UNLOCK;
} else {
num_buttons = 5;
}
if (num_buttons < 0) {
num_buttons = 0;
@ -284,7 +289,7 @@ void initialize_pointer_map(char *pointer_remap) {
static void update_x11_pointer_position(int x, int y) {
int rc;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
X_LOCK;
if (use_xwarppointer) {
@ -358,7 +363,7 @@ void do_button_mask_change(int mask, int button) {
/* do not send keysym on button up */
continue;
}
if (debug_pointer) {
if (debug_pointer && dpy) {
rfbLog("pointer(): sending button %d "
"down as keycode 0x%x (event %d)\n",
i+1, key, k+1);
@ -387,7 +392,7 @@ static void update_x11_pointer_mask(int mask) {
last_event = last_input = last_pointer_input = time(0);
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (mask != button_mask) {
last_pointer_click_time = dnow();
@ -513,6 +518,12 @@ static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
ClientData *cd = (ClientData *) client->clientData;
char hint[MAX_BUTTONS * 20];
if (pipeinput_int == PIPEINPUT_VID) {
v4l_pointer_command(mask, x, y, client);
}
if (pipeinput_int == PIPEINPUT_CONS) {
console_pointer_command(mask, x, y, client);
}
if (pipeinput_fh == NULL) {
return;
}
@ -795,7 +806,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
"%.4f\n", dnow() - x11vnc_start);
}
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
}
@ -828,13 +839,15 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
sent = 1;
}
if (nofb && sent) {
if (! dpy) {
;
} else if (nofb && sent) {
/*
* nofb is for, e.g. Win2VNC, where fastest pointer
* updates are desired.
*/
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (buffer_it) {
if (debug_pointer) {
@ -842,7 +855,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
"%.4f\n", dnow() - x11vnc_start);
}
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
}
@ -899,6 +912,33 @@ void initialize_pipeinput(void) {
} else {
p = pipeinput_str;
}
if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
if (!strcmp(p, "VID")) {
pipeinput_int = PIPEINPUT_VID;
return;
}
if (strstr(p, "CONS") == p) {
int tty = 0, n;
char dev[32];
if (sscanf(p, "CONS%d", &n) == 1) {
tty = n;
}
sprintf(dev, "/dev/tty%d", tty);
pipeinput_cons_fd = open(dev, O_WRONLY);
if (pipeinput_cons_fd >= 0) {
rfbLog("pipeinput: using linux console: %s\n", dev);
if (pipeinput_cons_dev) {
free(pipeinput_cons_dev);
}
pipeinput_cons_dev = strdup(dev);
pipeinput_int = PIPEINPUT_CONS;
} else {
rfbLog("pipeinput: could not open: %s\n", dev);
rfbLogPerror("open");
}
return;
}
set_child_info();
if (no_external_cmds) {

@ -209,9 +209,7 @@ void initialize_speeds(void) {
int n = 0;
double dt, timer;
dtime0(&timer);
if (0 && raw_fb && ! dpy) { /* raw_fb hack */
n = 0;
} else if (fullscreen) {
if (fullscreen) {
copy_image(fullscreen, 0, 0, 0, 0);
n = fullscreen->bytes_per_line * fullscreen->height;
} else if (scanline) {

@ -74,7 +74,9 @@ int send_remote_cmd(char *cmd, int query, int wait) {
fprintf(stderr, ">>> sending remote command: \"%s\" via"
" X11VNC_REMOTE X property.\n", cmd);
set_x11vnc_remote_prop(cmd);
XFlush(dpy);
if (dpy) {
XFlush_wr(dpy);
}
}
if (query || wait) {
@ -724,9 +726,16 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (!strcmp(p, "stop") || !strcmp(p, "quit") ||
!strcmp(p, "exit") || !strcmp(p, "shutdown")) {
NOTAPP
close_all_clients();
if (client_connect_file) {
FILE *in = fopen(client_connect_file, "w");
if (in) {
fprintf(in, "cmd=noop\n");
fclose(in);
}
}
rfbLog("remote_cmd: setting shut_down flag\n");
shut_down = 1;
close_all_clients();
} else if (!strcmp(p, "ping")) {
query = 1;
@ -1063,6 +1072,34 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: set cmap8to24_str to: %s\n", cmap8to24_str);
do_new_fb(0);
} else if (!strcmp(p, "24to32")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, xform24to32);
goto qry;
}
rfbLog("remote_cmd: turning on -24to32 mode.\n");
xform24to32 = 1;
do_new_fb(1);
} else if (!strcmp(p, "no24to32")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !xform24to32);
goto qry;
}
rfbLog("remote_cmd: turning off -24to32 mode.\n");
if (set_visual_str_to_something) {
if (visual_str) {
rfbLog("unsetting: %d %d/%d\n", visual_str,
(int) visual_id, visual_depth);
free(visual_str);
}
visual_str = NULL;
visual_id = (VisualID) 0;
visual_depth = 0;
}
xform24to32 = 0;
do_new_fb(1);
} else if (strstr(p, "visual") == p) {
COLON_CHECK("visual:")
if (query) {
@ -1579,7 +1616,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: turning on flipbyteorder mode.\n");
flip_byte_order = 1;
if (orig != flip_byte_order) {
if (! using_shm) {
if (! using_shm || xform24to32) {
do_new_fb(1);
} else {
rfbLog(" using shm, not resetting fb\n");
@ -1594,7 +1631,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: turning off flipbyteorder mode.\n");
flip_byte_order = 0;
if (orig != flip_byte_order) {
if (! using_shm) {
if (! using_shm || xform24to32) {
do_new_fb(1);
} else {
rfbLog(" using shm, not resetting fb\n");
@ -3282,6 +3319,19 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (*raw_fb_str == '\0') {
free(raw_fb_str);
raw_fb_str = NULL;
if (raw_fb_mmap) {
munmap(raw_fb_addr, raw_fb_mmap);
}
if (raw_fb_fd >= 0) {
close(raw_fb_fd);
}
raw_fb_fd = -1;
raw_fb = NULL;
raw_fb_addr = NULL;
raw_fb_offset = 0;
raw_fb_shm = 0;
raw_fb_mmap = 0;
raw_fb_seek = 0;
rfbLog("restoring per-rawfb settings...\n");
set_raw_fb_params(1);
}
@ -3976,7 +4026,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else {
if (dpy) { /* raw_fb hack */
set_x11vnc_remote_prop(buf);
XFlush(dpy);
XFlush_wr(dpy);
}
}
#endif

@ -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;

@ -19,7 +19,12 @@
#include "unixpw.h"
#include "sslcmds.h"
#include "sslhelper.h"
#include "v4l.h"
#include "linuxfb.h"
void set_greyscale_colormap(void);
void set_hi240_colormap(void);
void unset_colormap(void);
void set_colormap(int reset);
void set_nofb_params(int restore);
void set_raw_fb_params(int restore);
@ -41,12 +46,14 @@ static void nofb_hook(rfbClientPtr cl);
static void remove_fake_fb(void);
static void install_fake_fb(int w, int h, int bpp);
static void initialize_snap_fb(void);
static XImage *initialize_raw_fb(void);
XImage *initialize_raw_fb(int);
static void initialize_clipshift(void);
static int wait_until_mapped(Window win);
static void announce(int lport, int ssl, char *iface);
static void setup_scaling(int *width_in, int *height_in);
int rawfb_reset = -1;
int rawfb_dev_video = 0;
/*
* X11 and rfb display/screen related routines
@ -57,22 +64,96 @@ static void setup_scaling(int *width_in, int *height_in);
* the clients and dynamically if -flashcmap is specified.
*/
#define NCOLOR 256
void set_greyscale_colormap(void) {
int i;
if (! screen) {
return;
}
if (screen->colourMap.data.shorts) {
free(screen->colourMap.data.shorts);
screen->colourMap.data.shorts = NULL;
}
if (0) fprintf(stderr, "set_greyscale_colormap: %s\n", raw_fb_pixfmt);
screen->colourMap.count = NCOLOR;
screen->serverFormat.trueColour = FALSE;
screen->colourMap.is16 = TRUE;
screen->colourMap.data.shorts = (unsigned short *)
malloc(3*sizeof(unsigned short) * NCOLOR);
for(i = 0; i < NCOLOR; i++) {
unsigned short lvl = i * 256;
screen->colourMap.data.shorts[i*3+0] = lvl;
screen->colourMap.data.shorts[i*3+1] = lvl;
screen->colourMap.data.shorts[i*3+2] = lvl;
}
rfbSetClientColourMaps(screen, 0, NCOLOR);
}
/* this is specific to bttv rf tuner card */
void set_hi240_colormap(void) {
int i;
if (! screen) {
return;
}
if (0) fprintf(stderr, "set_hi240_colormap: %s\n", raw_fb_pixfmt);
if (screen->colourMap.data.shorts) {
free(screen->colourMap.data.shorts);
screen->colourMap.data.shorts = NULL;
}
screen->colourMap.count = 256;
screen->serverFormat.trueColour = FALSE;
screen->colourMap.is16 = TRUE;
screen->colourMap.data.shorts = (unsigned short *)
calloc(3*sizeof(unsigned short) * 256, 1);
for(i = 0; i < 225; i++) {
int r, g, b;
r = ( (i/5) % 5 ) * 255.0 / 4 + 0.5;
g = ( (i/25) ) * 255.0 / 8 + 0.5;
b = ( i % 5 ) * 255.0 / 4 + 0.5;
screen->colourMap.data.shorts[(i+16)*3+0] = (unsigned short) (r * 256);
screen->colourMap.data.shorts[(i+16)*3+1] = (unsigned short) (g * 256);
screen->colourMap.data.shorts[(i+16)*3+2] = (unsigned short) (b * 256);
}
rfbSetClientColourMaps(screen, 0, 256);
}
void unset_colormap(void) {
if (! screen) {
return;
}
if (screen->colourMap.data.shorts) {
free(screen->colourMap.data.shorts);
screen->colourMap.data.shorts = NULL;
}
screen->serverFormat.trueColour = TRUE;
if (0) fprintf(stderr, "unset_colormap: %s\n", raw_fb_pixfmt);
}
void set_colormap(int reset) {
static int first = 1;
static int init = 1;
static XColor color[NCOLOR], prev[NCOLOR];
Colormap cmap;
Visual *vis;
int i, ncells, diffs = 0;
if (reset) {
first = 1;
init = 1;
if (screen->colourMap.data.shorts) {
free(screen->colourMap.data.shorts);
screen->colourMap.data.shorts = NULL;
}
}
if (0) fprintf(stderr, "unset_colormap: %d\n", reset);
if (first) {
if (init) {
screen->colourMap.count = NCOLOR;
screen->serverFormat.trueColour = FALSE;
screen->colourMap.is16 = TRUE;
@ -86,6 +167,8 @@ void set_colormap(int reset) {
prev[i].blue = color[i].blue;
}
RAWFB_RET_VOID
X_LOCK;
cmap = DefaultColormap(dpy, scr);
@ -103,7 +186,7 @@ void set_colormap(int reset) {
}
if (ncells != NCOLOR) {
if (first && ! quiet) {
if (init && ! quiet) {
rfbLog("set_colormap: number of cells is %d "
"instead of %d.\n", ncells, NCOLOR);
}
@ -112,7 +195,7 @@ void set_colormap(int reset) {
}
}
if (flash_cmap && ! first) {
if (flash_cmap && ! init) {
XWindowAttributes attr;
Window c;
int tries = 0;
@ -178,7 +261,7 @@ void set_colormap(int reset) {
}
}
if (diffs && ! first) {
if (diffs && ! init) {
if (! all_clients_initialized()) {
rfbLog("set_colormap: warning: sending cmap "
"with uninitialized clients.\n");
@ -190,7 +273,7 @@ void set_colormap(int reset) {
}
}
first = 0;
init = 0;
}
static void debug_colormap(XImage *fb) {
@ -248,10 +331,13 @@ static void debug_colormap(XImage *fb) {
* visual_id and possibly visual_depth are set.
*/
static void set_visual(char *str) {
int vis, vdepth, defdepth = DefaultDepth(dpy, scr);
int vis, vdepth, defdepth;
XVisualInfo vinfo;
char *p, *vstring = strdup(str);
RAWFB_RET_VOID
defdepth = DefaultDepth(dpy, scr);
visual_id = (VisualID) 0;
visual_depth = 0;
@ -410,7 +496,7 @@ static char *raw_fb_orig_dpy = NULL;
void set_raw_fb_params(int restore) {
static int first = 1;
static int vo0, us0, sm0, ws0, wp0, wc0, wb0, na0, tn0;
static int xr0, sb0;
static int xr0, sb0, re0;
static char *mc0;
/*
@ -432,6 +518,7 @@ void set_raw_fb_params(int restore) {
sm0 = using_shm;
tn0 = take_naps;
xr0 = xrandr;
re0 = noxrecord;
mc0 = multiple_cursors_mode;
first = 0;
@ -450,6 +537,7 @@ void set_raw_fb_params(int restore) {
using_shm = sm0;
take_naps = tn0;
xrandr = xr0;
noxrecord = re0;
multiple_cursors_mode = mc0;
if (! dpy && raw_fb_orig_dpy) {
@ -484,56 +572,60 @@ void set_raw_fb_params(int restore) {
} else {
/* Normal case: */
if (! view_only) {
if (! quiet) rfbLog("rawfb: setting view_only\n");
if (! quiet) rfbLog(" rawfb: setting view_only\n");
view_only = 1;
}
if (watch_selection) {
if (! quiet) rfbLog("rawfb: turning off "
if (! quiet) rfbLog(" rawfb: turning off "
"watch_selection\n");
watch_selection = 0;
}
if (watch_primary) {
if (! quiet) rfbLog("rawfb: turning off "
if (! quiet) rfbLog(" rawfb: turning off "
"watch_primary\n");
watch_primary = 0;
}
if (watch_clipboard) {
if (! quiet) rfbLog("rawfb: turning off "
if (! quiet) rfbLog(" rawfb: turning off "
"watch_clipboard\n");
watch_clipboard = 0;
}
if (watch_bell) {
if (! quiet) rfbLog("rawfb: turning off watch_bell\n");
if (! quiet) rfbLog(" rawfb: turning off watch_bell\n");
watch_bell = 0;
}
if (no_autorepeat) {
if (! quiet) rfbLog("rawfb: turning off "
if (! quiet) rfbLog(" rawfb: turning off "
"no_autorepeat\n");
no_autorepeat = 0;
}
if (use_solid_bg) {
if (! quiet) rfbLog("rawfb: turning off "
if (! quiet) rfbLog(" rawfb: turning off "
"use_solid_bg\n");
use_solid_bg = 0;
}
multiple_cursors_mode = strdup("arrow");
}
if (use_snapfb) {
if (! quiet) rfbLog("rawfb: turning off use_snapfb\n");
if (0 && use_snapfb) {
if (! quiet) rfbLog(" rawfb: turning off use_snapfb\n");
use_snapfb = 0;
}
if (using_shm) {
if (! quiet) rfbLog("rawfb: turning off using_shm\n");
if (! quiet) rfbLog(" rawfb: turning off using_shm\n");
using_shm = 0;
}
if (take_naps) {
if (! quiet) rfbLog("rawfb: turning off take_naps\n");
if (! quiet) rfbLog(" rawfb: turning off take_naps\n");
take_naps = 0;
}
if (xrandr) {
if (! quiet) rfbLog("rawfb: turning off xrandr\n");
if (! quiet) rfbLog(" rawfb: turning off xrandr\n");
xrandr = 0;
}
if (! noxrecord) {
if (! quiet) rfbLog(" rawfb: turning off xrecord\n");
noxrecord = 1;
}
}
/*
@ -545,8 +637,10 @@ void set_raw_fb_params(int restore) {
*/
static void nofb_hook(rfbClientPtr cl) {
XImage *fb;
rfbLog("framebuffer requested in -nofb mode by client %s\n", cl->host);
/* ignore xrandr */
RAWFB_RET_VOID
fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
main_fb = fb->data;
rfb_fb = main_fb;
@ -669,6 +763,7 @@ void install_padded_fb(char *geom) {
}
static void initialize_snap_fb(void) {
RAWFB_RET_VOID
if (snap_fb) {
free(snap_fb);
}
@ -677,12 +772,63 @@ static void initialize_snap_fb(void) {
snap_fb = snap->data;
}
static XImage *initialize_raw_fb(void) {
#define RAWFB_MMAP 1
#define RAWFB_FILE 2
#define RAWFB_SHM 3
XImage *initialize_raw_fb(int reset) {
char *str, *q;
int w, h, b, shmid = 0;
unsigned long rm = 0, gm = 0, bm = 0;
unsigned long rm = 0, gm = 0, bm = 0, tm;
static XImage ximage_struct; /* n.b.: not (XImage *) */
int closedpy = 1, i, m;
static XImage ximage_struct_snap;
int closedpy = 1, i, m, db = 0;
static char *last_file = NULL;
static int last_mode = 0;
if (reset && last_mode) {
int fd;
if (last_mode != RAWFB_MMAP && last_mode != RAWFB_FILE) {
return NULL;
}
if (last_mode == RAWFB_MMAP) {
munmap(raw_fb_addr, raw_fb_mmap);
}
if (raw_fb_fd >= 0) {
close(raw_fb_fd);
}
raw_fb_fd = -1;
if (db) fprintf(stderr, "initialize_raw_fb reset\n");
fd = -1;
if (rawfb_dev_video) {
fd = open(last_file, O_RDWR);
}
if (fd < 0) {
fd = open(last_file, O_RDONLY);
}
if (fd < 0) {
rfbLogEnable(1);
rfbLog("failed to rawfb file: %s\n", last_file);
rfbLogPerror("open");
clean_up_exit(1);
}
raw_fb_fd = fd;
if (last_mode == RAWFB_MMAP) {
raw_fb_addr = mmap(0, raw_fb_mmap, PROT_READ,
MAP_SHARED, fd, 0);
if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) {
rfbLogEnable(1);
rfbLog("failed to mmap file: %s\n", last_file);
rfbLog(" raw_fb_addr: %p\n", raw_fb_addr);
rfbLogPerror("mmap");
clean_up_exit(1);
}
}
return NULL;
}
if (raw_fb_addr || raw_fb_seek) {
if (raw_fb_shm) {
@ -693,13 +839,17 @@ static XImage *initialize_raw_fb(void) {
if (raw_fb_fd >= 0) {
close(raw_fb_fd);
}
raw_fb_fd = -1;
#endif
} else if (raw_fb_seek) {
if (raw_fb_fd >= 0) {
close(raw_fb_fd);
}
raw_fb_fd = -1;
}
raw_fb_addr = NULL;
raw_fb_mmap = 0;
raw_fb_seek = 0;
}
if (! raw_fb_str) {
return NULL;
@ -750,22 +900,48 @@ static XImage *initialize_raw_fb(void) {
} else {
str = strdup(raw_fb_str);
}
/*
* uppercase means do not close the display (e.g. for remote control)
*/
if (strstr(str, "SHM:") == str) {
closedpy = 0;
str[0] = 's'; str[1] = 'h'; str[2] = 'm';
} else if (strstr(str, "MAP:") == str) {
closedpy = 0;
str[0] = 'm'; str[1] = 'a'; str[2] = 'p';
} else if (strstr(str, "MMAP:") == str) {
closedpy = 0;
str[0] = 'm'; str[1] = 'm'; str[2] = 'a'; str[3] = 'p';
} else if (strstr(str, "FILE:") == str) {
str[0] = 'f'; str[1] = 'i'; str[2] = 'l'; str[3] = 'e';
if (str[0] == '+') {
char *t = strdup(str+1);
free(str);
str = t;
closedpy = 0;
if (! window) {
window = rootwin;
}
}
raw_fb_shm = 0;
raw_fb_mmap = 0;
raw_fb_seek = 0;
raw_fb_fd = -1;
raw_fb_addr = NULL;
raw_fb_offset = 0;
last_mode = 0;
if (last_file) {
free(last_file);
last_file = NULL;
}
if (strstr(str, "video") == str || strstr(str, "/dev/video") == str) {
char *str2 = v4l_guess(str, &raw_fb_fd);
if (str2 == NULL) {
rfbLog("v4l_guess failed for: %s\n", str);
clean_up_exit(1);
}
str = str2;
rfbLog("v4l_guess returned: %s\n", str);
rawfb_dev_video = 1;
} else if (strstr(str, "dev/video")) {
rawfb_dev_video = 1;
} else if (strstr(str, "cons") == str || strstr(str, "/dev/fb") == str) {
char *str2 = console_guess(str, &raw_fb_fd);
if (str2 == NULL) {
rfbLog("console_guess failed for: %s\n", str);
clean_up_exit(1);
}
str = str2;
rfbLog("console_guess returned: %s\n", str);
}
if (closedpy && !view_only && got_noviewonly) {
@ -799,7 +975,6 @@ static XImage *initialize_raw_fb(void) {
* -rawfb file:/path/to/file@640x480x32:ff/ff00/ff0000
*/
raw_fb_offset = 0;
/* +O offset */
if ((q = strrchr(str, '+')) != NULL) {
@ -836,6 +1011,34 @@ static XImage *initialize_raw_fb(void) {
}
*q = '\0';
dpy_x = wdpy_x = w;
dpy_y = wdpy_y = h;
off_x = 0;
off_y = 0;
if (rawfb_dev_video) {
if (b == 24) {
rfbLog("enabling -24to32 for 24bpp video\n");
xform24to32 = 1;
} else {
if (xform24to32) {
rfbLog("disabling -24to32 for 24bpp video\n");
}
xform24to32 = 0;
}
}
if (xform24to32) {
if (b != 24) {
rfbLog("warning: -24to32 mode and bpp=%d\n", b);
}
b = 32;
}
if (strstr(str, "snap:") == str) {
use_snapfb = 1;
str[0] = 'f'; str[1] = 'i'; str[2] = 'l'; str[3] = 'e';
}
if (strstr(str, "shm:") != str && strstr(str, "mmap:") != str &&
strstr(str, "map:") != str && strstr(str, "file:") != str) {
/* hmmm, not following directions, see if map: applies */
@ -854,17 +1057,6 @@ static XImage *initialize_raw_fb(void) {
}
}
dpy_x = wdpy_x = w;
dpy_y = wdpy_y = h;
off_x = 0;
off_y = 0;
raw_fb_shm = 0;
raw_fb_mmap = 0;
raw_fb_seek = 0;
raw_fb_fd = -1;
raw_fb_addr = NULL;
if (sscanf(str, "shm:%d", &shmid) == 1) {
/* shm:N */
#if LIBVNCSERVER_HAVE_XSHM
@ -878,6 +1070,7 @@ static XImage *initialize_raw_fb(void) {
raw_fb_shm = 1;
rfbLog("rawfb: shm: %d W: %d H: %d B: %d addr: %p\n",
shmid, w, h, b, raw_fb_addr);
last_mode = RAWFB_SHM;
#else
rfbLogEnable(1);
rfbLog("x11vnc was compiled without shm support.\n");
@ -896,7 +1089,15 @@ static XImage *initialize_raw_fb(void) {
q = strchr(str, ':');
q++;
fd = open(q, O_RDONLY);
last_file = strdup(q);
fd = raw_fb_fd;
if (fd < 0 && rawfb_dev_video) {
fd = open(q, O_RDWR);
}
if (fd < 0) {
fd = open(q, O_RDONLY);
}
if (fd < 0) {
rfbLogEnable(1);
rfbLog("failed to open file: %s, %s\n", q, str);
@ -905,7 +1106,11 @@ static XImage *initialize_raw_fb(void) {
}
raw_fb_fd = fd;
size = w*h*b/8 + raw_fb_offset;
if (xform24to32) {
size = w*h*24/8 + raw_fb_offset;
} else {
size = w*h*b/8 + raw_fb_offset;
}
if (fstat(fd, &sbuf) == 0) {
if (S_ISREG(sbuf.st_mode)) {
if (0) size = sbuf.st_size;
@ -931,13 +1136,16 @@ static XImage *initialize_raw_fb(void) {
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");
raw_fb_seek = size;
last_mode = RAWFB_FILE;
#endif
} else {
raw_fb_seek = size;
last_mode = RAWFB_FILE;
rfbLog("rawfb: seek file: %s\n", q);
rfbLog(" W: %d H: %d B: %d sz: %d\n", w, h, b, size);
@ -962,6 +1170,24 @@ static XImage *initialize_raw_fb(void) {
raw_fb_image->bits_per_pixel = b;
raw_fb_image->bytes_per_line = dpy_x*b/8;
if (use_snapfb && (raw_fb_seek || raw_fb_mmap)) {
int b_use = b;
if (snap_fb) {
free(snap_fb);
}
if (b_use == 32 && xform24to32) {
b_use = 24;
}
snap_fb = (char *) malloc(dpy_x * dpy_y * b_use/8);
snap = &ximage_struct_snap;
snap->data = snap_fb;
snap->format = ZPixmap;
snap->width = dpy_x;
snap->height = dpy_y;
snap->bits_per_pixel = b_use;
snap->bytes_per_line = dpy_x*b_use/8;
}
if (rm == 0 && gm == 0 && bm == 0) {
/* guess masks... */
if (b == 24 || b == 32) {
@ -978,6 +1204,26 @@ static XImage *initialize_raw_fb(void) {
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;
@ -1003,15 +1249,30 @@ static XImage *initialize_raw_fb(void) {
depth = raw_fb_image->depth;
if (raw_fb_image->depth == 15) {
/* unresolved bug with RGB555... */
depth++;
}
if (clipshift) {
memset(raw_fb, 0xff, dpy_x * dpy_y * b/8);
} else if (raw_fb_addr) {
} else if (raw_fb_addr && ! xform24to32) {
memcpy(raw_fb, raw_fb_addr + raw_fb_offset, dpy_x*dpy_y*b/8);
} else {
memset(raw_fb, 0xff, dpy_x * dpy_y * b/8);
}
rfbLog("rawfb: raw_fb %p\n", raw_fb);
rfbLog("\n");
rfbLog("rawfb: raw_fb %p\n", raw_fb);
rfbLog(" format %d\n", raw_fb_image->format);
rfbLog(" width %d\n", raw_fb_image->width);
rfbLog(" height %d\n", raw_fb_image->height);
rfbLog(" bpp %d\n", raw_fb_image->bits_per_pixel);
rfbLog(" depth %d\n", raw_fb_image->depth);
rfbLog(" bpl %d\n", raw_fb_image->bytes_per_line);
if (use_snapfb && snap_fb) {
rfbLog(" snap_fb %p\n", snap_fb);
}
free(str);
@ -1073,7 +1334,7 @@ static int wait_until_mapped(Window win) {
usleep(ms * 1000);
continue;
}
if (! XGetWindowAttributes(dpy, win, &attr)) {
if (dpy && ! XGetWindowAttributes(dpy, win, &attr)) {
return 0;
}
if (attr.map_state == IsViewable) {
@ -1095,7 +1356,7 @@ XImage *initialize_xdisplay_fb(void) {
int subwin_bs;
if (raw_fb_str) {
return initialize_raw_fb();
return initialize_raw_fb(0);
}
X_LOCK;
@ -1137,12 +1398,24 @@ XImage *initialize_xdisplay_fb(void) {
vis_str = strdup(str);
}
if (xform24to32) {
if (DefaultDepth(dpy, scr) == 24) {
vis_str = strdup("TrueColor:32");
rfbLog("initialize_xdisplay_fb: vis_str set to: %s ",
vis_str);
visual_id = (VisualID) 0;
visual_depth = 0;
set_visual_str_to_something = 1;
}
}
if (vis_str != NULL) {
set_visual(vis_str);
if (vis_str != visual_str) {
free(vis_str);
}
}
if (0) fprintf(stderr, "vis_str %s\n", vis_str ? vis_str : "notset");
/* set up parameters for subwin or non-subwin cases: */
@ -1184,6 +1457,8 @@ XImage *initialize_xdisplay_fb(void) {
/* initialize depth to reasonable value, visual_id may override */
depth = DefaultDepth(dpy, scr);
if (0) fprintf(stderr, "DefaultDepth: %d visial_id: %d\n", depth, (int) visual_id);
if (visual_id) {
int n;
XVisualInfo vinfo_tmpl, *vinfo;
@ -1272,7 +1547,7 @@ XImage *initialize_xdisplay_fb(void) {
}
XMapRaised(dpy, window);
XRaiseWindow(dpy, window);
XFlush(dpy);
XFlush_wr(dpy);
}
try++;
@ -1533,6 +1808,9 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
fb_Bpl = (int) fb->bytes_per_line;
fb_depth = (int) fb->depth;
rfbLog("initialize_screen: fb_depth/fb_bpp/fb_Bpl %d/%d/%d\n", fb_depth,
fb_depth, fb_Bpl);
main_bytes_per_line = fb->bytes_per_line;
if (cmap8to24) {
@ -1675,7 +1953,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
have_masks = 2;
/* need to fetch TrueColor visual */
X_LOCK;
if (XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinfo)) {
if (dpy && XMatchVisualInfo(dpy, scr, 24, TrueColor, &vinfo)) {
main_red_mask = vinfo.red_mask;
main_green_mask = vinfo.green_mask;
main_blue_mask = vinfo.blue_mask;
@ -1691,6 +1969,19 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
X_UNLOCK;
}
if (raw_fb_str && raw_fb_pixfmt) {
char *fmt = strdup(raw_fb_pixfmt);
uppercase(fmt);
if (strstr(fmt, "GREY")) {
set_greyscale_colormap();
} else if (strstr(fmt, "HI240")) {
set_hi240_colormap();
} else {
unset_colormap();
}
free(fmt);
}
if (! have_masks && screen->serverFormat.bitsPerPixel == 8
&& dpy && CellsOfScreen(ScreenOfDisplay(dpy, scr))) {
/* indexed color */
@ -1966,8 +2257,6 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->deferUpdateTime = defer_update;
}
rfbSetServerVersionIdentity(screen, "x11vnc: %s", lastmod);
rfbInitServer(screen);
if (use_openssl) {

@ -3,6 +3,9 @@
/* -- screen.h -- */
extern void set_greyscale_colormap(void);
extern void set_hi240_colormap(void);
extern void unset_colormap(void);
extern void set_colormap(int reset);
extern void set_nofb_params(int restore);
extern void set_raw_fb_params(int restore);
@ -11,10 +14,14 @@ extern void free_old_fb(char *old_main, char *old_rfb, char *old_8to24);
extern void check_padded_fb(void);
extern void install_padded_fb(char *geom);
extern XImage *initialize_xdisplay_fb(void);
extern XImage *initialize_raw_fb(int);
extern void parse_scale_string(char *str, double *factor, int *scaling, int *blend,
int *nomult4, int *pad, int *interpolate, int *numer, int *denom);
extern int scale_round(int len, double fac);
extern void initialize_screen(int *argc, char **argv, XImage *fb);
extern void set_vnc_desktop_name(void);
extern int rawfb_reset;
extern int rawfb_dev_video;
#endif /* _X11VNC_SCREEN_H */

@ -4,6 +4,7 @@
#include "cleanup.h"
#include "connections.h"
#include "unixpw.h"
#include "xwrappers.h"
/*
* Selection/Cutbuffer/Clipboard handlers.
@ -57,7 +58,11 @@ void selection_request(XEvent *ev, char *type) {
unsigned int length;
unsigned char *data;
#ifndef XA_LENGTH
unsigned long XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
unsigned long XA_LENGTH;
#endif
RAWFB_RET_VOID
#ifndef XA_LENGTH
XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
#endif
req_event = &(ev->xselectionrequest);
@ -128,7 +133,7 @@ void selection_request(XEvent *ev, char *type) {
XSetErrorHandler(old_handler);
trapped_xerror = 0;
XFlush(dpy);
XFlush_wr(dpy);
}
int check_sel_direction(char *dir, char *label, char *sel, int len) {
@ -179,6 +184,7 @@ void cutbuffer_send(void) {
cutbuffer_str[0] = '\0';
slen = 0;
RAWFB_RET_VOID
/* read the property value into cutbuffer_str: */
do {
@ -248,6 +254,7 @@ void selection_send(XEvent *ev) {
unsigned char* data = NULL;
char *selection_str;
RAWFB_RET_VOID
/*
* remember info about our last value of PRIMARY (or CUT_BUFFER0)
* so we can check for any changes below.

@ -2,6 +2,7 @@
#include "x11vnc.h"
#include "win_utils.h"
#include "xwrappers.h"
char *guess_desktop(void);
void solid_bg(int restore);
@ -46,6 +47,8 @@ static void usr_bin_path(int restore) {
static int dt_cmd(char *cmd) {
int rc;
RAWFB_RET(0)
if (!cmd || *cmd == '\0') {
return 0;
}
@ -117,6 +120,8 @@ static void solid_root(char *color) {
XColor cdef;
Colormap cmap;
RAWFB_RET_VOID
if (subwin || window != rootwin) {
rfbLog("cannot set subwin to solid color, must be rootwin\n");
return;
@ -159,7 +164,7 @@ static void solid_root(char *color) {
XSetWindowBackgroundPixmap(dpy, window, pixmap);
XFreePixmap(dpy, pixmap);
XClearWindow(dpy, window);
XFlush(dpy);
XFlush_wr(dpy);
/* generate exposures */
XMapWindow(dpy, expose);
@ -228,6 +233,8 @@ static void solid_cde(char *color) {
Colormap cmap;
int n;
RAWFB_RET_VOID
if (subwin || window != rootwin) {
rfbLog("cannot set subwin to solid color, must be rootwin\n");
return;
@ -282,7 +289,7 @@ static void solid_cde(char *color) {
XSetWindowBackgroundPixmap(dpy, twin, pixmap);
XFreePixmap(dpy, pixmap);
XClearWindow(dpy, twin);
XFlush(dpy);
XFlush_wr(dpy);
}
/* generate exposures */
@ -481,6 +488,8 @@ static void solid_gnome(char *color) {
static char *orig_color = NULL;
static char *orig_option = NULL;
char *cmd;
RAWFB_RET_VOID
if (! color) {
if (! orig_color) {
@ -555,6 +564,8 @@ static void solid_kde(char *color) {
char *cmd, *user = NULL;
int len;
RAWFB_RET_VOID
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("invalid user: %s\n", user);
@ -595,6 +606,8 @@ static void solid_kde(char *color) {
char *guess_desktop(void) {
Atom prop;
RAWFB_RET("root")
if (wmdt_str && *wmdt_str != '\0') {
char *s = wmdt_str;
lowercase(s);
@ -647,6 +660,8 @@ void solid_bg(int restore) {
static char *prev_str;
char *dtname, *color;
RAWFB_RET_VOID
if (started_as_root == 1 && users_list) {
/* we are still root, don't try. */
return;

@ -1028,7 +1028,7 @@ if (db) fprintf(stderr, "tv_sec: %d - %s\n", (int) tv.tv_sec, last_get);
return 1;
}
#define BSIZE 16384
#define ABSIZE 16384
static int watch_for_http_traffic(char *buf_a, int *n_a) {
int is_http, err, n, n2;
char *buf;
@ -1038,13 +1038,13 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
* if it is http or not. if we read them OK, we must read the
* rest of the available data otherwise we may deadlock.
* what has be read is returned in buf_a and n_a.
* *buf_a is BSIZE+1 long and zeroed.
* *buf_a is ABSIZE+1 long and zeroed.
*/
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
buf = (char *) calloc(sizeof(BSIZE+1), 1);
buf = (char *) calloc(sizeof(ABSIZE+1), 1);
*n_a = 0;
n = SSL_read(ssl, buf, 2);
@ -1075,7 +1075,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
* better read all we can and fwd it along to avoid blocking
* in ssl_xfer().
*/
n2 = SSL_read(ssl, buf + n, BSIZE - n);
n2 = SSL_read(ssl, buf + n, ABSIZE - n);
if (n2 >= 0) {
n += n2;
}
@ -1376,8 +1376,8 @@ void accept_openssl(int mode) {
char *iface = NULL;
char *buf, *tbuf;
buf = (char *) calloc((BSIZE+1), 1);
tbuf = (char *) calloc((2*BSIZE+1), 1);
buf = (char *) calloc((ABSIZE+1), 1);
tbuf = (char *) calloc((2*ABSIZE+1), 1);
if (mode == OPENSSL_HTTPS) {
/*
@ -1857,7 +1857,7 @@ if (db > 1) write(2, buf, n);
static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err;
char cbuf[BSIZE], sbuf[BSIZE];
char cbuf[ABSIZE], sbuf[ABSIZE];
int cptr, sptr, c_rd, c_wr, s_rd, s_wr;
fd_set rd, wr;
struct timeval tv;
@ -1905,7 +1905,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* cbuf[] is data from csock that we have read but not passed on to ssl
* sbuf[] is data from ssl that we have read but not passed on to csock
*/
for (i=0; i<BSIZE; i++) {
for (i=0; i<ABSIZE; i++) {
cbuf[i] = '\0';
sbuf[i] = '\0';
}
@ -1927,7 +1927,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
s_rd = 1; /* ssl data (remote client) socket open for reading */
s_wr = 1; /* ssl data (remote client) socket open for writing */
cptr = 0; /* offsets into BSIZE buffers */
cptr = 0; /* offsets into ABSIZE buffers */
sptr = 0;
while (1) {
@ -1966,7 +1966,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
FD_ZERO(&rd);
if (c_rd && cptr < BSIZE) {
if (c_rd && cptr < ABSIZE) {
/* we could read more from C since cbuf is not full */
FD_SET(csock, &rd);
}
@ -1976,7 +1976,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* OR ssl is waiting for more BIO to be able to
* read and we have some C data still buffered.
*/
if (sptr < BSIZE || (cptr > 0 && SSL_want_read(ssl))) {
if (sptr < ABSIZE || (cptr > 0 && SSL_want_read(ssl))) {
FD_SET(s_in, &rd);
}
}
@ -1993,7 +1993,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* OR ssl is waiting for more BIO to be able
* write and we haven't filled up sbuf yet.
*/
if (cptr > 0 || (sptr < BSIZE && SSL_want_write(ssl))) {
if (cptr > 0 || (sptr < ABSIZE && SSL_want_write(ssl))) {
FD_SET(s_out, &wr);
}
}
@ -2050,7 +2050,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
} else {
/* shift over the data in sbuf by n */
memmove(sbuf, sbuf + n, sptr - n);
if (sptr == BSIZE) {
if (sptr == ABSIZE) {
check_pending = 1;
}
sptr -= n;
@ -2111,7 +2111,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
/* try to read some data from C into our cbuf */
n = read(csock, cbuf + cptr, BSIZE - cptr);
n = read(csock, cbuf + cptr, ABSIZE - cptr);
if (n < 0) {
if (errno != EINTR) {
@ -2135,13 +2135,13 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
}
if (s_rd) {
if ((sptr < BSIZE && FD_ISSET(s_in, &rd)) ||
if ((sptr < ABSIZE && FD_ISSET(s_in, &rd)) ||
(SSL_want_write(ssl) && FD_ISSET(s_out, &wr)) ||
(check_pending && SSL_pending(ssl))) {
/* try to read some data from S into our sbuf */
n = SSL_read(ssl, sbuf + sptr, BSIZE - sptr);
n = SSL_read(ssl, sbuf + sptr, ABSIZE - sptr);
err = SSL_get_error(ssl, n);
if (err == SSL_ERROR_NONE) {

@ -178,6 +178,7 @@ Screen
visual:
rawfb:
pipeinput:
24to32
=GAL LOFF
Keyboard

@ -189,6 +189,7 @@ char gui_code[] = "";
" visual:\n"
" rawfb:\n"
" pipeinput:\n"
" 24to32\n"
" =GAL LOFF\n"
"\n"
"Keyboard\n"

@ -67,6 +67,8 @@ static int db = 0;
static int white(void) {
static unsigned long black_pix = 0, white_pix = 1, set = 0;
RAWFB_RET(0xffffff)
if (depth <= 8 && ! set) {
X_LOCK;
black_pix = BlackPixel(dpy, scr);

@ -445,10 +445,13 @@ void lurk_loop(char *str) {
}
static int guess_user_and_switch(char *str, int fb_mode) {
char *dstr, *d = DisplayString(dpy);
char *dstr, *d;
char *p, *tstr = NULL, *allowed = NULL, *logins, **users = NULL;
int dpy1, ret = 0;
RAWFB_RET(0)
d = DisplayString(dpy);
/* pick out ":N" */
dstr = strchr(d, ':');
if (! dstr) {
@ -639,7 +642,7 @@ static int switch_user_env(uid_t uid, char *name, char *home, int fb_mode) {
* OK tricky here, we need to free the shm... otherwise
* we won't be able to delete it as the other user...
*/
if (fb_mode == 1 && using_shm) {
if (fb_mode == 1 && (using_shm && ! xform24to32)) {
reset_fb = 1;
clean_shm(0);
free_tiles();

@ -96,6 +96,8 @@ int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
int rootx, rooty, wx, wy;
unsigned int mask;
RAWFB_RET(0)
ret = XQueryPointer(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy,
&mask);
@ -2140,6 +2142,9 @@ static int check_xrecord_keys(void) {
double set_repeat_in;
static double set_repeat = 0.0;
RAWFB_RET(0)
set_repeat_in = set_repeat;
set_repeat = 0.0;
@ -2222,7 +2227,7 @@ if (db) fprintf(stderr, "check_xrecord_keys: BEGIN LOOP: scr_ev_cnt: "
X_LOCK;
flush1 = 1;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (set_repeat_in > 0.0) {
@ -2253,7 +2258,7 @@ if (0 || db) fprintf(stderr, "check_xrecord: more keys: %.3f 0x%x "
" %.4f %s %s\n", spin, last_rfb_keysym, last_rfb_keytime - x11vnc_start,
last_rfb_down ? "down":"up ", last_rfb_key_accepted ? "accept":"skip");
flush2 = 1;
XFlush(dpy);
XFlush_wr(dpy);
}
#if LIBVNCSERVER_HAVE_RECORD
SCR_LOCK;
@ -2383,6 +2388,8 @@ static int check_xrecord_mouse(void) {
int btn4 = (1<<3);
int btn5 = (1<<4);
RAWFB_RET(0)
get_out = 1;
if (button_mask) {
get_out = 0;
@ -2540,7 +2547,7 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON_UP_SCROLL: %.3f\n", spin);
if (! already_down || (!scr_cnt && spin>flush1_time)) {
flush1 = 1;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dtime0(&last_flush);
}
@ -2624,7 +2631,7 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d %
if (doflush) {
flush1 = 1;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dtime0(&last_flush);
}
@ -2679,8 +2686,8 @@ if (db) fprintf(stderr, " we decide to send ret=3\n");
if (flush2) {
X_LOCK;
XFlush(dpy);
XFlush(rdpy_ctrl);
XFlush_wr(dpy);
XFlush_wr(rdpy_ctrl);
X_UNLOCK;
flush2 = 1;
@ -2708,6 +2715,8 @@ int check_xrecord(void) {
int watch_keys = 0, watch_mouse = 0, consider_mouse;
static int mouse_wants_back_in = 0;
RAWFB_RET(0)
if (! use_xrecord) {
return 0;
}
@ -3291,6 +3300,8 @@ int check_wireframe(void) {
int try_it = 0;
DB_SET
RAWFB_RET(0)
if (unixpw_in_progress) return 0;
if (nofb) {
return 0;
@ -3439,7 +3450,7 @@ if (db) fprintf(stderr, "INTERIOR\n");
while (1) {
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
/* try do induce/waitfor some more user input */
@ -3504,7 +3515,7 @@ if (db) fprintf(stderr, " ++pointer event!! [%02d] dt: %.3f x: %d y: %d mas
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
/* periodically try to let the wm get moving: */
@ -3849,7 +3860,7 @@ static void check_user_input2(double dt) {
X_LOCK;
do_flush = 0;
if (0) fprintf(stderr, "check_user_input2-A: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (eaten < max_eat) {
continue;
@ -3864,7 +3875,7 @@ if (0) fprintf(stderr, "check_user_input2-A: XFlush %.4f\n", tm);
if (do_flush) {
X_LOCK;
if (0) fprintf(stderr, "check_user_input2-B: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
@ -3922,7 +3933,7 @@ if (0) fprintf(stderr, "check_user_input2-B: XFlush %.4f\n", tm);
}
X_LOCK;
if (0) fprintf(stderr, "check_user_input2-C: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
miss = 0;
} else {
@ -4020,7 +4031,7 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
got_input = 1;
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (--allowed_misses <= 0) {
/* too many misses */
@ -4172,7 +4183,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
}
if (iter) {
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
push_frame = 0;
@ -4256,7 +4267,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
got_input = 1;
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (consecutive_misses >= 2) {
@ -4296,7 +4307,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) {
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (use_xrecord) {
int rc = check_xrecord();
@ -4328,7 +4339,7 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
/* every ui_skip-th drops thru to scan */
*cnt++;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return 1; /* short circuit watch_loop */
} else {

File diff suppressed because it is too large Load Diff

@ -0,0 +1,10 @@
#ifndef _X11VNC_V4L_H
#define _X11VNC_V4L_H
/* -- v4l.h -- */
extern char *v4l_guess(char *str, int *fd);
extern void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
extern void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client);
#endif /* _X11VNC_V4L_H */

@ -4,6 +4,7 @@
#include "xinerama.h"
#include "winattr_t.h"
#include "cleanup.h"
#include "xwrappers.h"
winattr_t *stack_list = NULL;
int stack_list_len = 0;
@ -32,6 +33,7 @@ Window parent_window(Window win, char **name) {
if (name != NULL) {
*name = NULL;
}
RAWFB_RET(None)
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
@ -68,6 +70,7 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
if (win == None) {
return 0;
}
RAWFB_RET(0)
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
@ -92,6 +95,8 @@ Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
XErrorHandler old_handler;
Bool ok = False;
RAWFB_RET(False)
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
if (XTranslateCoordinates(dpy, src, dst, src_x, src_y, dst_x,
@ -157,6 +162,8 @@ void snapshot_stack_list(int free_only, double allowed_age) {
stack_list_num = 0;
last_free = now;
RAWFB_RET_VOID
X_LOCK;
/* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
@ -261,6 +268,7 @@ Window query_pointer(Window start) {
Window r, c;
int rx, ry, wx, wy;
unsigned int mask;
RAWFB_RET(None)
if (start == None) {
start = rootwin;
}
@ -276,6 +284,8 @@ int pick_windowid(unsigned long *num) {
int ok = 0, n = 0, msec = 10, secmax = 15;
FILE *p;
RAWFB_RET(0)
if (use_dpy) {
set_env("DISPLAY", use_dpy);
}
@ -319,7 +329,7 @@ int pick_windowid(unsigned long *num) {
* note this rfbPE takes about 30ms too:
*/
rfbPE(-1);
XFlush(dpy);
XFlush_wr(dpy);
continue;
}
}
@ -353,6 +363,8 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
static int nm_cache_len = 0;
static Window prev_start = None;
RAWFB_RET(None)
if (! classhint) {
classhint = XAllocClassHint();
}

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

@ -524,7 +524,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
* screen, but do flush the X11 display.
*/
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dt = 0.0;
} else {
@ -540,7 +540,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
}
dtime0(&tm);
if (use_snapfb) {
int t, tries = 5;
int t, tries = 3;
copy_snap();
for (t =0; t < tries; t++) {
tile_diffs = scan_for_updates(0);
@ -599,7 +599,7 @@ static char *choose_title(char *display) {
strncat(title, display, MAXN - strlen(title));
if (subwin && valid_window(subwin, NULL, 0)) {
char *name;
if (XFetchName(dpy, subwin, &name)) {
if (dpy && XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
}
@ -1030,6 +1030,7 @@ static void print_settings(int try_http, int bg, char *gui_str) {
fprintf(stderr, " cmap8to24: %d\n", cmap8to24);
fprintf(stderr, " 8to24_opts: %s\n", cmap8to24_str ? cmap8to24_str
: "null");
fprintf(stderr, " 24to32: %d\n", xform24to32);
fprintf(stderr, " visual: %s\n", visual_str ? visual_str
: "null");
fprintf(stderr, " overlay: %d\n", overlay);
@ -1521,6 +1522,8 @@ int main(int argc, char* argv[]) {
}
}
#endif
} else if (!strcmp(arg, "-24to32")) {
xform24to32 = 1;
} else if (!strcmp(arg, "-visual")) {
CHECK_ARGC
visual_str = strdup(argv[++i]);
@ -2111,6 +2114,9 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-rawfb")) {
CHECK_ARGC
raw_fb_str = strdup(argv[++i]);
} else if (!strcmp(arg, "-freqtab")) {
CHECK_ARGC
freqtab = strdup(argv[++i]);
} else if (!strcmp(arg, "-pipeinput")) {
CHECK_ARGC
pipeinput_str = strdup(argv[++i]);
@ -2782,7 +2788,7 @@ int main(int argc, char* argv[]) {
if (remote_cmd || query_cmd) {
int rc = do_remote_query(remote_cmd, query_cmd, remote_sync,
query_default);
XFlush(dpy);
XFlush_wr(dpy);
fflush(stderr);
fflush(stdout);
usleep(30 * 1000); /* still needed? */

@ -310,6 +310,9 @@ extern int xfixes_base_event_type;
#endif
extern int xdamage_base_event_type;
#define RAWFB_RET(y) if (raw_fb && ! dpy) return y;
#define RAWFB_RET_VOID if (raw_fb && ! dpy) return;
extern char lastmod[];
/* X display info */

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-04-25";
char lastmod[] = "0.8.1 lastmod: 2006-05-06";
/* X display info */

@ -169,6 +169,8 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
sraRegionPtr tmpregion;
int count = 0;
RAWFB_RET_VOID
if (! xdamage_present || ! use_xdamage) {
return;
}
@ -182,7 +184,7 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
X_LOCK;
if (flush) {
XFlush(dpy);
XFlush_wr(dpy);
}
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
count++;
@ -225,6 +227,8 @@ int collect_xdamage(int scancnt, int call) {
int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
double tm, dt;
RAWFB_RET(0)
if (scancnt) {} /* unused vars warning: */
if (! xdamage_present || ! use_xdamage) {
@ -252,7 +256,7 @@ int collect_xdamage(int scancnt, int call) {
X_LOCK;
if (0) XFlush(dpy);
if (0) XFlush_wr(dpy);
if (0) XEventsQueued(dpy, QueuedAfterFlush);
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
/*
@ -472,7 +476,7 @@ void initialize_xdamage(void) {
void create_xdamage_if_needed(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if (! xdamage) {
@ -487,14 +491,14 @@ void create_xdamage_if_needed(void) {
void destroy_xdamage_if_needed(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if (xdamage) {
XEvent ev;
X_LOCK;
XDamageDestroy(dpy, xdamage);
XFlush(dpy);
XFlush_wr(dpy);
if (xdamage_base_event_type) {
while (XCheckTypedEvent(dpy,
xdamage_base_event_type+XDamageNotify, &ev)) {

@ -38,15 +38,18 @@ static void grab_buster_watch(int parent, char *dstr);
void initialize_vnc_connect_prop(void) {
vnc_connect_str[0] = '\0';
RAWFB_RET_VOID
vnc_connect_prop = XInternAtom(dpy, "VNC_CONNECT", False);
}
void initialize_x11vnc_remote_prop(void) {
x11vnc_remote_str[0] = '\0';
RAWFB_RET_VOID
x11vnc_remote_prop = XInternAtom(dpy, "X11VNC_REMOTE", False);
}
void initialize_clipboard_atom(void) {
RAWFB_RET_VOID
clipboard_atom = XInternAtom(dpy, "CLIPBOARD", False);
if (clipboard_atom == None) {
if (! quiet) rfbLog("could not find atom CLIPBOARD\n");
@ -69,6 +72,7 @@ static void initialize_xevents(void) {
static int did_xdamage = 0;
static int did_xrandr = 0;
RAWFB_RET_VOID
if ((watch_selection || vnc_connect) && !did_xselect_input) {
/*
* register desired event(s) for notification.
@ -143,6 +147,7 @@ static void get_prop(char *str, int len, Atom prop) {
if (prop == None) {
return;
}
RAWFB_RET_VOID
slen = 0;
@ -224,7 +229,7 @@ static void bust_grab(int reset) {
fprintf(stderr, "**bust_grab: button%d %.4f\n",
button, dnowx());
XTestFakeButtonEvent_wr(dpy, button, True, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
usleep(50 * 1000);
XTestFakeButtonEvent_wr(dpy, button, False, CurrentTime);
} else if (x > 0) {
@ -234,14 +239,14 @@ static void bust_grab(int reset) {
fprintf(stderr, "**bust_grab: x=%d y=%d %.4f\n", x, y,
dnowx());
XTestFakeMotionEvent_wr(dpy, scr, x, y, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
usleep(50 * 1000);
/* followed by button press */
button = 1;
fprintf(stderr, "**bust_grab: button%d\n", button);
XTestFakeButtonEvent_wr(dpy, button, True, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
usleep(50 * 1000);
XTestFakeButtonEvent_wr(dpy, button, False, CurrentTime);
} else {
@ -249,11 +254,11 @@ static void bust_grab(int reset) {
fprintf(stderr, "**bust_grab: keycode: %d %.4f\n",
(int) key, dnowx());
XTestFakeKeyEvent_wr(dpy, key, True, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
usleep(50 * 1000);
XTestFakeKeyEvent_wr(dpy, key, False, CurrentTime);
}
XFlush(dpy);
XFlush_wr(dpy);
last_bust = time(0);
}
@ -429,6 +434,8 @@ static void grab_buster_watch(int parent, char *dstr) {
int ev, er, maj, min;
int db = 0;
RAWFB_RET_VOID
if (grab_buster > 1) {
db = 1;
}
@ -496,6 +503,8 @@ void spawn_grab_buster(void) {
int parent = (int) getpid();
char *dstr = strdup(DisplayString(dpy));
RAWFB_RET_VOID
XCloseDisplay(dpy);
dpy = NULL;
@ -534,6 +543,8 @@ void sync_tod_with_servertime(void) {
static unsigned long xserver_ticks = 1;
int i, db = 0;
RAWFB_RET_VOID
if (! ticker_atom) {
ticker_atom = XInternAtom(dpy, "X11VNC_TICKER", False);
}
@ -586,7 +597,7 @@ void check_keycode_state(void) {
return;
}
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (unixpw_in_progress) return;
@ -689,7 +700,7 @@ void check_xevents(void) {
time_t now = time(0);
static double last_request = 0.0;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (unixpw_in_progress) return;
@ -1043,7 +1054,7 @@ void check_xevents(void) {
void xcut_receive(char *text, int len, rfbClientPtr cl) {
allowed_input_t input;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (unixpw_in_progress) return;
@ -1072,7 +1083,7 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
own_primary = 1;
/* we need to grab the PRIMARY selection */
XSetSelectionOwner(dpy, XA_PRIMARY, selwin, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
if (debug_sel) {
rfbLog("Own PRIMARY.\n");
}
@ -1082,7 +1093,7 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
own_clipboard = 1;
/* we need to grab the CLIPBOARD selection */
XSetSelectionOwner(dpy, clipboard_atom, selwin, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
if (debug_sel) {
rfbLog("Own CLIPBOARD.\n");
}
@ -1117,7 +1128,7 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
/* copy this text to CUT_BUFFER0 as well: */
XChangeProperty(dpy, rootwin, XA_CUT_BUFFER0, XA_STRING, 8,
PropModeReplace, (unsigned char *) text, len);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;

@ -240,7 +240,7 @@ static void initialize_xinerama (void) {
char *bstr, *tstr;
int ev, er, i, n, rcnt;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! XineramaQueryExtension(dpy, &ev, &er)) {
rfbLog("Xinerama: disabling: display does not support it.\n");

@ -23,6 +23,8 @@ void initialize_xkb(void) {
int ir, reason;
int op, ev, er, maj, min;
RAWFB_RET_VOID
if (xkbcompat) {
xkb_present = 0;
} else if (! XkbQueryExtension(dpy, &op, &ev, &er, &maj, &min)) {
@ -60,6 +62,8 @@ void initialize_watch_bell(void) {
return;
}
RAWFB_RET_VOID
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbBellNotifyMask, 0);
if (! watch_bell) {
@ -88,6 +92,7 @@ void check_bell_event(void) {
if (! xkb_base_event_type) {
return;
}
RAWFB_RET_VOID
/* caller does X_LOCK */
if (! XCheckTypedEvent(dpy, xkb_base_event_type, &xev)) {

@ -28,7 +28,7 @@ static void handle_xrandr_change(int new_x, int new_y);
void initialize_xrandr(void) {
if (xrandr_present) {
if (xrandr_present && dpy) {
#if LIBVNCSERVER_HAVE_LIBXRANDR
Rotation rot;
@ -110,6 +110,8 @@ static void handle_xrandr_change(int new_x, int new_y) {
rfbClientIteratorPtr iter;
rfbClientPtr cl;
RAWFB_RET_VOID
/* sanity check xrandr_mode */
if (! xrandr_mode) {
xrandr_mode = strdup("default");
@ -148,6 +150,9 @@ static void handle_xrandr_change(int new_x, int new_y) {
int check_xrandr_event(char *msg) {
XEvent xev;
RAWFB_RET(0)
if (subwin) {
return handle_subwin_resize(msg);
}

@ -101,7 +101,7 @@ static void xrecord_grabserver(int start) {
}
XRecordDisableContext(gdpy_ctrl, rc_grab);
XRecordFreeContext(gdpy_ctrl, rc_grab);
XFlush(gdpy_ctrl);
XFlush_wr(gdpy_ctrl);
rc_grab = 0;
return;
}
@ -135,7 +135,7 @@ static void xrecord_grabserver(int start) {
return;
}
XSetErrorHandler(old_handler);
XFlush(gdpy_data);
XFlush_wr(gdpy_data);
#endif
if (debug_grabs) {
fprintf(stderr, "xrecord_grabserver-done: %.5f\n", dnowx());
@ -153,6 +153,7 @@ void initialize_xrecord(void) {
if (noxrecord) {
return;
}
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_RECORD
if (rr_CA) XFree(rr_CA);
@ -1307,7 +1308,7 @@ static void check_xrecord_grabserver(void) {
if (unixpw_in_progress) return;
dtime0(&d);
XFlush(gdpy_ctrl);
XFlush_wr(gdpy_ctrl);
for (i=0; i<max; i++) {
last_val = xserver_grabbed;
XRecordProcessReplies(gdpy_data);
@ -1318,7 +1319,7 @@ static void check_xrecord_grabserver(void) {
}
}
if (cnt) {
XFlush(gdpy_ctrl);
XFlush_wr(gdpy_ctrl);
}
if (debug_grabs && cnt > 0) {
d = dtime(&d);
@ -1332,6 +1333,7 @@ static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen)
int ret1, ret2;
int verb = (!bequiet && !quiet);
RAWFB_RET_VOID
if (0 || debug_scroll) {
rfbLog("shutdown_record_context(0x%lx, %d, %d)\n", rc,
bequiet, reopen);
@ -1346,7 +1348,7 @@ static void shutdown_record_context(XRecordContext rc, int bequiet, int reopen)
if (!ret2 && verb) {
rfbLog("XRecordFreeContext(0x%lx) failed.\n", rc);
}
XFlush(rdpy_ctrl);
XFlush_wr(rdpy_ctrl);
if (reopen == 2 && ret1 && ret2) {
reopen = 0; /* 2 means reopen only on failure */
@ -1607,7 +1609,7 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr
XRecordUnregisterClients(rdpy_ctrl, rc_scroll,
&rcs_scroll, 1);
XRecordDisableContext(rdpy_ctrl, rc_scroll);
XFlush(rdpy_ctrl);
XFlush_wr(rdpy_ctrl);
XRecordProcessReplies(rdpy_data);
if (trapped_record_xerror) {
@ -1633,7 +1635,7 @@ if (db > 1) fprintf(stderr, "=== disab-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr
SCR_UNLOCK;
/*
* XXX if we do a XFlush(rdpy_ctrl) here we get:
* XXX if we do a XFlush_wr(rdpy_ctrl) here we get:
*
X Error of failed request: XRecordBadContext
@ -1830,7 +1832,7 @@ if (db > 1) fprintf(stderr, "=-= reg-scroll 0x%lx 0x%lx\n", rc_scroll, rcs_scr
}
}
XFlush(rdpy_ctrl);
XFlush_wr(rdpy_ctrl);
if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
if (trapped_record_xerror) {
@ -1896,7 +1898,7 @@ if (db) fprintf(stderr, "rc_scroll: 0x%lx\n", rc_scroll);
/* XXX this may cause more problems than it solves... */
if (use_xrecord) {
XFlush(rdpy_data);
XFlush_wr(rdpy_data);
}
X_UNLOCK;

@ -18,6 +18,8 @@ int clipshift = 0;
int guess_bits_per_color(int bits_per_pixel);
int XFlush_wr(Display *disp);
Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
unsigned long mask);
XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
@ -66,11 +68,9 @@ void disable_grabserver(Display *in_dpy, int change);
Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
static void upup_downdown_warning(KeyCode key, Bool down);
/*
* used in rfbGetScreen and rfbNewFramebuffer: and estimate to the number
* of bits per color, of course for some visuals, e.g. 565, the number
@ -96,6 +96,14 @@ int guess_bits_per_color(int bits_per_pixel) {
return bits_per_color;
}
int XFlush_wr(Display *disp) {
if (disp) {
return XFlush(disp);
} else {
return 1;
}
}
/*
* Kludge to interpose image gets and limit to a subset rectangle of
* the rootwin. This is the -sid option trying to work around invisible
@ -277,17 +285,161 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
width, height, bitmap_pad, bytes_per_line);
}
static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w,
unsigned int h) {
/*
* kludge to read 1 byte at a time and dynamically transform
* 24bpp -> 32bpp by inserting a extra 0 byte into dst.
*/
char *src, *dst;
unsigned int line;
static char *buf = NULL;
static int buflen = -1;
int bpl = wdpy_x * 3; /* pixelsize == 3 */
int LE, n, stp, len, del, sz = w * 3;
int insert_zeroes = 1;
#define INSERT_ZEROES \
len = sz; \
del = 0; \
stp = 0; \
while (len > 0) { \
if (insert_zeroes && (del - LE) % 4 == 0) { \
*(dst + del) = 0; \
del++; \
} \
*(dst + del) = *(buf + stp); \
del++; \
len--; \
stp++; \
}
if (rfbEndianTest) {
LE = 3; /* little endian */
} else {
LE = 0; /* big endian */
}
if (sz > buflen || buf == NULL) {
if (buf) {
free(buf);
}
buf = (char *) malloc(4*(sz + 1000));
}
if (clipshift && ! use_snapfb) {
x += coff_x;
y += coff_y;
}
if (use_snapfb && dest != snap) {
/* snapfb src */
src = snap->data + snap->bytes_per_line*y + 3*x;
dst = dest->data;
for (line = 0; line < h; line++) {
memcpy(buf, src, sz);
INSERT_ZEROES
src += snap->bytes_per_line;
dst += dest->bytes_per_line;
}
} else if (! raw_fb_seek) {
/* mmap */
src = raw_fb_addr + raw_fb_offset + bpl*y + 3*x;
dst = dest->data;
if (use_snapfb && dest == snap) {
/*
* writing *to* snap_fb: need the x,y offset,
* and also do not do inserts.
*/
dst += bpl*y + 3*x;
insert_zeroes = 0;
}
for (line = 0; line < h; line++) {
memcpy(buf, src, sz);
INSERT_ZEROES
src += bpl;
dst += dest->bytes_per_line;
}
} else {
/* lseek */
off_t off = (off_t) (raw_fb_offset + bpl*y + 3*x);
lseek(raw_fb_fd, off, SEEK_SET);
dst = dest->data;
if (use_snapfb && dest == snap) {
/*
* writing *to* snap_fb: need the x,y offset,
* and also do not do inserts.
*/
dst += bpl*y + 3*x;
insert_zeroes = 0;
}
for (line = 0; line < h; line++) {
len = sz;
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;
}
}
INSERT_ZEROES
if (bpl > sz) {
off = (off_t) (bpl - sz);
lseek(raw_fb_fd, off, SEEK_CUR);
}
dst += dest->bytes_per_line;
}
}
}
void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
char *src, *dst;
unsigned int line;
int pixelsize = bpp/8;
int bpl = wdpy_x * pixelsize;
if (clipshift) {
if (xform24to32) {
copy_raw_fb_24_to_32(dest, x, y, w, h);
return;
}
if (clipshift && ! use_snapfb) {
x += coff_x;
y += coff_y;
}
if (! raw_fb_seek) {
if (use_snapfb && dest != snap) {
/* snapfb src */
src = snap->data + snap->bytes_per_line*y + pixelsize*x;
dst = dest->data;
for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize);
src += snap->bytes_per_line;
dst += dest->bytes_per_line;
}
} else if (! raw_fb_seek) {
/* mmap */
src = raw_fb_addr + raw_fb_offset + bpl*y + pixelsize*x;
dst = dest->data;
@ -296,32 +448,35 @@ static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int
src += bpl;
dst += dest->bytes_per_line;
}
} else{
} else {
/* lseek */
int n, len, del, sz = w * pixelsize;
off_t off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x);
lseek(raw_fb_fd, off, SEEK_SET);
dst = dest->data;
if (0) fprintf(stderr, "lseek 0 ps: %d sz: %d off: %d bpl: %d\n", pixelsize, sz, (int) off, bpl);
for (line = 0; line < h; line++) {
len = sz;
del = 0;
while (len > 0) {
n = read(raw_fb_fd, dst + del, len);
if (0) fprintf(stderr, "len: %d n: %d\n", len, n);
if (n > 0) {
del += n;
len -= n;
} else if (n == 0) {
break;
} else {
/* overkill... */
if (errno != EINTR && errno != EAGAIN) {
break;
}
} else if (errno != EINTR && errno != EAGAIN) {
break;
}
}
if (bpl > sz) {
if (0) fprintf(stderr, "bpl>sz %d %d\n", bpl, sz);
off = (off_t) (bpl - sz);
lseek(raw_fb_fd, off, SEEK_CUR);
}
@ -332,6 +487,9 @@ static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int
void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
/* default (w=0, h=0) is the fill the entire XImage */
if (dest == NULL) {
return;
}
if (w < 1) {
w = dest->width;
}
@ -339,7 +497,10 @@ void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
h = dest->height;
}
if (use_snapfb && snap_fb && dest != snaprect) {
if (raw_fb) {
copy_raw_fb(dest, x, y, w, h);
} else if (use_snapfb && snap_fb && dest != snaprect) {
char *src, *dst;
unsigned int line;
int pixelsize = bpp/8;
@ -352,10 +513,7 @@ void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
dst += dest->bytes_per_line;
}
} else if (raw_fb) {
copy_raw_fb(dest, x, y, w, h);
} else if (using_shm && (int) w == dest->width &&
} else if ((using_shm && ! xform24to32) && (int) w == dest->width &&
(int) h == dest->height) {
XShmGetImage_wr(dpy, window, dest, x, y, AllPlanes);
@ -379,6 +537,8 @@ void init_track_keycode_state(void) {
}
static void upup_downdown_warning(KeyCode key, Bool down) {
RAWFB_RET_VOID
if ((down ? 1:0) == keycode_state[(int) key]) {
rfbLog("XTestFakeKeyEvent: keycode=0x%x \"%s\" is *already* "
"%s\n", key, XKeysymToString(XKeycodeToKeysym(dpy, key, 0)),
@ -394,12 +554,14 @@ static void upup_downdown_warning(KeyCode key, Bool down) {
void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
unsigned long delay) {
RAWFB_RET_VOID
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "keyboard: no-XTRAP");
return;
}
/* unused vars warning: */
if (dpy || key || down || delay) {}
if (key || down || delay) {}
#if LIBVNCSERVER_HAVE_LIBXTRAP
XESimulateXEventRequest(trap_ctx, down ? KeyPress : KeyRelease,
@ -416,6 +578,9 @@ void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
unsigned long delay) {
static int first = 1;
RAWFB_RET_VOID
if (debug_keyboard) {
rfbLog("XTestFakeKeyEvent(dpy, keycode=0x%x \"%s\", %s)\n",
key, XKeysymToString(XKeycodeToKeysym(dpy, key, 0)),
@ -456,12 +621,14 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
unsigned long delay) {
RAWFB_RET_VOID
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "button: no-XTRAP");
return;
}
/* unused vars warning: */
if (dpy || button || is_press || delay) {}
if (button || is_press || delay) {}
#if LIBVNCSERVER_HAVE_LIBXTRAP
XESimulateXEventRequest(trap_ctx,
@ -474,6 +641,8 @@ void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
unsigned long delay) {
RAWFB_RET_VOID
if (xtrap_input) {
XTRAP_FakeButtonEvent_wr(dpy, button, is_press, delay);
return;
@ -495,6 +664,8 @@ void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
unsigned long delay) {
RAWFB_RET_VOID
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "motion: no-XTRAP");
return;
@ -512,6 +683,8 @@ void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
unsigned long delay) {
RAWFB_RET_VOID
if (xtrap_input) {
XTRAP_FakeMotionEvent_wr(dpy, screen, x, y, delay);
return;
@ -530,6 +703,8 @@ Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w) {
if (! xtest_present) {
return False;
}
RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_XTEST
return XTestCompareCurrentCursorWithWindow(dpy, w);
#else
@ -541,6 +716,7 @@ Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor) {
if (! xtest_present) {
return False;
}
RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_XTEST
return XTestCompareCursorWithWindow(dpy, w, cursor);
#else
@ -550,6 +726,7 @@ Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor) {
Bool XTestQueryExtension_wr(Display *dpy, int *ev, int *er, int *maj,
int *min) {
RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_XTEST
return XTestQueryExtension(dpy, ev, er, maj, min);
#else
@ -561,18 +738,20 @@ void XTestDiscard_wr(Display *dpy) {
if (! xtest_present) {
return;
}
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_XTEST
XTestDiscard(dpy);
#endif
}
Bool XETrapQueryExtension_wr(Display *dpy, int *ev, int *er, int *op) {
RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_LIBXTRAP
return XETrapQueryExtension(dpy, (INT32 *)ev, (INT32 *)er,
(INT32 *)op);
#else
/* unused vars warning: */
if (dpy || ev || er || op) {}
if (ev || er || op) {}
return False;
#endif
}
@ -581,6 +760,7 @@ int XTestGrabControl_wr(Display *dpy, Bool impervious) {
if (! xtest_present) {
return 0;
}
RAWFB_RET(0)
#if LIBVNCSERVER_HAVE_XTEST && LIBVNCSERVER_HAVE_XTESTGRABCONTROL
XTestGrabControl(dpy, impervious);
return 1;
@ -595,6 +775,7 @@ int XTRAP_GrabControl_wr(Display *dpy, Bool impervious) {
if (dpy || impervious) {}
return 0;
}
RAWFB_RET(0)
#if LIBVNCSERVER_HAVE_LIBXTRAP
else {
ReqFlags requests;
@ -685,10 +866,11 @@ void disable_grabserver(Display *in_dpy, int change) {
rfbLog("* DEADLOCK if your window manager calls XGrabServer !!! *\n");
rfbLog("*********************************************************\n");
}
XFlush(in_dpy);
XFlush_wr(in_dpy);
}
Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min) {
RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_RECORD
return XRecordQueryVersion(dpy, maj, min);
#else

@ -17,6 +17,8 @@ extern int clipshift;
extern int guess_bits_per_color(int bits_per_pixel);
extern int XFlush_wr(Display *disp);
extern Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
unsigned long mask);
extern XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
@ -38,6 +40,7 @@ extern XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth
int format, int offset, char *data, unsigned int width,
unsigned int height, int bitmap_pad, int bytes_per_line);
extern void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h);
extern void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
extern void init_track_keycode_state(void);
extern void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,

Loading…
Cancel
Save