x11vnc: fix some -rawfb bugs, add setup:cmd

pull/1/head
runge 19 years ago
parent baee5e2b3a
commit 7ed9e5b1d0

@ -1,3 +1,7 @@
2005-04-11 Karl Runge <runge@karlrunge.com>
* fix -clip under -rawfb, fix offset bug under file lseeking.
* add -rawfb setup:cmd mode to initialize fb.
2005-04-10 Karl Runge <runge@karlrunge.com> 2005-04-10 Karl Runge <runge@karlrunge.com>
* -rawfb non X-polling (i.e. shm, mmap, lseek). * -rawfb non X-polling (i.e. shm, mmap, lseek).
* -pipeinput enable external user input processing command. * -pipeinput enable external user input processing command.

File diff suppressed because it is too large Load Diff

@ -75,7 +75,7 @@ $I = 0;
while (<>) { while (<>) {
# read the next user input event, watch for button press or spacebar: # read the next user input event, watch for button press or spacebar:
last if /^Keysym.* [qQ] /; ###last if /^Keysym.* [qQ] /;
next unless /^(Pointer.*ButtonPress|Keysym.*space.*KeyPress)/; next unless /^(Pointer.*ButtonPress|Keysym.*space.*KeyPress)/;
$I = ($I + 1) % $N; $I = ($I + 1) % $N;
showpic($I); showpic($I);
@ -108,5 +108,5 @@ sub showpic {
} }
close(FB); close(FB);
#unlink($fb); # this (probably) won't kill x11vnc ###unlink($fb); # this (probably) won't kill x11vnc
print STDERR "$0 done.\n"; print STDERR "$0 done.\n";

@ -176,6 +176,7 @@ Misc
=-C:ignore,exit sigpipe: =-C:ignore,exit sigpipe:
=0 inetd =0 inetd
rfbwait: rfbwait:
pipeinput:
-- --
=RA remote-cmd: =RA remote-cmd:
=GA all-settings =GA all-settings

@ -182,6 +182,7 @@
" =-C:ignore,exit sigpipe:\n" " =-C:ignore,exit sigpipe:\n"
" =0 inetd\n" " =0 inetd\n"
" rfbwait:\n" " rfbwait:\n"
" pipeinput:\n"
" --\n" " --\n"
" =RA remote-cmd:\n" " =RA remote-cmd:\n"
" =GA all-settings\n" " =GA all-settings\n"

@ -2,7 +2,7 @@
.TH X11VNC "1" "April 2005" "x11vnc " "User Commands" .TH X11VNC "1" "April 2005" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.7.2pre, lastmod: 2005-04-10 version: 0.7.2, lastmod: 2005-04-11
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -1164,8 +1164,8 @@ or where window tearing is a problem.
Experimental option, instead of polling X, poll the Experimental option, instead of polling X, poll the
memory object specified in \fIstring\fR. For shared memory object specified in \fIstring\fR. For shared
memory segments it is of the form: "shm:N@WxHxB" memory segments it is of the form: "shm:N@WxHxB"
which specifies a shmid N and framebuffer width, height, which specifies a shmid N and framebuffer Width, Height,
and bits per pixel. To memory map and Bits per pixel. To memory map
.IR mmap (2) .IR mmap (2)
a file use: a file use:
"map:/path/to/a/file@WxHxB". If there is trouble "map:/path/to/a/file@WxHxB". If there is trouble
@ -1174,15 +1174,25 @@ with mmap, use "file:/..." for slower
based based
reading. reading.
.IP .IP
If string is "setup:cmd", then the command "cmd"
is run and the first line from it is read and used
as \fIstring\fR. This allows initializing the device,
determining WxHxB, etc. These are often done as root
so take care.
.IP
Optional suffixes are ":R/G/B" and "+O" to specify Optional suffixes are ":R/G/B" and "+O" to specify
red, green, and blue masks and an offset into the red, green, and blue masks and an offset into the
memory object. If the masks are not provided x11vnc memory object. If the masks are not provided x11vnc
guesses them based on the bpp. guesses them based on the bpp.
.IP .IP
Examples: Examples:
.IP
\fB-rawfb\fR shm:210337933@800x600x32:ff/ff00/ff0000 \fB-rawfb\fR shm:210337933@800x600x32:ff/ff00/ff0000
.IP
\fB-rawfb\fR map:/dev/fb0@1024x768x32 \fB-rawfb\fR map:/dev/fb0@1024x768x32
.IP
\fB-rawfb\fR map:/tmp/Xvfb_screen0@640x480x8+3232 \fB-rawfb\fR map:/tmp/Xvfb_screen0@640x480x8+3232
.IP
\fB-rawfb\fR file:/tmp/my.pnm@250x200x24+37 \fB-rawfb\fR file:/tmp/my.pnm@250x200x24+37
.IP .IP
(see (see
@ -1197,19 +1207,20 @@ will cause this mode to crash, so please think twice
before setting/changing them. If you don't want x11vnc before setting/changing them. If you don't want x11vnc
to close the DISPLAY in rawfb mode, then capitalize to close the DISPLAY in rawfb mode, then capitalize
the prefix, SHM:, MAP: etc. Keeping the display open the prefix, SHM:, MAP: etc. Keeping the display open
enables defautl remote control channel. enables default remote-control channel.
.PP .PP
\fB-pipeinput\fR \fIcmd\fR \fB-pipeinput\fR \fIcmd\fR
.IP .IP
Another experimental option: it lets you supply an Another experimental option: it lets you supply
extern command in \fIcmd\fR that x11vnc will pipe all of an extern command in \fIcmd\fR that x11vnc will pipe
the user input events to in a simple format. By default all of the user input events to in a simple format.
x11vnc will not process any of the user input events. In \fB-pipeinput\fR mode by default x11vnc will not process
If you prefix \fIcmd\fR with "tee:" it will both send any of the user input events. If you prefix \fIcmd\fR
them to the pipe command and process them. For a with "tee:" it will both send them to the pipe
description of the format run "\fB-pipeinput\fR \fItee:cat\fR". command and process them. For a description of the
Another prefix is "reopen" which means to reopen pipe format run "\fB-pipeinput\fR \fItee:/bin/cat\fR". Another prefix
if it exits. Separate multiple prefixes with commas. is "reopen" which means to reopen pipe if it exits.
Separate multiple prefixes with commas.
.IP .IP
In combination with \fB-rawfb\fR one might be able to In combination with \fB-rawfb\fR one might be able to
do amusing things (e.g. control non-X devices). do amusing things (e.g. control non-X devices).
@ -1717,25 +1728,26 @@ noalpharemove alphablend noalphablend xwarp xwarppointer
noxwarp noxwarppointer buttonmap dragging nodragging noxwarp noxwarppointer buttonmap dragging nodragging
pointer_mode pm input_skip input client_input speeds pointer_mode pm input_skip input client_input speeds
debug_pointer dp nodebug_pointer nodp debug_keyboard dk debug_pointer dp nodebug_pointer nodp debug_keyboard dk
nodebug_keyboard nodk deferupdate defer wait rfbwait nodebug_keyboard nodk deferupdate defer wait rfbwait nap
nap nonap sb screen_blank fs gaps grow fuzz snapfb nonap sb screen_blank fs gaps grow fuzz snapfb nosnapfb
nosnapfb rawfb progressive rfbport http nohttp httpport rawfb setup: progressive rfbport http nohttp httpport
httpdir enablehttpproxy noenablehttpproxy alwaysshared httpdir enablehttpproxy noenablehttpproxy alwaysshared
noalwaysshared nevershared noalwaysshared dontdisconnect noalwaysshared nevershared noalwaysshared dontdisconnect
nodontdisconnect desktop noremote nodontdisconnect desktop noremote
.IP .IP
aro= display vncdisplay desktopname http_url auth aro= debug_xevents: display vncdisplay desktopname
users rootshift clipshift scale_str scaled_x scaled_y http_url auth users rootshift clipshift scale_str
scale_numer scale_denom scale_fac scaling_blend scaled_x scaled_y scale_numer scale_denom
scaling_nomult4 scaling_pad scaling_interpolate scale_fac scaling_blend scaling_nomult4 scaling_pad
inetd safer unsafe passwdfile using_shm logfile o scaling_interpolate inetd safer unsafe passwdfile
flag rc norc h help V version lastmod bg sigpipe using_shm logfile o flag rc norc h help V version
threads clients client_count pid ext_xtest ext_xtrap lastmod bg sigpipe threads pipeinput clients
ext_xkb ext_xshm ext_xinerama ext_overlay ext_xfixes client_count pid ext_xtest ext_xtrap ext_xkb ext_xshm
ext_xdamage ext_xrandr rootwin num_buttons button_mask ext_xinerama ext_overlay ext_xfixes ext_xdamage
mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y ext_xrandr rootwin num_buttons button_mask mouse_x
wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y mouse_y bpp depth indexed_color dpy_x dpy_y wdpy_x
rfbauth passwd wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth
passwd
.PP .PP
\fB-sync\fR \fB-sync\fR
.IP .IP

@ -405,7 +405,7 @@ int overlay_present = 0;
#if LIBVNCSERVER_HAVE_LIBXRANDR #if LIBVNCSERVER_HAVE_LIBXRANDR
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#endif #endif
static int xrandr_base_event_type = 0; int xrandr_base_event_type = 0;
int xfixes_present = 0; int xfixes_present = 0;
@ -419,8 +419,8 @@ int alt_arrow = 1;
#if LIBVNCSERVER_HAVE_LIBXFIXES #if LIBVNCSERVER_HAVE_LIBXFIXES
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
static int xfixes_base_event_type = 0;
#endif #endif
int xfixes_base_event_type = 0;
int xdamage_present = 0; int xdamage_present = 0;
@ -428,15 +428,15 @@ int use_xdamage = 1; /* just use the xdamage rects. for scanline hints */
#if LIBVNCSERVER_HAVE_LIBXDAMAGE #if LIBVNCSERVER_HAVE_LIBXDAMAGE
#include <X11/extensions/Xdamage.h> #include <X11/extensions/Xdamage.h>
Damage xdamage = 0; Damage xdamage = 0;
static int xdamage_base_event_type = 0;
#endif #endif
int xdamage_base_event_type = 0;
int xdamage_max_area = 20000; /* pixels */ int xdamage_max_area = 20000; /* pixels */
double xdamage_memory = 1.0; /* in units of NSCAN */ double xdamage_memory = 1.0; /* in units of NSCAN */
int xdamage_tile_count; int xdamage_tile_count;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.7.2pre lastmod: 2005-04-10"; char lastmod[] = "0.7.2 lastmod: 2005-04-11";
int hack_val = 0; int hack_val = 0;
/* X display info */ /* X display info */
@ -559,7 +559,6 @@ unsigned char *tile_has_xdamage_diff, *tile_row_has_xdamage_diff;
/* times of recent events */ /* times of recent events */
time_t last_event, last_input, last_client = 0; time_t last_event, last_input, last_client = 0;
time_t last_sendevent = 0;
/* last client to move pointer */ /* last client to move pointer */
rfbClientPtr last_pointer_client = NULL; rfbClientPtr last_pointer_client = NULL;
@ -820,6 +819,8 @@ int pipeinput_tee = 0;
unsigned long subwin = 0x0; /* -id, -sid */ unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0; int subwin_wait_mapped = 0;
int debug_xevents = 0; /* -R debug_xevents:1 */
int xtrap_input = 0; /* -xtrap for user input insertion */ int xtrap_input = 0; /* -xtrap for user input insertion */
int xinerama = 0; /* -xinerama */ int xinerama = 0; /* -xinerama */
int xrandr = 0; /* -xrandr */ int xrandr = 0; /* -xrandr */
@ -2315,20 +2316,23 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
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) {
char *src, *dst; char *src, *dst;
int line, pixelsize = bpp/8; int line, pixelsize = bpp/8;
int bpl = wdpy_x * pixelsize;
if (clipshift) {
x += coff_x;
y += coff_y;
}
if (! raw_fb_seek) { if (! raw_fb_seek) {
src = (raw_fb_addr + raw_fb_offset) src = raw_fb_addr + raw_fb_offset + bpl*y + pixelsize*x;
+ raw_fb_image->bytes_per_line*y + pixelsize*x;
dst = dest->data; dst = dest->data;
for (line = 0; line < h; line++) { for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize); memcpy(dst, src, w * pixelsize);
src += raw_fb_image->bytes_per_line; src += bpl;
dst += dest->bytes_per_line; dst += dest->bytes_per_line;
} }
} else{ } else{
int n, len, del, sz = w * pixelsize; int n, len, del, sz = w * pixelsize;
int bpl = raw_fb_image->bytes_per_line;
off_t off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x); off_t off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x);
lseek(raw_fb_fd, off, SEEK_SET); lseek(raw_fb_fd, off, SEEK_SET);
@ -2352,6 +2356,10 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
} }
} }
} }
if (bpl > sz) {
off = (off_t) (bpl - sz);
lseek(raw_fb_fd, off, SEEK_CUR);
}
dst += dest->bytes_per_line; dst += dest->bytes_per_line;
} }
} }
@ -3187,6 +3195,25 @@ void set_client_input(char *str) {
free(cl_list); free(cl_list);
} }
void set_child_info(void) {
char pid[16];
/* set up useful environment for child process */
sprintf(pid, "%d", (int) getpid());
set_env("X11VNC_PID", pid);
if (program_name) {
/* e.g. for remote control -R */
set_env("X11VNC_PROG", program_name);
}
if (program_cmdline) {
set_env("X11VNC_CMDLINE", program_cmdline);
}
if (raw_fb_str) {
set_env("X11VNC_RAWFB_STR", raw_fb_str);
} else {
set_env("X11VNC_RAWFB_STR", "");
}
}
/* /*
* utility to run a user supplied command setting some RFB_ env vars. * utility to run a user supplied command setting some RFB_ env vars.
* used by, e.g., accept_client() and client_gone() * used by, e.g., accept_client() and client_gone()
@ -6751,7 +6778,6 @@ int check_pipeinput(void) {
void initialize_pipeinput(void) { void initialize_pipeinput(void) {
char *p; char *p;
char pid[16];
if (pipeinput_fh != NULL) { if (pipeinput_fh != NULL) {
rfbLog("closing pipeinput stream: %p\n", pipeinput_fh); rfbLog("closing pipeinput stream: %p\n", pipeinput_fh);
@ -6803,20 +6829,7 @@ void initialize_pipeinput(void) {
p = pipeinput_str; p = pipeinput_str;
} }
/* set up useful environment for child process */ set_child_info();
sprintf(pid, "%d", (int) getpid());
set_env("X11VNC_PID", pid);
if (program_name) {
/* e.g. for remote control -R */
set_env("X11VNC_PROG", program_name);
}
if (program_cmdline) {
set_env("X11VNC_CMDLINE", program_cmdline);
}
if (raw_fb_str) {
set_env("X11VNC_RAWFB_STR", raw_fb_str);
}
rfbLog("pipeinput: starting: \"%s\"...\n", p); rfbLog("pipeinput: starting: \"%s\"...\n", p);
pipeinput_fh = popen(p, "w"); pipeinput_fh = popen(p, "w");
@ -6862,7 +6875,7 @@ void initialize_pipeinput(void) {
"# if two more more buttons change state in one event they are listed\n" "# if two more more buttons change state in one event they are listed\n"
"# separated by commas.\n" "# separated by commas.\n"
"#\n" "#\n"
"# One might parse a Pointer like with:\n" "# One might parse a Pointer line with:\n"
"#\n" "#\n"
"# int client, x, y, mask; char *hint;\n" "# int client, x, y, mask; char *hint;\n"
"# sscanf(line, \"Pointer %d %d %d %s\", &client, &x, &y, &mask, &hint);\n" "# sscanf(line, \"Pointer %d %d %d %s\", &client, &x, &y, &mask, &hint);\n"
@ -6887,7 +6900,7 @@ void initialize_pipeinput(void) {
"# You basically remove the leading 'XK_' prefix from the macro name in\n" "# You basically remove the leading 'XK_' prefix from the macro name in\n"
"# that file to get the Keysym name.\n" "# that file to get the Keysym name.\n"
"#\n" "#\n"
"# One might parse a Pointer like with:\n" "# One might parse a Keysym line with:\n"
"#\n" "#\n"
"# int client, down, keysym; char *name, *hint;\n" "# int client, down, keysym; char *name, *hint;\n"
"# sscanf(line, \"Keysym %d %d %s %s\", &client, &down, &keysym, &name, &hint);\n" "# sscanf(line, \"Keysym %d %d %s %s\", &client, &down, &keysym, &name, &hint);\n"
@ -6907,7 +6920,8 @@ void initialize_pipeinput(void) {
"# info will be enough for most purposes (having identical keyboards on\n" "# info will be enough for most purposes (having identical keyboards on\n"
"# both sides helps).\n" "# both sides helps).\n"
"#\n" "#\n"
"# Here comes yours stream:\n" "# Here comes your stream. The following token will always indicate the\n"
"# end of this informational text:\n"
"# END_OF_TOP\n" "# END_OF_TOP\n"
); );
fflush(pipeinput_fh); fflush(pipeinput_fh);
@ -6921,10 +6935,9 @@ void initialize_pipeinput(void) {
/* /*
* Bell event handling. Requires XKEYBOARD extension. * Bell event handling. Requires XKEYBOARD extension.
*/ */
#if LIBVNCSERVER_HAVE_XKEYBOARD int xkb_base_event_type = 0;
static int xkb_base_event_type = 0;
#if LIBVNCSERVER_HAVE_XKEYBOARD
/* /*
* check for XKEYBOARD, set up xkb_base_event_type * check for XKEYBOARD, set up xkb_base_event_type
*/ */
@ -7374,7 +7387,6 @@ static void selection_request(XEvent *ev) {
if (! trapped_xerror) { if (! trapped_xerror) {
XSendEvent(req_event->display, req_event->requestor, False, 0, XSendEvent(req_event->display, req_event->requestor, False, 0,
(XEvent *)&notify_event); (XEvent *)&notify_event);
last_sendevent = time(0);
} }
if (trapped_xerror) { if (trapped_xerror) {
rfbLog("selection_request: ignored XError while sending " rfbLog("selection_request: ignored XError while sending "
@ -7586,6 +7598,18 @@ void initialize_xevents(void) {
} }
} }
void print_xevent_bases(void) {
fprintf(stderr, "X event bases: xkb=%d, xtest=%d, xrandr=%d, "
"xfixes=%d, xdamage=%d, xtrap=%d\n", xkb_base_event_type,
xtest_base_event_type, xrandr_base_event_type,
xfixes_base_event_type, xdamage_base_event_type,
xtrap_base_event_type);
fprintf(stderr, " MapNotify=%d, ClientMsg=%d PropNotify=%d "
"SelNotify=%d, SelRequest=%d\n", MappingNotify, ClientMessage,
PropertyNotify, SelectionNotify, SelectionRequest);
fprintf(stderr, " SelClear=%d, Expose=%d\n", SelectionClear, Expose);
}
/* /*
* This routine is periodically called to check for selection related * This routine is periodically called to check for selection related
* and other X11 events and respond to them as needed. * and other X11 events and respond to them as needed.
@ -7685,9 +7709,6 @@ void check_xevents(void) {
; ;
} }
} }
}
if (last_sendevent && (now > last_sendevent+1 || now % 10 == 0)) {
/* /*
* we can get ClientMessage from our XSendEvent() call in * we can get ClientMessage from our XSendEvent() call in
* selection_request(). * selection_request().
@ -7695,7 +7716,6 @@ void check_xevents(void) {
while (XCheckTypedEvent(dpy, ClientMessage, &xev)) { while (XCheckTypedEvent(dpy, ClientMessage, &xev)) {
; ;
} }
last_sendevent = 0;
} }
/* check for CUT_BUFFER0 and VNC_CONNECT changes: */ /* check for CUT_BUFFER0 and VNC_CONNECT changes: */
@ -7804,28 +7824,44 @@ void check_xevents(void) {
#define DEBUG_XEVENTS 1 #define DEBUG_XEVENTS 1
#endif #endif
#if DEBUG_XEVENTS #if DEBUG_XEVENTS
if (hack_val) { if (debug_xevents) {
static time_t last_check = 0; static time_t last_check = 0;
static time_t reminder = 0;
static int freq = 0;
if (! freq) {
if (getenv("X11VNC_REMINDER_RATE")) {
freq = atoi(getenv("X11VNC_REMINDER_RATE"));
} else {
freq = 300;
}
}
if (now > last_check + 1) { if (now > last_check + 1) {
int ev_max = 300, ev_size = 400;
XEvent xevs[400]; XEvent xevs[400];
int i, tot = XEventsQueued(dpy, QueuedAlready); int i, tot = XEventsQueued(dpy, QueuedAlready);
if (reminder == 0 || (tot && now > reminder + freq)) {
print_xevent_bases();
reminder = now;
}
last_check = now; last_check = now;
if (tot) { if (tot) {
fprintf(stderr, "Total events queued: %d\n", fprintf(stderr, "Total events queued: %d\n",
tot); tot);
} }
for (i=1; i<300; i++) { for (i=1; i<ev_max; i++) {
int k, n = 0; int k, n = 0;
while (XCheckTypedEvent(dpy, i, xevs+n)) { while (XCheckTypedEvent(dpy, i, xevs+n)) {
if (++n >= 400) { if (++n >= ev_size) {
break; break;
} }
} }
if (n) { if (n) {
fprintf(stderr, "%d events of type %d " fprintf(stderr, " %d events of type %d"
"queued\n", n, i); " queued\n", n, i);
} }
for (k=n-1; k >= 0; k--) { for (k=n-1; k >= 0; k--) {
XPutBackEvent(dpy, xevs+k); XPutBackEvent(dpy, xevs+k);
@ -7843,6 +7879,8 @@ void check_xevents(void) {
if (qlen >= bugout) { if (qlen >= bugout) {
rfbLog("event leak: %d queued, " rfbLog("event leak: %d queued, "
" calling XSync(dpy, True)\n", qlen); " calling XSync(dpy, True)\n", qlen);
rfbLog(" for diagnostics run: 'x11vnc -R"
" debug_xevents:1'\n");
XSync(dpy, True); XSync(dpy, True);
} }
} }
@ -10344,6 +10382,11 @@ char *process_remote_cmd(char *cmd, int stringonly) {
p += strlen("rawfb:"); p += strlen("rawfb:");
if (raw_fb_str) free(raw_fb_str); if (raw_fb_str) free(raw_fb_str);
raw_fb_str = strdup(p); raw_fb_str = strdup(p);
if (safe_remote_only && strstr(p, "setup:") == p) {
/* n.b. we still allow filename, shm, of rawfb */
fprintf(stderr, "unsafe rawfb setup: %s\n", p);
exit(1);
}
rfbLog("process_remote_cmd: setting -rawfb to:\n" rfbLog("process_remote_cmd: setting -rawfb to:\n"
"\t'%s'\n", p); "\t'%s'\n", p);
@ -10538,6 +10581,16 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("process_remote_cmd: disabling remote commands.\n"); rfbLog("process_remote_cmd: disabling remote commands.\n");
accept_remote_cmds = 0; /* cannot be turned back on. */ accept_remote_cmds = 0; /* cannot be turned back on. */
} else if (strstr(p, "debug_xevents:") == p) {
COLON_CHECK("debug_xevents:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xevents);
goto qry;
}
p += strlen("debug_xevents:");
debug_xevents = atoi(p);
rfbLog("set debug_xevents to: %d\n", debug_xevents);
} else if (strstr(p, "hack:") == p) { /* skip-cmd-list */ } else if (strstr(p, "hack:") == p) { /* skip-cmd-list */
COLON_CHECK("hack:") COLON_CHECK("hack:")
if (query) { if (query) {
@ -10640,6 +10693,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe)); snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe));
} else if (!strcmp(p, "threads")) { } else if (!strcmp(p, "threads")) {
snprintf(buf, bufn, "aro=%s:%d", p, use_threads); snprintf(buf, bufn, "aro=%s:%d", p, use_threads);
} else if (!strcmp(p, "pipeinput")) {
snprintf(buf, bufn, "aro=%s:%s", p,
NONUL(pipeinput_str));
} else if (!strcmp(p, "clients")) { } else if (!strcmp(p, "clients")) {
char *str = list_clients(); char *str = list_clients();
snprintf(buf, bufn, "aro=%s:%s", p, str); snprintf(buf, bufn, "aro=%s:%s", p, str);
@ -11064,7 +11120,7 @@ void check_xdamage_state(void) {
* Create or destroy the Damage object as needed, we don't want * Create or destroy the Damage object as needed, we don't want
* one if no clients are connected. * one if no clients are connected.
*/ */
if (client_count) { if (client_count && use_xdamage) {
create_xdamage_if_needed(); create_xdamage_if_needed();
} else { } else {
destroy_xdamage_if_needed(); destroy_xdamage_if_needed();
@ -13391,7 +13447,7 @@ XImage *initialize_raw_fb(void) {
int w, h, b, shmid = 0; int w, h, b, shmid = 0;
unsigned long rm = 0, gm = 0, bm = 0; unsigned long rm = 0, gm = 0, bm = 0;
static XImage ximage_struct; /* n.b.: not (XImage *) */ static XImage ximage_struct; /* n.b.: not (XImage *) */
int closedpy = 1; int closedpy = 1, i, m;
if (raw_fb_addr || raw_fb_seek) { if (raw_fb_addr || raw_fb_seek) {
if (raw_fb_shm) { if (raw_fb_shm) {
@ -13415,7 +13471,38 @@ XImage *initialize_raw_fb(void) {
} }
str = strdup(raw_fb_str); if ( (q = strstr(raw_fb_str, "setup:")) == raw_fb_str) {
FILE *pipe;
char line[1024], *t;
set_child_info();
q += strlen("setup:");
rfbLog("running command to setup rawfb: %s\n", q);
pipe = popen(q, "r");
if (! pipe) {
rfbLog("popen of setup command failed.\n");
rfbLogPerror("popen");
clean_up_exit(1);
}
line[0] = '\0';
if (fgets(line, 1024, pipe) == NULL) {
rfbLog("read of setup command failed.\n");
clean_up_exit(1);
}
pclose(pipe);
str = strdup(line);
t = str;
while (*t != '\0') {
if (*t == '\n') {
*t = '\0';
}
t++;
}
rfbLog("setup command returned: %s\n", str);
} else {
str = strdup(raw_fb_str);
}
/* /*
* uppercase means do not close the display (e.g. for remote control) * uppercase means do not close the display (e.g. for remote control)
@ -13480,12 +13567,12 @@ XImage *initialize_raw_fb(void) {
} }
} }
if ((q = strrchr(str, '@')) == NULL) { if ((q = strrchr(str, '@')) == NULL) {
rfbLog("invalid rawfb str: %s\n", raw_fb_str); rfbLog("invalid rawfb str: %s\n", str);
clean_up_exit(1); clean_up_exit(1);
} }
/* @WxHxB */ /* @WxHxB */
if (sscanf(q, "@%dx%dx%d", &w, &h, &b) != 3) { if (sscanf(q, "@%dx%dx%d", &w, &h, &b) != 3) {
rfbLog("invalid rawfb str: %s\n", raw_fb_str); rfbLog("invalid rawfb str: %s\n", str);
clean_up_exit(1); clean_up_exit(1);
} }
@ -13505,8 +13592,7 @@ XImage *initialize_raw_fb(void) {
/* shm:N */ /* shm:N */
raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY); raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY);
if (! raw_fb_addr) { if (! raw_fb_addr) {
rfbLog("failed to attach to shm: %d, %s\n", shmid, rfbLog("failed to attach to shm: %d, %s\n", shmid, str);
raw_fb_str);
rfbLogPerror("shmat"); rfbLogPerror("shmat");
clean_up_exit(1); clean_up_exit(1);
} }
@ -13528,7 +13614,7 @@ XImage *initialize_raw_fb(void) {
fd = open(q, O_RDONLY); fd = open(q, O_RDONLY);
if (fd < 0) { if (fd < 0) {
rfbLog("failed to open file: %s, %s\n", q, raw_fb_str); rfbLog("failed to open file: %s, %s\n", q, str);
rfbLogPerror("open"); rfbLogPerror("open");
clean_up_exit(1); clean_up_exit(1);
} }
@ -13549,8 +13635,7 @@ XImage *initialize_raw_fb(void) {
fd, 0); fd, 0);
if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) { if (raw_fb_addr == MAP_FAILED || raw_fb_addr == NULL) {
rfbLog("failed to mmap file: %s, %s\n", rfbLog("failed to mmap file: %s, %s\n", q, str);
q, raw_fb_str);
rfbLog(" raw_fb_addr: %p\n", raw_fb_addr); rfbLog(" raw_fb_addr: %p\n", raw_fb_addr);
rfbLogPerror("mmap"); rfbLogPerror("mmap");
clean_up_exit(1); clean_up_exit(1);
@ -13572,7 +13657,7 @@ XImage *initialize_raw_fb(void) {
rfbLog(" W: %d H: %d B: %d sz: %d\n", w, h, b, size); rfbLog(" W: %d H: %d B: %d sz: %d\n", w, h, b, size);
} }
} else { } else {
rfbLog("invalid rawfb str: %s\n", raw_fb_str); rfbLog("invalid rawfb str: %s\n", str);
clean_up_exit(1); clean_up_exit(1);
} }
@ -13580,14 +13665,15 @@ XImage *initialize_raw_fb(void) {
raw_fb_image = &ximage_struct; raw_fb_image = &ximage_struct;
} }
raw_fb = (char *) malloc(w*h*b/8); initialize_clipshift();
raw_fb = (char *) malloc(dpy_x * dpy_y * b/8);
raw_fb_image->data = raw_fb; raw_fb_image->data = raw_fb;
raw_fb_image->format = ZPixmap; raw_fb_image->format = ZPixmap;
raw_fb_image->width = w; raw_fb_image->width = dpy_x;
raw_fb_image->height = h; raw_fb_image->height = dpy_y;
raw_fb_image->bits_per_pixel = b; raw_fb_image->bits_per_pixel = b;
raw_fb_image->depth = (b == 32) ? 24 : b; raw_fb_image->bytes_per_line = dpy_x*b/8;
raw_fb_image->bytes_per_line = w*b/8;
if (rm == 0 && gm == 0 && bm == 0) { if (rm == 0 && gm == 0 && bm == 0) {
/* guess masks... */ /* guess masks... */
@ -13610,18 +13696,36 @@ XImage *initialize_raw_fb(void) {
raw_fb_image->green_mask = gm; raw_fb_image->green_mask = gm;
raw_fb_image->blue_mask = bm; raw_fb_image->blue_mask = bm;
if (raw_fb_addr) { raw_fb_image->depth = 0;
memcpy(raw_fb, raw_fb_addr + raw_fb_offset, w*h*(b/8)); m = 1;
for (i=0; i<32; i++) {
if (rm & m) {
raw_fb_image->depth++;
}
if (gm & m) {
raw_fb_image->depth++;
}
if (bm & m) {
raw_fb_image->depth++;
}
m = m << 1;
}
if (! raw_fb_image->depth) {
raw_fb_image->depth = (b == 32) ? 24 : b;
}
if (clipshift) {
memset(raw_fb, 0xff, dpy_x * dpy_y * b/8);
} else if (raw_fb_addr) {
memcpy(raw_fb, raw_fb_addr + raw_fb_offset, dpy_x*dpy_y*b/8);
} else { } else {
memset(raw_fb, 0xff, w*h*(b/8)); memset(raw_fb, 0xff, dpy_x * dpy_y * b/8);
} }
rfbLog("rawfb: raw_fb %p\n", raw_fb); rfbLog("rawfb: raw_fb %p\n", raw_fb);
free(str); free(str);
initialize_clipshift();
return raw_fb_image; return raw_fb_image;
} }
@ -16614,7 +16718,7 @@ void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force) {
if (damage_time != 0) { if (damage_time != 0) {
/* /*
* This is not XDAMAGE, rather a hack for testing * This is not XDAMAGE, rather a hack for testing
* were we allow the framebuffer to be corrupted for * where we allow the framebuffer to be corrupted for
* damage_delay seconds. * damage_delay seconds.
*/ */
int debug = 0; int debug = 0;
@ -20204,12 +20308,18 @@ static void print_help(int mode) {
"-rawfb string Experimental option, instead of polling X, poll the\n" "-rawfb string Experimental option, instead of polling X, poll the\n"
" memory object specified in \"string\". For shared\n" " memory object specified in \"string\". For shared\n"
" memory segments it is of the form: \"shm:N@WxHxB\"\n" " memory segments it is of the form: \"shm:N@WxHxB\"\n"
" which specifies a shmid N and framebuffer width, height,\n" " which specifies a shmid N and framebuffer Width, Height,\n"
" and bits per pixel. To memory map mmap(2) a file use:\n" " and Bits per pixel. To memory map mmap(2) a file use:\n"
" \"map:/path/to/a/file@WxHxB\". If there is trouble\n" " \"map:/path/to/a/file@WxHxB\". If there is trouble\n"
" with mmap, use \"file:/...\" for slower lseek(2) based\n" " with mmap, use \"file:/...\" for slower lseek(2) based\n"
" reading.\n" " reading.\n"
"\n" "\n"
" If string is \"setup:cmd\", then the command \"cmd\"\n"
" is run and the first line from it is read and used\n"
" as \"string\". This allows initializing the device,\n"
" determining WxHxB, etc. These are often done as root\n"
" so take care.\n"
"\n"
" Optional suffixes are \":R/G/B\" and \"+O\" to specify\n" " Optional suffixes are \":R/G/B\" and \"+O\" to specify\n"
" red, green, and blue masks and an offset into the\n" " red, green, and blue masks and an offset into the\n"
" memory object. If the masks are not provided x11vnc\n" " memory object. If the masks are not provided x11vnc\n"
@ -20229,17 +20339,18 @@ static void print_help(int mode) {
" before setting/changing them. If you don't want x11vnc\n" " before setting/changing them. If you don't want x11vnc\n"
" to close the DISPLAY in rawfb mode, then capitalize\n" " to close the DISPLAY in rawfb mode, then capitalize\n"
" the prefix, SHM:, MAP: etc. Keeping the display open\n" " the prefix, SHM:, MAP: etc. Keeping the display open\n"
" enables defautl remote control channel.\n" " enables default remote-control channel.\n"
"\n" "\n"
"-pipeinput cmd Another experimental option: it lets you supply an\n" "-pipeinput cmd Another experimental option: it lets you supply\n"
" extern command in \"cmd\" that x11vnc will pipe all of\n" " an extern command in \"cmd\" that x11vnc will pipe\n"
" the user input events to in a simple format. By default\n" " all of the user input events to in a simple format.\n"
" x11vnc will not process any of the user input events.\n" " In -pipeinput mode by default x11vnc will not process\n"
" If you prefix \"cmd\" with \"tee:\" it will both send\n" " any of the user input events. If you prefix \"cmd\"\n"
" them to the pipe command and process them. For a\n" " with \"tee:\" it will both send them to the pipe\n"
" description of the format run \"-pipeinput tee:cat\".\n" " command and process them. For a description of the\n"
" Another prefix is \"reopen\" which means to reopen pipe\n" " format run \"-pipeinput tee:/bin/cat\". Another prefix\n"
" if it exits. Separate multiple prefixes with commas.\n" " is \"reopen\" which means to reopen pipe if it exits.\n"
" Separate multiple prefixes with commas.\n"
"\n" "\n"
" In combination with -rawfb one might be able to\n" " In combination with -rawfb one might be able to\n"
" do amusing things (e.g. control non-X devices).\n" " do amusing things (e.g. control non-X devices).\n"
@ -20588,25 +20699,26 @@ static void print_help(int mode) {
" noxwarp noxwarppointer buttonmap dragging nodragging\n" " noxwarp noxwarppointer buttonmap dragging nodragging\n"
" pointer_mode pm input_skip input client_input speeds\n" " pointer_mode pm input_skip input client_input speeds\n"
" debug_pointer dp nodebug_pointer nodp debug_keyboard dk\n" " debug_pointer dp nodebug_pointer nodp debug_keyboard dk\n"
" nodebug_keyboard nodk deferupdate defer wait rfbwait\n" " nodebug_keyboard nodk deferupdate defer wait rfbwait nap\n"
" nap nonap sb screen_blank fs gaps grow fuzz snapfb\n" " nonap sb screen_blank fs gaps grow fuzz snapfb nosnapfb\n"
" nosnapfb rawfb progressive rfbport http nohttp httpport\n" " rawfb setup: progressive rfbport http nohttp httpport\n"
" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n" " httpdir enablehttpproxy noenablehttpproxy alwaysshared\n"
" noalwaysshared nevershared noalwaysshared dontdisconnect\n" " noalwaysshared nevershared noalwaysshared dontdisconnect\n"
" nodontdisconnect desktop noremote\n" " nodontdisconnect desktop noremote\n"
"\n" "\n"
" aro= display vncdisplay desktopname http_url auth\n" " aro= debug_xevents: display vncdisplay desktopname\n"
" users rootshift clipshift scale_str scaled_x scaled_y\n" " http_url auth users rootshift clipshift scale_str\n"
" scale_numer scale_denom scale_fac scaling_blend\n" " scaled_x scaled_y scale_numer scale_denom\n"
" scaling_nomult4 scaling_pad scaling_interpolate\n" " scale_fac scaling_blend scaling_nomult4 scaling_pad\n"
" inetd safer unsafe passwdfile using_shm logfile o\n" " scaling_interpolate inetd safer unsafe passwdfile\n"
" flag rc norc h help V version lastmod bg sigpipe\n" " using_shm logfile o flag rc norc h help V version\n"
" threads clients client_count pid ext_xtest ext_xtrap\n" " lastmod bg sigpipe threads pipeinput clients\n"
" ext_xkb ext_xshm ext_xinerama ext_overlay ext_xfixes\n" " client_count pid ext_xtest ext_xtrap ext_xkb ext_xshm\n"
" ext_xdamage ext_xrandr rootwin num_buttons button_mask\n" " ext_xinerama ext_overlay ext_xfixes ext_xdamage\n"
" mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y\n" " ext_xrandr rootwin num_buttons button_mask mouse_x\n"
" wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y\n" " mouse_y bpp depth indexed_color dpy_x dpy_y wdpy_x\n"
" rfbauth passwd\n" " wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth\n"
" passwd\n"
"\n" "\n"
"-sync By default -remote commands are run asynchronously, that\n" "-sync By default -remote commands are run asynchronously, that\n"
" is, the request is posted and the program immediately\n" " is, the request is posted and the program immediately\n"
@ -22215,6 +22327,10 @@ int main(int argc, char* argv[]) {
} else { } else {
xtest_present = 1; xtest_present = 1;
xtest_base_event_type = ev; xtest_base_event_type = ev;
if (maj <= 1 || (maj == 2 && min <= 2)) {
/* no events defined as of 2.2 */
xtest_base_event_type = 0;
}
} }
if (! XETrapQueryExtension_wr(dpy, &ev, &er, &maj)) { if (! XETrapQueryExtension_wr(dpy, &ev, &er, &maj)) {

Loading…
Cancel
Save