x11vnc -solid color, -opts; tightvnc unix viewer alpha patch

pull/1/head
runge 19 years ago
parent 914f7b71c5
commit 2bc615f6e0

@ -1,3 +1,8 @@
2005-02-05 Karl Runge <runge@karlrunge.com>
* x11vnc: -solid color, -opts/-?
* tightvnc-1.3dev5-vncviewer-alpha-cursor.patch: create, name
says it all.
2005-01-23 Karl Runge <runge@karlrunge.com> 2005-01-23 Karl Runge <runge@karlrunge.com>
* x11vnc: -timeout, -noalphablend. make -R norepeat work. * x11vnc: -timeout, -noalphablend. make -R norepeat work.
* sync with new draw cursor mechanism. * sync with new draw cursor mechanism.

@ -0,0 +1,143 @@
--- vnc_unixsrc.orig/vncviewer/cursor.c 2003-01-15 04:46:52.000000000 -0500
+++ vnc_unixsrc/vncviewer/cursor.c 2005-02-05 12:28:10.000000000 -0500
@@ -472,6 +472,140 @@
int offset, bytesPerPixel;
char *pos;
+#define alphahack
+#ifdef alphahack
+ /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */
+ static int alphablend = -1;
+
+ if (alphablend < 0) {
+ /* you have to set NO_ALPHABLEND=1 in your environment to disable */
+ if (getenv("NO_ALPHABLEND")) {
+ alphablend = 0;
+ } else {
+ alphablend = 1;
+ }
+ }
+
+ bytesPerPixel = myFormat.bitsPerPixel / 8;
+
+ if (alphablend && bytesPerPixel == 4) {
+ unsigned long pixel, put, *upos, *upix;
+ int got_alpha = 0, rsX, rsY, rsW, rsH;
+ static XImage *image = NULL;
+ static int iwidth = 128;
+
+ if (! image) {
+ /* watch out for tiny fb (rare) */
+ if (iwidth > si.framebufferWidth) {
+ iwidth = si.framebufferWidth;
+ }
+ if (iwidth > si.framebufferHeight) {
+ iwidth = si.framebufferHeight;
+ }
+
+ /* initialize an XImage with a chunk of desktopWin */
+ image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth,
+ AllPlanes, ZPixmap);
+ }
+
+ /* first check if there is any non-zero alpha channel data at all: */
+ for (y = 0; y < rcHeight; y++) {
+ for (x = 0; x < rcWidth; x++) {
+ int alpha;
+
+ offset = y * rcWidth + x;
+ pos = (char *)&rcSource[offset * bytesPerPixel];
+
+ upos = (unsigned long *) pos;
+ alpha = (*upos & 0xff000000) >> 24;
+ if (alpha) {
+ got_alpha = 1;
+ break;
+ }
+ }
+ if (got_alpha) {
+ break;
+ }
+ }
+
+ if (!got_alpha) {
+ /* no alpha channel data, fallback to the old way */
+ goto oldway;
+ }
+
+ /* load the saved fb patch in to image (faster way?) */
+ XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight,
+ AllPlanes, ZPixmap, image, 0, 0);
+ upix = (unsigned long *)image->data;
+
+ /* if the richcursor is clipped, the fb patch will be smaller */
+ rsW = rcWidth;
+ rsX = 0; /* used to denote a shift from the left side */
+ x = rcCursorX - rcHotX;
+ if (x < 0) {
+ rsW += x;
+ rsX = -x;
+ } else if (x + rsW > si.framebufferWidth) {
+ rsW = si.framebufferWidth - x;
+ }
+ rsH = rcHeight;
+ rsY = 0; /* used to denote a shift from the top side */
+ y = rcCursorY - rcHotY;
+ if (y < 0) {
+ rsH += y;
+ rsY = -y;
+ } else if (y + rsH > si.framebufferHeight) {
+ rsH = si.framebufferHeight - y;
+ }
+
+ /*
+ * now loop over the cursor data, blend in the fb values,
+ * and then overwrite the fb (CopyDataToScreen())
+ */
+ for (y = 0; y < rcHeight; y++) {
+ y0 = rcCursorY - rcHotY + y;
+ if (y0 < 0 || y0 >= si.framebufferHeight) {
+ continue; /* clipped */
+ }
+ for (x = 0; x < rcWidth; x++) {
+ int alpha, color_curs, color_fb, i;
+
+ x0 = rcCursorX - rcHotX + x;
+ if (x0 < 0 || x0 >= si.framebufferWidth) {
+ continue; /* clipped */
+ }
+
+ offset = y * rcWidth + x;
+ pos = (char *)&rcSource[offset * bytesPerPixel];
+
+ /* extract secret alpha byte from rich cursor: */
+ upos = (unsigned long *) pos;
+ alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */
+
+ /* extract the pixel from the fb: */
+ pixel = *(upix + (y-rsY)*iwidth + (x-rsX));
+
+ put = 0;
+ /* for simplicity, blend all 4 bytes */
+ for (i = 0; i < 4; i++) {
+ int sh = i*8;
+ color_curs = ((0xff << sh) & *upos) >> sh;
+ color_fb = ((0xff << sh) & pixel) >> sh;
+
+ /* XXX assumes pre-multipled color_curs */
+ color_fb = color_curs
+ + ((0xff - alpha) * color_fb)/0xff;
+ put |= color_fb << sh;
+ }
+ /* place in the fb: */
+ CopyDataToScreen((char *)&put, x0, y0, 1, 1);
+ }
+ }
+ return;
+ }
+oldway:
+#endif
+
bytesPerPixel = myFormat.bitsPerPixel / 8;
/* FIXME: Speed optimization is possible. */

@ -1,3 +1,7 @@
2005-02-05 Karl Runge <runge@karlrunge.com>
* -solid solid color background when clients are connected.
* -opts/-? to show option names only.
2005-01-23 Karl Runge <runge@karlrunge.com> 2005-01-23 Karl Runge <runge@karlrunge.com>
* sync with new draw cursor mechanism, keep old way in OLD_TREE. * sync with new draw cursor mechanism, keep old way in OLD_TREE.
* add -timeout option, change -alphablend to be default * add -timeout option, change -alphablend to be default

File diff suppressed because it is too large Load Diff

@ -120,6 +120,9 @@ Screen
=DP blackout: =DP blackout:
=D xinerama =D xinerama
-- --
solid
solid_color:
--
= xrandr = xrandr
=-C:resize,newfbsize,exit xrandr_mode: =-C:resize,newfbsize,exit xrandr_mode:
padgeom: padgeom:
@ -127,9 +130,9 @@ Screen
Keyboard Keyboard
norepeat norepeat
add_keysyms add_keysyms
skip_keycodes:
modtweak modtweak
xkb xkb
skip_keycodes:
-- --
=FP remap: =FP remap:
-- --
@ -320,6 +323,10 @@ Shows a menu of currently connected VNC clients on the x11vnc server.
Allows you to find more information about them or disconnect them. Allows you to find more information about them or disconnect them.
You will be prompted to confirm any disconnections. You will be prompted to confirm any disconnections.
"
set helptext(solid_color) "
Set the -solid color value.
" "
set helptext(xrandr_mode) " set helptext(xrandr_mode) "
@ -390,7 +397,7 @@ will be \"(*none*)\" when there is no connection established.
4) Below the x11 and vnc displays text label is a text area there scrolling 4) Below the x11 and vnc displays text label is a text area there scrolling
information about actions being taken and commands being run is displayed. information about actions being taken and commands being run is displayed.
To scroll use PageUp/PageDown or the arrow keys. To scroll click in the area and use PageUp/PageDown or the arrow keys.
5) At the bottom is an entry area. When one selects a menu item that 5) At the bottom is an entry area. When one selects a menu item that
requires supplying a string value, the label will be set to the requires supplying a string value, the label will be set to the
@ -2319,6 +2326,8 @@ proc get_start_x11vnc_cmd {{show_rc 0}} {
set nitem "sb" set nitem "sb"
} elseif {$nitem == "xrandr_mode"} { } elseif {$nitem == "xrandr_mode"} {
set nitem "xrandr" set nitem "xrandr"
} elseif {$nitem == "solid_color"} {
set nitem "solid"
} }
lappend cmd "-$nitem" lappend cmd "-$nitem"
lappend cmd $menu_var($item) lappend cmd $menu_var($item)

@ -126,6 +126,9 @@
" =DP blackout:\n" " =DP blackout:\n"
" =D xinerama\n" " =D xinerama\n"
" --\n" " --\n"
" solid\n"
" solid_color:\n"
" --\n"
" = xrandr\n" " = xrandr\n"
" =-C:resize,newfbsize,exit xrandr_mode:\n" " =-C:resize,newfbsize,exit xrandr_mode:\n"
" padgeom:\n" " padgeom:\n"
@ -133,9 +136,9 @@
"Keyboard\n" "Keyboard\n"
" norepeat\n" " norepeat\n"
" add_keysyms\n" " add_keysyms\n"
" skip_keycodes:\n"
" modtweak\n" " modtweak\n"
" xkb\n" " xkb\n"
" skip_keycodes:\n"
" --\n" " --\n"
" =FP remap:\n" " =FP remap:\n"
" --\n" " --\n"
@ -328,6 +331,10 @@
"You will be prompted to confirm any disconnections.\n" "You will be prompted to confirm any disconnections.\n"
"\"\n" "\"\n"
"\n" "\n"
" set helptext(solid_color) \"\n"
"Set the -solid color value.\n"
"\"\n"
"\n"
" set helptext(xrandr_mode) \"\n" " set helptext(xrandr_mode) \"\n"
"Set the -xrandr mode value.\n" "Set the -xrandr mode value.\n"
"\"\n" "\"\n"
@ -396,7 +403,7 @@
"\n" "\n"
"4) Below the x11 and vnc displays text label is a text area there scrolling\n" "4) Below the x11 and vnc displays text label is a text area there scrolling\n"
"information about actions being taken and commands being run is displayed.\n" "information about actions being taken and commands being run is displayed.\n"
"To scroll use PageUp/PageDown or the arrow keys.\n" "To scroll click in the area and use PageUp/PageDown or the arrow keys.\n"
"\n" "\n"
"5) At the bottom is an entry area. When one selects a menu item that\n" "5) At the bottom is an entry area. When one selects a menu item that\n"
"requires supplying a string value, the label will be set to the\n" "requires supplying a string value, the label will be set to the\n"
@ -2325,6 +2332,8 @@
" set nitem \"sb\"\n" " set nitem \"sb\"\n"
" } elseif {$nitem == \"xrandr_mode\"} {\n" " } elseif {$nitem == \"xrandr_mode\"} {\n"
" set nitem \"xrandr\"\n" " set nitem \"xrandr\"\n"
" } elseif {$nitem == \"solid_color\"} {\n"
" set nitem \"solid\"\n"
" }\n" " }\n"
" lappend cmd \"-$nitem\"\n" " lappend cmd \"-$nitem\"\n"
" lappend cmd $menu_var($item)\n" " lappend cmd $menu_var($item)\n"

@ -1,8 +1,8 @@
.\" This file was automatically generated from x11vnc -help output. .\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "January 2005" "x11vnc " "User Commands" .TH X11VNC "1" "February 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.1pre, lastmod: 2005-01-23 version: 0.7.1pre, lastmod: 2005-02-05
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
@ -351,6 +351,22 @@ Do not use the new copy_tiles() framebuffer mechanism,
just use 1 shm tile for polling. Limits shm segments just use 1 shm tile for polling. Limits shm segments
used to 3. used to 3.
.PP .PP
\fB-solid\fR \fI[color]\fR
.IP
To improve performance, when VNC clients are connected
try to change the desktop background to a solid color.
The [color] is optional: the default color is "cyan4".
For a different one specify the X color (rgb.txt name,
e.g. "darkblue" or numerical "#RRGGBB"). Currently
this option only works on GNOME, KDE, and classic X
(i.e. with the background image on the root window).
The "gconftool-2" and "dcop" external commands are
run for GNOME and KDE respectively. Other desktops
won't work, e.g. XFCE (send us the corresponding
commands if you find them). If x11vnc guesses your
desktop incorrectly, you can force it by prefixing
color with "gnome:", "kde:", or "root:".
.PP
\fB-blackout\fR \fIstring\fR \fB-blackout\fR \fIstring\fR
.IP .IP
Black out rectangles on the screen. \fIstring\fR is a Black out rectangles on the screen. \fIstring\fR is a
@ -426,6 +442,7 @@ Do not process any .x11vncrc file for options.
\fB-h,\fR \fB-help\fR \fB-h,\fR \fB-help\fR
.IP .IP
Print this help text. Print this help text.
-?, \fB-opts\fR Only list the x11vnc options.
.PP .PP
\fB-V,\fR \fB-version\fR \fB-V,\fR \fB-version\fR
.IP .IP
@ -764,11 +781,11 @@ pointer events). Also note that these modes are not
available in \fB-threads\fR mode which has its own pointer available in \fB-threads\fR mode which has its own pointer
event handling mechanism. event handling mechanism.
.IP .IP
To try out the different pointer modes to see To try out the different pointer modes to see which
which one gives the best response for your usage, one gives the best response for your usage, it is
it is convenient to use the remote control function, convenient to use the remote control function, for
e.g. "x11vnc \fB-R\fR pointer_mode:4" or the tcl/tk gui example "x11vnc \fB-R\fR pm:4" or the tcl/tk gui (Tuning ->
(Tuning -> pointer_mode -> n). pointer_mode -> n).
.PP .PP
\fB-input_skip\fR \fIn\fR \fB-input_skip\fR \fIn\fR
.IP .IP
@ -1065,6 +1082,12 @@ onetile enable \fB-onetile\fR mode. (you may need to
.IP .IP
noonetile disable \fB-onetile\fR mode. noonetile disable \fB-onetile\fR mode.
.IP .IP
solid enable \fB-solid\fR mode
.IP
nosolid disable \fB-solid\fR mode.
.IP
solid_color:color set \fB-solid\fR color (and apply it).
.IP
blackout:str set \fB-blackout\fR "str" (empty to disable). blackout:str set \fB-blackout\fR "str" (empty to disable).
See \fB-blackout\fR for the form of "str" See \fB-blackout\fR for the form of "str"
(basically: WxH+X+Y,...) (basically: WxH+X+Y,...)
@ -1130,8 +1153,6 @@ bell enable bell (if supported).
.IP .IP
nobell disable bell. nobell disable bell.
.IP .IP
bell enable bell (if supported).
.IP
nosel enable \fB-nosel\fR mode. nosel enable \fB-nosel\fR mode.
.IP .IP
sel disable \fB-nosel\fR mode. sel disable \fB-nosel\fR mode.
@ -1315,17 +1336,18 @@ refresh reset close disconnect id sid waitmapped
nowaitmapped flashcmap noflashcmap truecolor notruecolor nowaitmapped flashcmap noflashcmap truecolor notruecolor
overlay nooverlay overlay_cursor overlay_yescursor overlay nooverlay overlay_cursor overlay_yescursor
nooverlay_nocursor nooverlay_cursor nooverlay_yescursor nooverlay_nocursor nooverlay_cursor nooverlay_yescursor
overlay_nocursor visual scale viewonly noviewonly shared overlay_nocursor visual scale viewonly noviewonly
noshared forever noforever once timeout deny lock nodeny shared noshared forever noforever once timeout deny
unlock connect allowonce allow localhost nolocalhost lock nodeny unlock connect allowonce allow localhost
accept gone shm noshm flipbyteorder noflipbyteorder nolocalhost accept gone shm noshm flipbyteorder
onetile noonetile blackout xinerama noxinerama xrandr noflipbyteorder onetile noonetile solid_color solid
noxrandr xrandr_mode padgeom quiet q noquiet modtweak nosolid blackout xinerama noxinerama xrandr noxrandr
nomodtweak xkb noxkb skip_keycodes add_keysyms xrandr_mode padgeom quiet q noquiet modtweak nomodtweak
noadd_keysyms clear_mods noclear_mods clear_keys xkb noxkb skip_keycodes add_keysyms noadd_keysyms
noclear_keys remap repeat norepeat fb nofb bell nobell clear_mods noclear_mods clear_keys noclear_keys
sel nosel primary noprimary cursorshape nocursorshape remap repeat norepeat fb nofb bell nobell sel nosel
cursorpos nocursorpos cursor show_cursor noshow_cursor primary noprimary cursorshape nocursorshape cursorpos
nocursorpos cursor show_cursor noshow_cursor
nocursor xfixes noxfixes alphacut alphafrac nocursor xfixes noxfixes alphacut alphafrac
alpharemove noalpharemove alphablend noalphablend alpharemove noalpharemove alphablend noalphablend
xwarp xwarppointer noxwarp noxwarppointer buttonmap xwarp xwarppointer noxwarp noxwarppointer buttonmap

@ -273,7 +273,7 @@ static int xdamage_base_event_type;
#endif #endif
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.7.1pre lastmod: 2005-01-23"; char lastmod[] = "0.7.1pre lastmod: 2005-02-05";
/* X display info */ /* X display info */
@ -402,6 +402,7 @@ void close_clients(char *);
void autorepeat(int restore); void autorepeat(int restore);
char *bitprint(unsigned int, int); char *bitprint(unsigned int, int);
void blackout_tiles(void); void blackout_tiles(void);
void solid_bg(int);
void check_connect_inputs(void); void check_connect_inputs(void);
void check_padded_fb(void); void check_padded_fb(void);
void clean_up_exit(int); void clean_up_exit(int);
@ -526,6 +527,9 @@ char *logfile = NULL;
int logfile_append = 0; int logfile_append = 0;
char *passwdfile = NULL; char *passwdfile = NULL;
char *blackout_str = NULL; char *blackout_str = NULL;
int use_solid_bg = 0;
char *solid_str = NULL;
char *solid_default = "cyan4";
char *speeds_str = NULL; char *speeds_str = NULL;
int measure_speeds = 1; int measure_speeds = 1;
@ -1340,6 +1344,9 @@ void clean_up_exit (int ret) {
if (no_autorepeat) { if (no_autorepeat) {
autorepeat(1); autorepeat(1);
} }
if (use_solid_bg) {
solid_bg(1);
}
X_LOCK; X_LOCK;
XTestDiscard_wr(dpy); XTestDiscard_wr(dpy);
XCloseDisplay(dpy); XCloseDisplay(dpy);
@ -1390,6 +1397,9 @@ static void interrupted (int sig) {
if (no_autorepeat) { if (no_autorepeat) {
autorepeat(1); autorepeat(1);
} }
if (use_solid_bg) {
solid_bg(1);
}
if (sig) { if (sig) {
exit(2); exit(2);
@ -1803,6 +1813,9 @@ static void client_gone(rfbClientPtr client) {
if (no_autorepeat && client_count == 0) { if (no_autorepeat && client_count == 0) {
autorepeat(1); autorepeat(1);
} }
if (use_solid_bg && client_count == 0) {
solid_bg(1);
}
if (gone_cmd && *gone_cmd != '\0') { if (gone_cmd && *gone_cmd != '\0') {
rfbLog("client_gone: using cmd for: %s\n", client->host); rfbLog("client_gone: using cmd for: %s\n", client->host);
run_user_command(gone_cmd, client, "gone"); run_user_command(gone_cmd, client, "gone");
@ -2830,6 +2843,9 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
/* first client, turn off X server autorepeat */ /* first client, turn off X server autorepeat */
autorepeat(0); autorepeat(0);
} }
if (use_solid_bg && client_count == 1) {
solid_bg(0);
}
if (pad_geometry) { if (pad_geometry) {
install_padded_fb(pad_geometry); install_padded_fb(pad_geometry);
@ -6740,6 +6756,62 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} }
single_copytile = 0; single_copytile = 0;
} else if (strstr(p, "solid_color") == p) {
char *new;
int doit = 1;
COLON_CHECK("solid_color:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%s", p, co,
NONUL(solid_str));
goto qry;
}
p += strlen("solid_color:");
if (*p != '\0') {
new = strdup(p);
} else {
new = strdup(solid_default);
}
rfbLog("process_remote_cmd: solid %s -> %s\n",
NONUL(solid_str), new);
if (solid_str) {
if (!strcmp(solid_str, new)) {
doit = 0;
}
free(solid_str);
}
solid_str = new;
use_solid_bg = 1;
if (doit && client_count) {
solid_bg(0);
}
} else if (!strcmp(p, "solid")) {
int orig = use_solid_bg;
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, use_solid_bg);
goto qry;
}
rfbLog("process_remote_cmd: enable -solid mode\n");
if (! solid_str) {
solid_str = strdup(solid_default);
}
use_solid_bg = 1;
if (client_count && !orig) {
solid_bg(0);
}
} else if (!strcmp(p, "nosolid")) {
int orig = use_solid_bg;
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !use_solid_bg);
goto qry;
}
rfbLog("process_remote_cmd: disable -solid mode\n");
use_solid_bg = 0;
if (client_count && orig) {
solid_bg(1);
}
} else if (strstr(p, "blackout") == p) { } else if (strstr(p, "blackout") == p) {
char *before, *old; char *before, *old;
COLON_CHECK("blackout:") COLON_CHECK("blackout:")
@ -10581,6 +10653,325 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
} }
} }
/* -- solid.c -- */
int do_cmd(char *cmd) {
int rc;
if (!cmd || *cmd == '\0') {
return 0;
}
rfbLog("running command:\n %s\n", cmd);
rc = system(cmd);
if (rc >= 256) {
rc = rc/256;
}
return rc;
}
char *cmd_output(char *cmd) {
FILE *p;
static char output[50000];
char line[1024];
int rc;
rfbLog("running pipe:\n %s\n", cmd);
p = popen(cmd, "r");
output[0] = '\0';
while (fgets(line, 1024, p) != NULL) {
if (strlen(output) + strlen(line) + 1 < 50000) {
strcat(output, line);
}
}
rc = pclose(p);
return(output);
}
void solid_root(char *color) {
Window expose;
static XImage *image = NULL;
Pixmap pixmap;
XGCValues gcv;
GC gc;
XSetWindowAttributes swa;
Visual visual;
unsigned long mask, pixel;
XColor cdef;
Colormap cmap;
if (subwin || window != rootwin) {
rfbLog("cannot set subwin to solid color, must be root\n");
return;
}
/* create the "clear" window just for generating exposures */
swa.override_redirect = True;
swa.backing_store = NotUseful;
swa.save_under = False;
swa.background_pixmap = None;
visual.visualid = CopyFromParent;
mask = (CWOverrideRedirect|CWBackingStore|CWSaveUnder|CWBackPixmap);
expose = XCreateWindow(dpy, window, 0, 0, dpy_x, dpy_y, 0, depth,
InputOutput, &visual, mask, &swa);
if (! color) {
/* restore the root window from the XImage snapshot */
pixmap = XCreatePixmap(dpy, window, dpy_x, dpy_y, depth);
if (! image) {
/* whoops */
XDestroyWindow(dpy, expose);
rfbLog("no root snapshot available.\n");
return;
}
/* draw the image to a pixmap: */
gcv.function = GXcopy;
gcv.plane_mask = AllPlanes;
gc = XCreateGC(dpy, window, GCFunction|GCPlaneMask, &gcv);
XPutImage(dpy, pixmap, gc, image, 0, 0, 0, 0, dpy_x, dpy_y);
gcv.foreground = gcv.background = BlackPixel(dpy, scr);
gc = XCreateGC(dpy, window, GCForeground|GCBackground, &gcv);
rfbLog("restoring root snapshot...\n");
/* set the pixmap as the bg: */
XSetWindowBackgroundPixmap(dpy, window, pixmap);
XFreePixmap(dpy, pixmap);
XClearWindow(dpy, window);
XFlush(dpy);
/* generate exposures */
XMapWindow(dpy, expose);
XSync(dpy, False);
XDestroyWindow(dpy, expose);
return;
}
if (! image) {
/* need to retrieve a snapshot of the root background: */
Window iwin;
XSetWindowAttributes iswa;
/* create image window: */
iswa.override_redirect = True;
iswa.backing_store = NotUseful;
iswa.save_under = False;
iswa.background_pixmap = None;
iswa.background_pixmap = ParentRelative;
iwin = XCreateWindow(dpy, window, 0, 0, dpy_x, dpy_y, 0, depth,
InputOutput, &visual, mask, &iswa);
rfbLog("snapshotting background...\n");
XMapWindow(dpy, iwin);
XSync(dpy, False);
image = XGetImage(dpy, iwin, 0, 0, dpy_x, dpy_y, AllPlanes,
ZPixmap);
XSync(dpy, False);
XDestroyWindow(dpy, iwin);
}
/* use black for low colors or failure */
pixel = BlackPixel(dpy, scr);
if (depth > 8 || strcmp(color, solid_default)) {
cmap = DefaultColormap (dpy, scr);
if (XParseColor(dpy, cmap, color, &cdef) &&
XAllocColor(dpy, cmap, &cdef)) {
pixel = cdef.pixel;
} else {
rfbLog("error parsing/allocing color: %s\n", color);
}
}
rfbLog("setting solid background...\n");
XSetWindowBackground(dpy, window, pixel);
XMapWindow(dpy, expose);
XSync(dpy, False);
XDestroyWindow(dpy, expose);
}
void solid_gnome(char *color) {
char get_color[] = "gconftool-2 --get "
"/desktop/gnome/background/primary_color";
char set_color[] = "gconftool-2 --set "
"/desktop/gnome/background/primary_color --type string '%s'";
char get_option[] = "gconftool-2 --get "
"/desktop/gnome/background/picture_options";
char set_option[] = "gconftool-2 --set "
"/desktop/gnome/background/picture_options --type string '%s'";
static char *orig_color = NULL;
static char *orig_option = NULL;
char *cmd;
if (! color) {
if (! orig_color) {
orig_color = strdup("#FFFFFF");
}
if (! orig_option) {
orig_option = strdup("stretched");
}
if (strstr(orig_color, "'") != NULL) {
rfbLog("bad color: %s\n", orig_color);
return;
}
if (strstr(orig_option, "'") != NULL) {
rfbLog("bad option: %s\n", orig_option);
return;
}
cmd = (char *)malloc(strlen(set_option) - 2 +
strlen(orig_option) + 1);
sprintf(cmd, set_option, orig_option);
do_cmd(cmd);
free(cmd);
cmd = (char *)malloc(strlen(set_color) - 2 +
strlen(orig_color) + 1);
sprintf(cmd, set_color, orig_color);
do_cmd(cmd);
free(cmd);
return;
}
if (! orig_color) {
char *q;
orig_color = strdup(cmd_output(get_color));
if (*orig_color == '\0') {
orig_color = strdup("#FFFFFF");
}
if ((q = strchr(orig_color, '\n')) != NULL) {
*q = '\0';
}
}
if (! orig_option) {
char *q;
orig_option = strdup(cmd_output(get_option));
if (*orig_option == '\0') {
orig_option = strdup("stretched");
}
if ((q = strchr(orig_option, '\n')) != NULL) {
*q = '\0';
}
}
if (strstr(color, "'") != NULL) {
rfbLog("bad color: %s\n", color);
return;
}
cmd = (char *)malloc(strlen(set_color) - 2 + strlen(color) + 1);
sprintf(cmd, set_color, color);
do_cmd(cmd);
free(cmd);
cmd = (char *)malloc(strlen(set_option) - 2 + strlen("none") + 1);
sprintf(cmd, set_option, "none");
do_cmd(cmd);
free(cmd);
}
void solid_kde(char *color) {
char set_color[] = "dcop kdesktop KBackgroundIface setColor '%s' 1";
char bg_off[] = "dcop kdesktop KBackgroundIface setBackgroundEnabled 0";
char bg_on[] = "dcop kdesktop KBackgroundIface setBackgroundEnabled 1";
char *cmd;
if (! color) {
do_cmd(bg_on);
return;
}
if (strstr(color, "'") != NULL) {
rfbLog("bad color: %s\n", color);
return;
}
cmd = (char *)malloc(strlen(set_color) - 2 + strlen(color) + 1);
sprintf(cmd, set_color, color);
do_cmd(cmd);
do_cmd(bg_off);
free(cmd);
}
char *guess_desktop() {
Atom prop;
prop = XInternAtom(dpy, "_QT_DESKTOP_PROPERTIES", True);
if (prop != None) {
return "kde";
}
prop = XInternAtom(dpy, "NAUTILUS_DESKTOP_WINDOW_ID", True);
if (prop != None) {
return "gnome";
}
return "root";
}
void solid_bg(int restore) {
static int desktop = -1;
static int solid_on = 0;
static char *prev_str;
char *dtname, *color;
if (restore) {
if (! solid_on) {
return;
}
if (desktop == 0) {
solid_root(NULL);
} else if (desktop == 1) {
solid_gnome(NULL);
} else if (desktop == 2) {
solid_kde(NULL);
}
solid_on = 0;
return;
}
if (! solid_str) {
return;
}
if (solid_on && !strcmp(prev_str, solid_str)) {
return;
}
if (strstr(solid_str, "guess:") == solid_str
|| !strchr(solid_str, ':')) {
dtname = guess_desktop();
rfbLog("guessed desktop: %s\n", dtname);
} else {
if (strstr(solid_str, "gnome:") == solid_str) {
dtname = "gnome";
} else if (strstr(solid_str, "kde:") == solid_str) {
dtname = "kde";
} else {
dtname = "root";
}
}
color = strchr(solid_str, ':');
if (! color) {
color = solid_str;
} else {
color++;
if (*color == '\0') {
color = solid_default;
}
}
if (!strcmp(dtname, "gnome")) {
desktop = 1;
solid_gnome(color);
} else if (!strcmp(dtname, "kde")) {
desktop = 2;
solid_kde(color);
} else {
desktop = 0;
solid_root(color);
}
if (prev_str) {
free(prev_str);
}
prev_str = strdup(solid_str);
solid_on = 1;
}
/* -- xinerama.c -- */ /* -- xinerama.c -- */
/* /*
* routines related to xinerama and blacking out rectangles * routines related to xinerama and blacking out rectangles
@ -14457,7 +14848,7 @@ static void watch_loop(void) {
/* /*
* text printed out under -help option * text printed out under -help option
*/ */
static void print_help(void) { static void print_help(int mode) {
char help[] = char help[] =
"\n" "\n"
"x11vnc: allow VNC connections to real X11 displays. %s\n" "x11vnc: allow VNC connections to real X11 displays. %s\n"
@ -14706,6 +15097,19 @@ static void print_help(void) {
" just use 1 shm tile for polling. Limits shm segments\n" " just use 1 shm tile for polling. Limits shm segments\n"
" used to 3.\n" " used to 3.\n"
"\n" "\n"
"-solid [color] To improve performance, when VNC clients are connected\n"
" try to change the desktop background to a solid color.\n"
" The [color] is optional: the default color is \"cyan4\".\n"
" For a different one specify the X color (rgb.txt name,\n"
" e.g. \"darkblue\" or numerical \"#RRGGBB\"). Currently\n"
" this option only works on GNOME, KDE, and classic X\n"
" (i.e. with the background image on the root window).\n"
" The \"gconftool-2\" and \"dcop\" external commands are\n"
" run for GNOME and KDE respectively. Other desktops\n"
" won't work, e.g. XFCE (send us the corresponding\n"
" commands if you find them). If x11vnc guesses your\n"
" desktop incorrectly, you can force it by prefixing\n"
" color with \"gnome:\", \"kde:\", or \"root:\".\n"
"-blackout string Black out rectangles on the screen. \"string\" is a\n" "-blackout string Black out rectangles on the screen. \"string\" is a\n"
" comma separated list of WxH+X+Y type geometries for\n" " comma separated list of WxH+X+Y type geometries for\n"
" each rectangle.\n" " each rectangle.\n"
@ -14758,6 +15162,7 @@ static void print_help(void) {
"-rc filename Use \"filename\" instead of $HOME/.x11vncrc for rc file.\n" "-rc filename Use \"filename\" instead of $HOME/.x11vncrc for rc file.\n"
"-norc Do not process any .x11vncrc file for options.\n" "-norc Do not process any .x11vncrc file for options.\n"
"-h, -help Print this help text.\n" "-h, -help Print this help text.\n"
"-?, -opts Only list the x11vnc options.\n"
"-V, -version Print program version (last modification date).\n" "-V, -version Print program version (last modification date).\n"
"\n" "\n"
"-q Be quiet by printing less informational output to\n" "-q Be quiet by printing less informational output to\n"
@ -15024,11 +15429,11 @@ static void print_help(void) {
" available in -threads mode which has its own pointer\n" " available in -threads mode which has its own pointer\n"
" event handling mechanism.\n" " event handling mechanism.\n"
"\n" "\n"
" To try out the different pointer modes to see\n" " To try out the different pointer modes to see which\n"
" which one gives the best response for your usage,\n" " one gives the best response for your usage, it is\n"
" it is convenient to use the remote control function,\n" " convenient to use the remote control function, for\n"
" e.g. \"x11vnc -R pointer_mode:4\" or the tcl/tk gui\n" " example \"x11vnc -R pm:4\" or the tcl/tk gui (Tuning ->\n"
" (Tuning -> pointer_mode -> n).\n" " pointer_mode -> n).\n"
"\n" "\n"
"-input_skip n For the pointer handling when non-threaded: try to\n" "-input_skip n For the pointer handling when non-threaded: try to\n"
" read n user input events before scanning display. n < 0\n" " read n user input events before scanning display. n < 0\n"
@ -15239,6 +15644,9 @@ static void print_help(void) {
" onetile enable -onetile mode. (you may need to\n" " onetile enable -onetile mode. (you may need to\n"
" set shm for this to do something)\n" " set shm for this to do something)\n"
" noonetile disable -onetile mode.\n" " noonetile disable -onetile mode.\n"
" solid enable -solid mode\n"
" nosolid disable -solid mode.\n"
" solid_color:color set -solid color (and apply it).\n"
" blackout:str set -blackout \"str\" (empty to disable).\n" " blackout:str set -blackout \"str\" (empty to disable).\n"
" See -blackout for the form of \"str\"\n" " See -blackout for the form of \"str\"\n"
" (basically: WxH+X+Y,...)\n" " (basically: WxH+X+Y,...)\n"
@ -15277,7 +15685,6 @@ static void print_help(void) {
" fb disable -nofb mode.\n" " fb disable -nofb mode.\n"
" bell enable bell (if supported).\n" " bell enable bell (if supported).\n"
" nobell disable bell.\n" " nobell disable bell.\n"
" bell enable bell (if supported).\n"
" nosel enable -nosel mode.\n" " nosel enable -nosel mode.\n"
" sel disable -nosel mode.\n" " sel disable -nosel mode.\n"
" noprimary enable -noprimary mode.\n" " noprimary enable -noprimary mode.\n"
@ -15385,17 +15792,18 @@ static void print_help(void) {
" nowaitmapped flashcmap noflashcmap truecolor notruecolor\n" " nowaitmapped flashcmap noflashcmap truecolor notruecolor\n"
" overlay nooverlay overlay_cursor overlay_yescursor\n" " overlay nooverlay overlay_cursor overlay_yescursor\n"
" nooverlay_nocursor nooverlay_cursor nooverlay_yescursor\n" " nooverlay_nocursor nooverlay_cursor nooverlay_yescursor\n"
" overlay_nocursor visual scale viewonly noviewonly shared\n" " overlay_nocursor visual scale viewonly noviewonly\n"
" noshared forever noforever once timeout deny lock nodeny\n" " shared noshared forever noforever once timeout deny\n"
" unlock connect allowonce allow localhost nolocalhost\n" " lock nodeny unlock connect allowonce allow localhost\n"
" accept gone shm noshm flipbyteorder noflipbyteorder\n" " nolocalhost accept gone shm noshm flipbyteorder\n"
" onetile noonetile blackout xinerama noxinerama xrandr\n" " noflipbyteorder onetile noonetile solid_color solid\n"
" noxrandr xrandr_mode padgeom quiet q noquiet modtweak\n" " nosolid blackout xinerama noxinerama xrandr noxrandr\n"
" nomodtweak xkb noxkb skip_keycodes add_keysyms\n" " xrandr_mode padgeom quiet q noquiet modtweak nomodtweak\n"
" noadd_keysyms clear_mods noclear_mods clear_keys\n" " xkb noxkb skip_keycodes add_keysyms noadd_keysyms\n"
" noclear_keys remap repeat norepeat fb nofb bell nobell\n" " clear_mods noclear_mods clear_keys noclear_keys\n"
" sel nosel primary noprimary cursorshape nocursorshape\n" " remap repeat norepeat fb nofb bell nobell sel nosel\n"
" cursorpos nocursorpos cursor show_cursor noshow_cursor\n" " primary noprimary cursorshape nocursorshape cursorpos\n"
" nocursorpos cursor show_cursor noshow_cursor\n"
" nocursor xfixes noxfixes alphacut alphafrac\n" " nocursor xfixes noxfixes alphacut alphafrac\n"
" alpharemove noalpharemove alphablend noalphablend\n" " alpharemove noalpharemove alphablend noalphablend\n"
" xwarp xwarppointer noxwarp noxwarppointer buttonmap\n" " xwarp xwarppointer noxwarp noxwarppointer buttonmap\n"
@ -15473,6 +15881,31 @@ static void print_help(void) {
; ;
/* have both our help and rfbUsage to stdout for more(1), etc. */ /* have both our help and rfbUsage to stdout for more(1), etc. */
dup2(1, 2); dup2(1, 2);
if (mode == 1) {
char *p;
int l = 0;
fprintf(stderr, "x11vnc: allow VNC connections to real "
"X11 displays. %s\n\nx11vnc options:\n", lastmod);
p = strtok(help, "\n");
while (p) {
int w = 23;
char tmp[100];
if (p[0] == '-') {
strncpy(tmp, p, w);
fprintf(stderr, " %s", tmp);
l++;
if (l % 2 == 0) {
fprintf(stderr, "\n");
}
}
p = strtok(NULL, "\n");
}
fprintf(stderr, "\n\nlibvncserver options:\n");
rfbUsage();
fprintf(stderr, "\n");
exit(1);
}
fprintf(stderr, help, lastmod, fprintf(stderr, help, lastmod,
view_only ? "on":"off", view_only ? "on":"off",
shared ? "on":"off", shared ? "on":"off",
@ -15503,6 +15936,9 @@ static void print_help(void) {
void set_vnc_desktop_name(void) { void set_vnc_desktop_name(void) {
int sz = 256; int sz = 256;
sprintf(vnc_desktop_name, "unknown"); sprintf(vnc_desktop_name, "unknown");
if (inetd) {
sprintf(vnc_desktop_name, "inetd-no-further-clients");
}
if (screen->port) { if (screen->port) {
char *host = this_host(); char *host = this_host();
int lport = screen->port; int lport = screen->port;
@ -15827,6 +16263,8 @@ int main(int argc, char* argv[]) {
argv_vnc[0] = strdup(argv[0]); argv_vnc[0] = strdup(argv[0]);
program_name = strdup(argv[0]); program_name = strdup(argv[0]);
solid_default = strdup(solid_default); /* for freeing with -R */
len = 0; len = 0;
for (i=1; i < argc; i++) { for (i=1; i < argc; i++) {
len += strlen(argv[i]) + 4 + 1; len += strlen(argv[i]) + 4 + 1;
@ -15970,6 +16408,18 @@ int main(int argc, char* argv[]) {
flip_byte_order = 1; flip_byte_order = 1;
} else if (!strcmp(arg, "-onetile")) { } else if (!strcmp(arg, "-onetile")) {
single_copytile = 1; single_copytile = 1;
} else if (!strcmp(arg, "-solid")) {
use_solid_bg = 1;
if (i < argc-1) {
char *s = argv[i+1];
if (s[0] != '-') {
solid_str = strdup(s);
i++;
}
}
if (! solid_str) {
solid_str = strdup(solid_default);
}
} else if (!strcmp(arg, "-blackout")) { } else if (!strcmp(arg, "-blackout")) {
CHECK_ARGC CHECK_ARGC
blackout_str = strdup(argv[++i]); blackout_str = strdup(argv[++i]);
@ -16000,9 +16450,10 @@ int main(int argc, char* argv[]) {
i++; /* done above */ i++; /* done above */
} else if (!strcmp(arg, "-norc")) { } else if (!strcmp(arg, "-norc")) {
; /* done above */ ; /* done above */
} else if (!strcmp(arg, "-h") || !strcmp(arg, "-help") } else if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) {
|| !strcmp(arg, "-?")) { print_help(0);
print_help(); } else if (!strcmp(arg, "-?") || !strcmp(arg, "-opts")) {
print_help(1);
} else if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) { } else if (!strcmp(arg, "-V") || !strcmp(arg, "-version")) {
fprintf(stderr, "x11vnc: %s\n", lastmod); fprintf(stderr, "x11vnc: %s\n", lastmod);
exit(0); exit(0);
@ -16270,7 +16721,6 @@ int main(int argc, char* argv[]) {
} }
/* /*
* If -passwd was used, clear it out of argv. This does not * If -passwd was used, clear it out of argv. This does not
* work on all UNIX, have to use execvp() in general... * work on all UNIX, have to use execvp() in general...
@ -16480,6 +16930,8 @@ int main(int argc, char* argv[]) {
fprintf(stderr, " using_shm: %d\n", using_shm); fprintf(stderr, " using_shm: %d\n", using_shm);
fprintf(stderr, " flipbytes: %d\n", flip_byte_order); fprintf(stderr, " flipbytes: %d\n", flip_byte_order);
fprintf(stderr, " onetile: %d\n", single_copytile); fprintf(stderr, " onetile: %d\n", single_copytile);
fprintf(stderr, " solid: %s\n", solid_str
? solid_str : "null");
fprintf(stderr, " blackout: %s\n", blackout_str fprintf(stderr, " blackout: %s\n", blackout_str
? blackout_str : "null"); ? blackout_str : "null");
fprintf(stderr, " xinerama: %d\n", xinerama); fprintf(stderr, " xinerama: %d\n", xinerama);
@ -16491,7 +16943,7 @@ int main(int argc, char* argv[]) {
fprintf(stderr, " logfile: %s\n", logfile ? logfile fprintf(stderr, " logfile: %s\n", logfile ? logfile
: "null"); : "null");
fprintf(stderr, " logappend: %d\n", logfile_append); fprintf(stderr, " logappend: %d\n", logfile_append);
fprintf(stderr, " rc_file: \%s\n", rc_rcfile ? rc_rcfile fprintf(stderr, " rc_file: %s\n", rc_rcfile ? rc_rcfile
: "null"); : "null");
fprintf(stderr, " norc: %d\n", rc_norc); fprintf(stderr, " norc: %d\n", rc_norc);
fprintf(stderr, " bg: %d\n", bg); fprintf(stderr, " bg: %d\n", bg);

Loading…
Cancel
Save