x11vnc: -reflect, -N. -ncache, FINDDISPLAY, FINDCREATEDISPLAY, improvements. MODTWEAK_LOWEST workaround.

pull/1/head
runge 17 years ago
parent 1f8da9bde3
commit 1b9082bc87

@ -1,3 +1,13 @@
2007-01-31 Karl Runge <runge@karlrunge.com>
* x11vnc: -reflect reflector/repeater mode with libvncclient.
-ncache tweaks: no kde animations and wm improvements,
fixes to FINDDISPLAY and FINDCREATEDISPLAY login modes,
MODTWEAK_LOWEST envvar for HP-UX keyboard workaround.
-N option for display and rfbport matching.
2007-01-12 Karl Runge <runge@karlrunge.com>
* x11vnc: -N option, more -ncache improvements, kde/gnome.
2007-01-03 Karl Runge <runge@karlrunge.com>
* x11vnc: more -ncache improvements.

@ -1,5 +1,5 @@
AM_CFLAGS = -I $(top_srcdir)
LDADD = ../libvncserver/libvncserver.a @WSOCKLIB@
LDADD = ../libvncserver/libvncserver.a ../libvncclient/libvncclient.a @WSOCKLIB@
if OSX
x11vnc_LDFLAGS = -framework ApplicationServices -framework Carbon -framework IOKit -framework Cocoa

File diff suppressed because it is too large Load Diff

@ -158,6 +158,9 @@ void clean_up_exit (int ret) {
if (use_solid_bg) {
solid_bg(1);
}
if (ncache || ncache0) {
kde_no_animate(1);
}
X_LOCK;
XTestDiscard_wr(dpy);
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
@ -415,6 +418,9 @@ static void interrupted (int sig) {
if (use_solid_bg) {
solid_bg(1);
}
if (ncache || ncache0) {
kde_no_animate(1);
}
stop_stunnel();
if (crash_debug) {

@ -517,8 +517,9 @@ int run_user_command(char *cmd, rfbClientPtr client, char *mode, char *input,
clean_up_exit(1);
}
rfbLog("running command:\n");
rfbLog(" %s\n", cmd);
if (!quiet) {
fprintf(stderr, "\n %s\n\n", cmd);
}
close_exec_fds();
if (output != NULL) {
@ -668,6 +669,9 @@ void client_gone(rfbClientPtr client) {
if (use_solid_bg && client_count == 0) {
solid_bg(1);
}
if ((ncache || ncache0) && client_count == 0) {
kde_no_animate(1);
}
if (client->clientData) {
cd = (ClientData *) client->clientData;
if (cd->ssl_helper_pid > 0) {

@ -1113,7 +1113,6 @@ static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
a = 0xff000000 & (*(pixels+i));
a = a >> 24; /* alpha channel */
if (a < (unsigned int) thresh) {
bitmap[i] = ' ';
} else {
@ -1256,6 +1255,13 @@ static int get_exact_cursor(int init) {
}
#endif
if (rawfb_vnc_reflect) {
int last_idx = (int) get_cursor_serial(1);
if (last_idx) {
which = last_idx;
}
return which;
}
if (xfixes_present && dpy) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
int last_idx = (int) get_cursor_serial(1);
@ -1490,6 +1496,9 @@ int get_which_cursor(void) {
mode = 3;
}
if (rawfb_vnc_reflect && mode > -1) {
return get_exact_cursor(0);
}
if (mode == 3) {
if ((xfixes_present && use_xfixes) || macosx_console) {
if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");

@ -55,10 +55,10 @@ void print_help(int mode) {
" and http://www.karlrunge.com/x11vnc/#faq\n"
"\n"
"\n"
"Rudimentary config file support: if the file $HOME/.x11vncrc exists then each\n"
"line in it is treated as a single command line option. Disable with -norc.\n"
"For each option name, the leading character \"-\" is not required. E.g. a\n"
"line that is either \"forever\" or \"-forever\" may be used and are equivalent.\n"
"Config file support: if the file $HOME/.x11vncrc exists then each line in\n"
"it is treated as a single command line option. Disable with -norc. For\n"
"each option name, the leading character \"-\" is not required. E.g. a line\n"
"that is either \"forever\" or \"-forever\" may be used and are equivalent.\n"
"Likewise \"wait 100\" or \"-wait 100\" are acceptable and equivalent lines.\n"
"The \"#\" character comments out to the end of the line in the usual way\n"
"(backslash it for a literal). Leading and trailing whitespace is trimmed off.\n"
@ -77,7 +77,23 @@ void print_help(int mode) {
" before startup. Same as -xauth file. See Xsecurity(7),\n"
" xauth(1) man pages for more info.\n"
"\n"
"-id windowid Show the window corresponding to \"windowid\" not\n"
"-N If the X display is :N, try to set the VNC display\n"
" to also be :N This just sets the -rfbport option\n"
" to 5900+N. The program will exit immediately if that\n"
" port is not available.\n"
"\n"
"-reflect host:N Instead of connecting to and polling an X display,\n"
" connect to the remote VNC server host:N and be a\n"
" reflector/repeater for it. This is useful for trying\n"
" to manage the case of many simultaneous VNC viewers\n"
" (e.g. classroom broadcasting) where, e.g. you put\n"
" a repeater on each network switch, etc, to improve\n"
" performance by distributing the load and network\n"
" traffic. Implies -shared (use -noshared as a later\n"
" option to disable). See the discussion below under\n"
" -rawfb vnc:host:N for more details.\n"
"\n"
"-id windowid Show the X window corresponding to \"windowid\" not\n"
" the entire display. New windows like popup menus,\n"
" transient toplevels, etc, may not be seen or may be\n"
" clipped. Disabling SaveUnders or BackingStore in the\n"
@ -789,15 +805,16 @@ void print_help(int mode) {
" in PATH and have run \"Xdummy -install\" once to create\n"
" the shared library. Xdummy requires root permission\n"
" and only works on Linux. Xvfb is available on most\n"
" platforms.\n"
" platforms and does not require root.\n"
"\n"
" When x11vnc exits (i.e. user disconnects) the X server\n"
" session stays running in the background. Presumably the\n"
" FINDDISPLAY will find it next time. The user must exit\n"
" the X session in the usual way for it to terminate.\n"
" session stays running in the background. Presumably\n"
" the FINDDISPLAY will find it next time. The user must\n"
" exit the X session in the usual way for it to terminate\n"
" (or kill the X server process if all else fails).\n"
"\n"
" So this is a somewhat odd mode for x11vnc in that it\n"
" will start up and poll virtual X servers. This can\n"
" will start up and poll virtual X servers! This can\n"
" be used from, say, inetd(8) to provide a means of\n"
" definitely getting a desktop (either real or virtual)\n"
" on the machine. E.g. a desktop service:\n"
@ -812,10 +829,24 @@ void print_help(int mode) {
" Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the\n"
" script used. You can specify the preferred order via\n"
" e.g., WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or\n"
" leave out ones you do not want. The the extra case \"X\"\n"
" means try to start up a real, hardware X server using\n"
" xinit(1). If there is already an X server running the\n"
" X case may only work on Linux (see startx(1)).\n"
" leave out ones you do not want. The the extra case\n"
" \"X\" means try to start up a real, hardware X server\n"
" using xinit(1) or startx(1). If there is already an\n"
" X server running the X case may only work on Linux\n"
" (see startx(1)).\n"
"\n"
" If you want the FINDCREATEDISPLAY session to contact an\n"
" XDMCP login manager (xdm/gdm/kdm) on the same machine,\n"
" then use \"Xvfb.xdmcp\" instead of \"Xvfb\", etc.\n"
" The user will have to supply his username and password\n"
" one more time (but he gets to select his desktop type\n"
" so that can be useful). For this to work, you will\n"
" need to enable localhost XDMCP (udp port 177) for the\n"
" display manager. This seems to be:\n"
"\n"
" for gdm in gdm.conf: Enable=true in section [xdmcp]\n"
" for kdm in kdmrc: Enable=true in section [Xdmcp]\n"
" for xdm in xdm-config: DisplayManager.requestPort: 177\n"
"\n"
#ifndef NO_SSL_OR_UNIXPW
"-ssl [pem] Use the openssl library (www.openssl.org) to provide a\n"
@ -1691,6 +1722,15 @@ void print_help(int mode) {
" identical keyboards). Also useful in resolving cases\n"
" where a Keysym is bound to multiple keys (e.g. \"<\" + \">\"\n"
" and \",\" + \"<\" keys). Default: %s\n"
"\n"
" On some HP-UX systems it is been noted that they have\n"
" an odd keymapping where a single keycode will have a\n"
" keysym, e.g. \"#\", up to three times. You can check\n"
" via \"xmodmap -pk\" or the -dk option. The failure\n"
" is when you try to type \"#\" it yields \"3\". If you\n"
" see this problem try setting the environment variable\n"
" MODTWEAK_LOWEST=1 to see if it helps.\n"
"\n"
"-xkb When in modtweak mode, use the XKEYBOARD extension (if\n"
"-noxkb the X display supports it) to do the modifier tweaking.\n"
" This is powerful and should be tried if there are still\n"
@ -2021,6 +2061,10 @@ void print_help(int mode) {
" for rapid retrieval. So a W x H frambuffer is expanded\n"
" to a W x (n+1)*H one. Use 0 to disable. Default: XXX.\n"
"\n"
" For this and the other -ncache* options below you can\n"
" abbreviate \"-ncache\" with \"-nc\". Also, \"-nonc\"\n"
" is the same as \"-ncache 0\"\n"
"\n"
" This is an experimental option, currently implemented\n"
" in an awkward way in that in the VNC Viewer you can\n"
" see the cache contents if you scroll down, etc. So you\n"
@ -2081,7 +2125,21 @@ void print_help(int mode) {
"\n"
"-ncache_no_rootpixmap In -ncache mode, do not try to snapshot the desktop\n"
" background to use in guessing or reconstructing window\n"
" save-unders..\n"
" save-unders.\n"
"\n"
"-ncache_keep_anims In -ncache mode, do not try to disable window\n"
" manager animations and other effects (that usually\n"
" degrade ncache performance or cause painting errors).\n"
" The default is to try to disable them on KDE (but not\n"
" GNOME) when VNC clients are connected.\n"
"\n"
" For other window managers or desktops that provide\n"
" animations, effects, compositing, translucency,\n"
" etc. that interfere with the -ncache method you will\n"
" have to disable them manually.\n"
"\n"
"-ncache_old_wm In -ncache mode, enable some heuristics for old style\n"
" window managers such as fvwm and twm.\n"
"\n"
"-ncache_pad n In -ncache mode, pad each window with n pixels for the\n"
" caching rectangles. This can be used to try to improve\n"
@ -2703,6 +2761,10 @@ void print_help(int mode) {
" the framebuffer device is opened and keystrokes (and\n"
" possibly mouse events) are inserted into the console.\n"
"\n"
" If the string begins with \"vnc\", see the VNC HOST\n"
" discussion below where the framebuffer is taken as that\n"
" of another remote VNC server.\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"
@ -2723,6 +2785,7 @@ void print_help(int mode) {
" -rawfb video0\n"
" -rawfb video -pipeinput VID\n"
" -rawfb console\n"
" -rawfb vnc:somehost:0\n"
"\n"
" (see ipcs(1) and fbset(1) for the first two examples)\n"
"\n"
@ -2893,6 +2956,44 @@ void print_help(int mode) {
" -rawfb console:/dev/nonstd\n"
" -rawfb console -pipeinput UINPUT:accel=4.0\n"
"\n"
" VNC HOST: if the -rawfb string is of the form\n"
" \"vnc:host:N\" then the VNC display \"N\" on the remote\n"
" VNC server \"host\" is connected to (i.e. x11vnc acts as\n"
" a VNC client itself) and that framebuffer is exported.\n"
"\n"
" This mode is really only of use if you are trying\n"
" to improve performance in the case of many (e.g. >\n"
" 10) simultaneous VNC viewers, and you try a divide\n"
" and conquer scheme to reduce bandwidth and improve\n"
" responsiveness.\n"
"\n"
" For example, if there will be 64 simultaneous VNC\n"
" viewers this can lead to a lot of redundant VNC traffic\n"
" to and from the server host:N, extra CPU usage,\n"
" and all viewers response can be reduced by having\n"
" to wait for writes to the slowest client to finish.\n"
" However, if you set up 8 reflectors/repeaters started\n"
" with option -rawfb vnc:host:N, then there are only\n"
" 8 connections to host:N. Each repeater then handles\n"
" 8 vnc viewer connections thereby spreading the load\n"
" around. In classroom broadcast usage, try to put the\n"
" repeaters on different switches. This mode is the same\n"
" as -reflect host:N. Replace \"host:N\" by \"listen\"\n"
" or \"listen:port\" for a reverse connection.\n"
"\n"
" Overall performance will not be as good as a single\n"
" direct connection because, among other things,\n"
" there is an additional level of framebuffer polling\n"
" and pointer motion can still induce many changes per\n"
" second that must be propagated. Tip: if the remote VNC\n"
" is x11vnc doing wireframing, or an X display that does\n"
" wireframing that gives much better response than opaque\n"
" window dragging. Consider the -nodragging option if\n"
" the problem is severe.\n"
"\n"
" The VNC HOST mode implies -shared. Use -noshared as\n"
" a subsequent cmdline option to disable sharing.\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"
@ -2995,7 +3096,7 @@ void print_help(int mode) {
" If the uinput device has an absolute pointer (as opposed\n"
" to a normal mouse that is a relative pointer) you can\n"
" specify the option \"abs\". Note that a touchpad\n"
" on a laptop is an absolute device t some degree.\n"
" on a laptop is an absolute device to some degree.\n"
" This (usually) avoids all the problems with mouse\n"
" acceleration. If x11vnc has trouble deducing the size\n"
" of the device, use \"abs=WxH\". Furthermore, if the\n"
@ -3355,6 +3456,8 @@ void print_help(int mode) {
" ncache_no_rootpixmap enable ncache_no_rootpixmap.\n"
" noncache_no_rootpixmap disable ncache_no_rootpixmap.\n"
" ncache_reset_rootpixmap recheck the root pixmap\n"
" ncache_keep_anims enable ncache_keep_anims.\n"
" noncache_keep_anims disable ncache_keep_anims.\n"
" wireframe enable -wireframe mode. same as \"wf\"\n"
" nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n"
@ -3505,26 +3608,27 @@ void print_help(int mode) {
" 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 rotate padgeom\n"
" quiet q noquiet modtweak nomodtweak xkb noxkb capslock\n"
" nocapslock skip_lockkeys noskip_lockkeys 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"
" bell nobell sel nosel primary noprimary setprimary\n"
" nosetprimary clipboard noclipboard setclipboard\n"
" nosetclipboard seldir cursorshape nocursorshape\n"
" cursorpos nocursorpos cursor_drag nocursor_drag cursor\n"
" show_cursor noshow_cursor nocursor arrow xfixes\n"
" noxfixes xdamage noxdamage xd_area xd_mem alphacut\n"
" alphafrac alpharemove noalpharemove alphablend\n"
" noalphablend xwarppointer xwarp noxwarppointer\n"
" noxwarp buttonmap dragging nodragging ncache_cr\n"
" noncache_cr ncache_no_moveraise noncache_no_moveraise\n"
" ncache_no_dtchange noncache_no_dtchange\n"
" ncache_no_rootpixmap noncache_no_rootpixmap\n"
" ncache_reset_rootpixmap ncache noncache ncache_size\n"
" wireframe_mode wireframe wf nowireframe nowf\n"
" xtrap noxtrap xrandr noxrandr xrandr_mode rotate\n"
" padgeom quiet q noquiet modtweak nomodtweak xkb noxkb\n"
" capslock nocapslock skip_lockkeys noskip_lockkeys\n"
" skip_keycodes sloppy_keys nosloppy_keys skip_dups\n"
" noskip_dups add_keysyms noadd_keysyms clear_mods\n"
" noclear_mods clear_keys noclear_keys remap repeat\n"
" norepeat fb nofb bell nobell sel nosel primary\n"
" noprimary setprimary nosetprimary clipboard noclipboard\n"
" setclipboard nosetclipboard seldir cursorshape\n"
" nocursorshape cursorpos nocursorpos cursor_drag\n"
" nocursor_drag cursor show_cursor noshow_cursor\n"
" nocursor arrow xfixes noxfixes xdamage noxdamage\n"
" xd_area xd_mem alphacut alphafrac alpharemove\n"
" noalpharemove alphablend noalphablend xwarppointer\n"
" xwarp noxwarppointer noxwarp buttonmap dragging\n"
" nodragging ncache_cr noncache_cr ncache_no_moveraise\n"
" noncache_no_moveraise ncache_no_dtchange\n"
" noncache_no_dtchange ncache_no_rootpixmap\n"
" noncache_no_rootpixmap ncache_reset_rootpixmap\n"
" ncache_keep_anims noncache_keep_anims ncache noncache\n"
" ncache_size wireframe_mode wireframe wf nowireframe nowf\n"
" wireframelocal wfl nowireframelocal nowfl wirecopyrect\n"
" wcr nowirecopyrect nowcr scr_area scr_skip scr_inc\n"
" scr_keys scr_term scr_keyrepeat scr_parms scrollcopyrect\n"

@ -2235,6 +2235,7 @@ void initialize_modtweak(void) {
#else
KeySym keysym, *keymap;
int i, j, minkey, maxkey, syms_per_keycode;
int use_lowest_index = 0;
if (use_xkb_modtweak) {
initialize_xkb_modtweak();
@ -2247,6 +2248,10 @@ void initialize_modtweak(void) {
RAWFB_RET_VOID
if (getenv("MODTWEAK_LOWEST")) {
use_lowest_index = 1;
}
X_LOCK;
XDisplayKeycodes(dpy, &minkey, &maxkey);
@ -2306,6 +2311,9 @@ void initialize_modtweak(void) {
keysym = keymap[ (i - minkey) * syms_per_keycode + j ];
if ( keysym >= ' ' && keysym < 0x100
&& i == XKeysymToKeycode(dpy, keysym) ) {
if (use_lowest_index && keycodes[keysym] != NoSymbol) {
continue;
}
keycodes[keysym] = i;
modifiers[keysym] = j;
}
@ -2555,6 +2563,8 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
uinput_key_command(down, keysym, client);
} else if (pipeinput_int == PIPEINPUT_MACOSX) {
macosx_key_command(down, keysym, client);
} else if (pipeinput_int == PIPEINPUT_VNC) {
vnc_reflect_send_key((uint32_t) keysym, down);
}
if (pipeinput_fh == NULL) {
return;

@ -243,7 +243,7 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
last_pointer_time = time(NULL);
}
if (last_mask != mask) {
fprintf(stderr, "about to inject mask change %d -> %d: %.4f\n", last_mask, mask, dnowx());
if (0) fprintf(stderr, "about to inject mask change %d -> %d: %.4f\n", last_mask, mask, dnowx());
if (mask) {
int px, py, x, y, w, h;
macosx_click_frame = None;
@ -267,7 +267,7 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (ncache > 0) {
/* XXX Y */
int i;
fprintf(stderr, "about to get all windows: %.4f\n", dnowx());
if (0) fprintf(stderr, "about to get all windows: %.4f\n", dnowx());
for (i=0; i < 2; i++) {
macosxCGS_get_all_windows();
fprintf(stderr, "!");
@ -275,7 +275,7 @@ fprintf(stderr, "about to get all windows: %.4f\n", dnowx());
break;
}
}
fprintf(stderr, "\ndone: %.4f\n", dnowx());
if (0) fprintf(stderr, "\ndone: %.4f\n", dnowx());
}
}
last_mask = mask;

@ -35,7 +35,7 @@ void macosxCG_key_inject(int down, unsigned int keysym);
CGDirectDisplayID displayID = NULL;
extern void macosx_log(char *);
extern int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
extern int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
static void macosxCG_callback(CGRectCount n, const CGRect *rects, void *dum) {
int i, db = 0;
@ -43,7 +43,7 @@ static void macosxCG_callback(CGRectCount n, const CGRect *rects, void *dum) {
if (!dum) {}
for (i=0; i < (int) n; i++) {
if (db > 1) fprintf(stderr, " : %g %g - %g %g\n", rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
collect_macosx_damage( (int) rects[i].origin.x, (int) rects[i].origin.y,
collect_non_X_xdamage( (int) rects[i].origin.x, (int) rects[i].origin.y,
(int) rects[i].size.width, (int) rects[i].size.height, 1);
}
}

@ -177,7 +177,7 @@ int macosxCGS_follow_animation_win(int win, int idx, int grow) {
macwins[idx].height = h;
}
fprintf(stderr, " chase: %03dx%03d+%03d+%03d %d\n", w, h, x, y, win);
if (0) fprintf(stderr, " chase: %03dx%03d+%03d+%03d %d\n", w, h, x, y, win);
if (x == xp && y == yp && w == wp && h == hp) {
reps++;
if (reps >= 2) {
@ -398,20 +398,20 @@ if (db) fprintf(stderr, "cnt: %d err: %d\n", (int) _wins_mapped_cnt, err);
;
} else if ( !(prev & is_mapped) && (curr & is_mapped)) {
/* MapNotify */
fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
if (0) fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 1);
if (0) macosxCGS_follow_animation_win(win, i, 1);
} else if ( !(curr & is_mapped) && (prev & is_mapped)) {
/* UnmapNotify */
fprintf(stderr, "UnmapNotify: %d/%d %d %.4f A tot=%d\n", prev, curr, win, dnowx(), totcnt);
if (0) fprintf(stderr, "UnmapNotify: %d/%d %d %.4f A tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 0);
} else if ( !(prev & is_exist) && (curr & is_exist)) {
/* CreateNotify */
fprintf(stderr, "CreateNotify:%d/%d %d %.4f whist: %d/%d 0x%x tot=%d\n", prev, curr, win, dnowx(), whist_prv, whist_idx, win, totcnt);
if (0) fprintf(stderr, "CreateNotify:%d/%d %d %.4f whist: %d/%d 0x%x tot=%d\n", prev, curr, win, dnowx(), whist_prv, whist_idx, win, totcnt);
macosx_add_create(win, macwins[i].level);
if (curr & is_mapped) {
fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
if (0) fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 1);
}
}
@ -425,24 +425,24 @@ if (db) fprintf(stderr, "cnt: %d err: %d\n", (int) _wins_mapped_cnt, err);
if (1) {
;
} else if (curr & is_clipped) {
fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
if (0) fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 1;
} else {
fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
if (0) fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 0;
}
} else {
if ( !(prev & is_clipped) && (curr & is_clipped) ) {
fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
if (0) fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 1;
} else if ( (prev & is_clipped) && !(curr & is_clipped) ) {
fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
if (0) fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 0;
@ -466,11 +466,11 @@ if (db) fprintf(stderr, "cnt: %d err: %d\n", (int) _wins_mapped_cnt, err);
prev = whist[whist_prv][win];
if (!(curr & is_exist) && (prev & is_exist)) {
if (prev & is_mapped) {
fprintf(stderr, "UnmapNotify: %d/%d %d %.4f B tot=%d\n", prev, curr, win, dnowx(), totcnt);
if (0) fprintf(stderr, "UnmapNotify: %d/%d %d %.4f B tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, lvl, 0);
}
/* DestroyNotify */
fprintf(stderr, "DestroNotify:%d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
if (0) fprintf(stderr, "DestroNotify:%d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_destroy(win, lvl);
}
}

@ -1,5 +1,5 @@
--- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400
+++ vnc_unixsrc/vncviewer/desktop.c 2006-07-27 11:30:01.000000000 -0400
+++ vnc_unixsrc/vncviewer/desktop.c 2007-01-13 13:59:51.000000000 -0500
@@ -50,6 +50,30 @@
},
};
@ -63,7 +63,7 @@
/*
* DesktopInitAfterRealization does things which require the X windows to
* exist. It creates some GCs and sets the dot cursor.
@@ -460,3 +463,69 @@
@@ -460,3 +463,70 @@
break;
}
}
@ -74,7 +74,8 @@
+ } else {
+ if (image && image->data) {
+ free(image->data);
+ XDestroyImage(image);
+ /* see manpage XDestroyImage may also free data, so we skip and have a tiny leak instead */
+ if (0) XDestroyImage(image);
+ image = NULL;
+ }
+ }

@ -9,6 +9,7 @@
int debug = 0;
char *use_dpy = NULL; /* -display */
int display_N = 0;
char *auth_file = NULL; /* -auth/-xauth */
char *visual_str = NULL; /* -visual */
int set_visual_str_to_something = 0;
@ -216,6 +217,8 @@ int ncache0 = 0;
int ncache_copyrect = 0;
int ncache_wf_raises = 1;
int ncache_dt_change = 1;
int ncache_keep_anims = 0;
int ncache_old_wm = 0;
int macosx_ncache_macmenu = 0;
int ncache_beta_tester = 0;

@ -9,6 +9,7 @@
extern int debug;
extern char *use_dpy;
extern int display_N;
extern char *auth_file;
extern char *visual_str;
extern int set_visual_str_to_something;
@ -163,6 +164,8 @@ extern int ncache_wf_raises;
extern int ncache_dt_change;
extern int ncache_pad;
extern int ncache_xrootpmap;
extern int ncache_keep_anims;
extern int ncache_old_wm;
extern int macosx_ncache_macmenu;
extern int ncache_beta_tester;

@ -5,8 +5,9 @@
#define ICON_MODE_SOCKS 16
/* had lw=3 for a long time */
#ifndef WIREFRAME_PARMS
#define WIREFRAME_PARMS "0xff,3,0,32+8+8+8,all,0.15+0.30+5.0+0.125"
#define WIREFRAME_PARMS "0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125"
#endif
#ifndef SCROLL_COPYRECT_PARMS
@ -40,6 +41,7 @@
#define PIPEINPUT_CONSOLE 0x2
#define PIPEINPUT_UINPUT 0x3
#define PIPEINPUT_MACOSX 0x4
#define PIPEINPUT_VNC 0x5
#define MAX_BUTTONS 5

@ -558,6 +558,8 @@ static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
uinput_pointer_command(mask, x, y, client);
} else if (pipeinput_int == PIPEINPUT_MACOSX) {
macosx_pointer_command(mask, x, y, client);
} else if (pipeinput_int == PIPEINPUT_VNC) {
vnc_reflect_send_pointer(x, y, mask);
}
if (pipeinput_fh == NULL) {
return;
@ -679,6 +681,8 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
got_user_input++;
got_pointer_input++;
last_pointer_client = client;
last_pointer_time = dnow();
last_event = last_input = last_pointer_input = time(NULL);
}
if (input.motion) {
/* raw_fb hack track button state */
@ -994,6 +998,9 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
} else if (strstr(p, "MACOSX") == p) {
pipeinput_int = PIPEINPUT_MACOSX;
return;
} else if (strstr(p, "VNC") == p) {
pipeinput_int = PIPEINPUT_VNC;
return;
}
set_child_info();

@ -2790,7 +2790,6 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (orig != ncache_xrootpmap) {
do_new_fb(1);
}
} else if (!strcmp(p, "noncache_no_rootpixmap")) {
int orig = ncache_xrootpmap;
if (query) {
@ -2813,6 +2812,38 @@ char *process_remote_cmd(char *cmd, int stringonly) {
set_ncache_xrootpmap();
}
} else if (!strcmp(p, "ncache_keep_anims")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, ncache_keep_anims);
goto qry;
}
kde_no_animate(0);
ncache_keep_anims = 1;
rfbLog("remote_cmd: set -ncache_keep_anims\n");
} else if (!strcmp(p, "noncache_keep_anims")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !ncache_keep_anims);
goto qry;
}
ncache_keep_anims = 0;
kde_no_animate(1);
rfbLog("remote_cmd: disabled -ncache_keep_anims\n");
} else if (!strcmp(p, "ncache_old_wm")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, ncache_old_wm);
goto qry;
}
ncache_old_wm = 1;
rfbLog("remote_cmd: set -ncache_old_wm\n");
} else if (!strcmp(p, "noncache_old_wm")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !ncache_old_wm);
goto qry;
}
ncache_old_wm = 0;
rfbLog("remote_cmd: disabled -ncache_old_wm\n");
} else if (!strcmp(p, "ncache")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);

@ -3065,11 +3065,15 @@ int scan_for_updates(int count_only) {
/* first pass collecting DAMAGE events: */
#ifdef MACOSX
if (macosx_console) {
collect_macosx_damage(-1, -1, -1, -1, 0);
collect_non_X_xdamage(-1, -1, -1, -1, 0);
} else
#endif
{
collect_xdamage(scan_count, 0);
if (rawfb_vnc_reflect) {
collect_non_X_xdamage(-1, -1, -1, -1, 0);
} else {
collect_xdamage(scan_count, 0);
}
}
}
}
@ -3100,7 +3104,11 @@ int scan_for_updates(int count_only) {
} else
#endif
{
collect_xdamage(scan_count, 1);
if (rawfb_vnc_reflect) {
;
} else {
collect_xdamage(scan_count, 1);
}
}
}
if (count_only) {

@ -24,6 +24,8 @@
#include "macosx.h"
#include "macosxCG.h"
#include <rfb/rfbclient.h>
void set_greyscale_colormap(void);
void set_hi240_colormap(void);
void unset_colormap(void);
@ -43,6 +45,11 @@ void initialize_screen(int *argc, char **argv, XImage *fb);
void set_vnc_desktop_name(void);
void announce(int lport, int ssl, char *iface);
char *vnc_reflect_guess(char *str, char **raw_fb_addr);
void vnc_reflect_process_client(void);
rfbBool vnc_reflect_send_pointer(int x, int y, int mask);
rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down);
rfbBool vnc_reflect_send_cuttext(char *str, int len);
static void debug_colormap(XImage *fb);
static void set_visual(char *str);
@ -57,6 +64,7 @@ static void setup_scaling(int *width_in, int *height_in);
int rawfb_reset = -1;
int rawfb_dev_video = 0;
int rawfb_vnc_reflect = 0;
/*
* X11 and rfb display/screen related routines
@ -605,7 +613,9 @@ void set_raw_fb_params(int restore) {
view_only = 1;
}
#endif
if (watch_selection) {
if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
;
} else if (watch_selection) {
if (verbose) rfbLog(" rawfb: turning off "
"watch_selection\n");
watch_selection = 0;
@ -635,7 +645,11 @@ void set_raw_fb_params(int restore) {
use_solid_bg = 0;
}
#ifndef MACOSX
multiple_cursors_mode = strdup("arrow");
if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
;
} else {
multiple_cursors_mode = strdup("arrow");
}
#endif
}
if (using_shm) {
@ -830,6 +844,281 @@ static void initialize_snap_fb(void) {
snap_fb = snap->data;
}
rfbClient* client = NULL;
void vnc_reflect_bell(rfbClient *cl) {
if (sound_bell) {
if (unixpw_in_progress) {
return;
}
if (! all_clients_initialized()) {
rfbLog("vnc_reflect_bell: not sending bell: "
"uninitialized clients\n");
} else {
if (screen && client_count) {
rfbSendBell(screen);
}
}
}
}
void vnc_reflect_recv_cuttext(rfbClient *cl, const char *str, int len) {
if (unixpw_in_progress) {
return;
}
if (! watch_selection) {
return;
}
if (! all_clients_initialized()) {
rfbLog("vnc_reflect_recv_cuttext: no send: uninitialized clients\n");
return; /* some clients initializing, cannot send */
}
rfbSendServerCutText(screen, (char *)str, len);
}
void vnc_reflect_got_update(rfbClient *cl, int x, int y, int w, int h) {
if (use_xdamage) {
static int first = 1;
if (first) {
collect_non_X_xdamage(-1, -1, -1, -1, 0);
first = 0;
}
collect_non_X_xdamage(x, y, w, h, 1);
}
}
void vnc_reflect_got_cursorshape(rfbClient *cl, int xhot, int yhot, int width, int height, int bytesPerPixel) {
static int serial = 1;
int i, j;
char *bitmap, *rich, *alpha;
char *pixels = NULL;
unsigned long r, g, b, a;
unsigned int ui;
unsigned long red_mask, green_mask, blue_mask;
if (unixpw_in_progress) {
return;
}
if (! all_clients_initialized()) {
rfbLog("vnc_reflect_got_copyshape: no send: uninitialized clients\n");
return; /* some clients initializing, cannot send */
}
if (! client->rcSource) {
return;
}
if (bytesPerPixel != 1 && bytesPerPixel != 2 && bytesPerPixel != 4) {
return;
}
red_mask = (client->format.redMax << client->format.redShift);
green_mask = (client->format.greenMax << client->format.greenShift);
blue_mask = (client->format.blueMax << client->format.blueShift);
pixels = (char *)malloc(4*width*height);
for (j=0; j<height; j++) {
for (i=0; i<width; i++) {
unsigned int* uip;
unsigned char* uic;
int m;
if (bytesPerPixel == 1) {
unsigned char* p = (unsigned char *) client->rcSource;
ui = (unsigned long) *(p + j * width + i);
} else if (bytesPerPixel == 2) {
unsigned short* p = (unsigned short *) client->rcSource;
ui = (unsigned long) *(p + j * width + i);
} else if (bytesPerPixel == 4) {
unsigned int* p = (unsigned int *) client->rcSource;
ui = (unsigned long) *(p + j * width + i);
}
r = (red_mask & ui) >> client->format.redShift;
g = (green_mask & ui) >> client->format.greenShift;
b = (blue_mask & ui) >> client->format.blueShift;
r = (255 * r) / client->format.redMax;
g = (255 * g) / client->format.greenMax;
b = (255 * b) / client->format.blueMax;
ui = (r << 16 | g << 8 | b << 0) ;
uic = (unsigned char *)client->rcMask;
m = (int) *(uic + j * width + i);
if (m) {
ui |= 0xff000000;
}
uip = (unsigned int *)pixels;
*(uip + j * width + i) = ui;
}
}
store_cursor(serial++, (unsigned long*) pixels, width, height, 32, xhot, yhot);
free(pixels);
set_cursor(cursor_x, cursor_y, get_which_cursor());
}
void vnc_reflect_got_copyrect(rfbClient *cl, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
sraRegionPtr reg;
int dx, dy, rc = -1;
static int last_dx = 0, last_dy = 0;
if (unixpw_in_progress) {
return;
}
if (! all_clients_initialized()) {
rfbLog("vnc_reflect_got_copyrect: no send: uninitialized clients\n");
return; /* some clients initializing, cannot send */
}
dx = dest_x - src_x;
dy = dest_y - src_y;
if (dx != last_dx || dy != last_dy) {
rc = fb_push_wait(0.05, FB_COPY|FB_MOD);
}
if (0) fprintf(stderr, "vnc_reflect_got_copyrect: %dx%d+%d+%d %d %d rc=%d\n", dest_x, dest_y, w, h, dx, dy, rc);
reg = sraRgnCreateRect(dest_x, dest_y, dest_x + w, dest_y + h);
do_copyregion(reg, dx, dy, 0);
sraRgnDestroy(reg);
last_dx = dx;
last_dy = dy;
}
rfbBool vnc_reflect_resize(rfbClient *cl) {
static int first = 1;
if(cl->frameBuffer) {
free(cl->frameBuffer);
}
cl->frameBuffer= malloc(cl->width * cl->height * cl->format.bitsPerPixel/8);
if (!first) {
do_new_fb(1);
}
first = 0;
return cl->frameBuffer ? TRUE : FALSE;
}
char *vnc_reflect_guess(char *str, char **raw_fb_addr) {
static int first = 1;
char *hp = str + strlen("vnc:");
char *at = NULL;
int argc = 0, i;
char *argv[16];
char str2[256];
char *str0 = strdup(str);
if (client == NULL) {
client = rfbGetClient(8, 3, 4);
}
rfbLog("rawfb: %s\n", str);
at = strchr(hp, '@');
if (at) {
*at = '\0';
at++;
}
client->appData.useRemoteCursor = TRUE;
client->Bell = vnc_reflect_bell;
client->GotXCutText = vnc_reflect_recv_cuttext;
client->GotCopyRect = vnc_reflect_got_copyrect;
client->GotCursorShape = vnc_reflect_got_cursorshape;
client->MallocFrameBuffer = vnc_reflect_resize;
client->canHandleNewFBSize = TRUE;
client->GotFrameBufferUpdate = vnc_reflect_got_update;
if (first) {
argv[argc++] = "x11vnc_rawfb_vnc";
if (strstr(hp, "listen") == hp) {
char *q = strchr(hp, ':');
argv[argc++] = strdup("-listen");
if (q) {
client->listenPort = atoi(q+1);
} else {
client->listenPort = LISTEN_PORT_OFFSET;
}
} else {
argv[argc++] = strdup(hp);
}
if (! rfbInitClient(client, &argc, argv)) {
rfbLog("vnc_reflector failed for: %s\n", str0);
clean_up_exit(1);
}
}
if (at) {
sprintf(str2, "map:/dev/null@%s", at);
} else {
unsigned long red_mask, green_mask, blue_mask;
red_mask = (client->format.redMax << client->format.redShift);
green_mask = (client->format.greenMax << client->format.greenShift);
blue_mask = (client->format.blueMax << client->format.blueShift);
sprintf(str2, "map:/dev/null@%dx%dx%d:0x%x/0x%x/0x%x",
client->width, client->height, client->format.bitsPerPixel,
red_mask, green_mask, blue_mask);
}
*raw_fb_addr = client->frameBuffer;
free(str0);
if (first) {
setup_cursors_and_push();
for (i=0; i<10; i++) {
vnc_reflect_process_client();
}
}
first = 0;
return strdup(str2);
}
rfbBool vnc_reflect_send_pointer(int x, int y, int mask) {
rfbBool ret;
int rc;
if (mask >= 0) {
got_user_input++;
got_pointer_input++;
last_pointer_time = time(NULL);
}
if (cursor_x != x || cursor_y != y) {
last_pointer_motion_time = dnow();
}
cursor_x = x;
cursor_y = y;
/* record the x, y position for the rfb screen as well. */
cursor_position(x, y);
/* change the cursor shape if necessary */
rc = set_cursor(x, y, get_which_cursor());
cursor_changes += rc;
return SendPointerEvent(client, x, y, mask);
}
rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down) {
return SendKeyEvent(client, key, down);
}
rfbBool vnc_reflect_send_cuttext(char *str, int len) {
return SendClientCutText(client, str, len);
}
void vnc_reflect_process_client(void) {
int num;
rfbBool save;
if (client == NULL) {
return;
}
num = WaitForMessage(client, 1000);
if (num > 0) {
if (!HandleRFBServerMessage(client)) {
rfbLog("vnc_reflect_process_client: read failure to server\n");
shut_down = 1;
}
}
}
#define RAWFB_MMAP 1
#define RAWFB_FILE 2
#define RAWFB_SHM 3
@ -842,6 +1131,7 @@ XImage *initialize_raw_fb(int reset) {
static XImage ximage_struct_snap;
int closedpy = 1, i, m, db = 0;
int do_macosx = 0;
int do_reflect = 0;
static char *last_file = NULL;
static int last_mode = 0;
@ -988,6 +1278,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
raw_fb_addr = NULL;
raw_fb_offset = 0;
raw_fb_bytes_per_line = 0;
rawfb_vnc_reflect = 0;
last_mode = 0;
if (last_file) {
@ -1023,6 +1314,18 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
str = str2;
rfbLog("console_guess returned: %s\n", str);
} else if (strstr(str, "vnc:") == str) {
char *str2 = vnc_reflect_guess(str, &raw_fb_addr);
rawfb_vnc_reflect = 1;
do_reflect = 1;
str = str2;
rfbLog("vnc_reflector set rawfb str to: %s\n", str);
if (pipeinput_str == NULL) {
pipeinput_str = strdup("VNC");
}
initialize_pipeinput();
}
if (closedpy && !view_only && got_noviewonly) {
@ -1222,6 +1525,12 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
b, raw_fb_addr, size);
last_mode = 0;
} else if (do_reflect) {
raw_fb_mmap = size;
rfbLog("rawfb: vnc fb: %s\n", q);
rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
b, raw_fb_addr, size);
last_mode = 0;
} else if (do_mmap) {
#if LIBVNCSERVER_HAVE_MMAP
@ -1987,6 +2296,20 @@ static void setup_rotating(void) {
}
}
static rfbBool set_xlate_wrapper(rfbClientPtr cl) {
static int first = 1;
if (first) {
first = 0;
} else if (ncache) {
int save = ncache_xrootpmap;
rfbLog("set_xlate_wrapper: clearing -ncache for new pixel format.\n");
ncache_xrootpmap = 0;
check_ncache(1, 0);
ncache_xrootpmap = save;
}
return rfbSetTranslateFunction(cl);
}
/*
* initialize the rfb framebuffer/screen
*/
@ -2507,6 +2830,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->kbdAddEvent = keyboard;
screen->ptrAddEvent = pointer;
screen->setXCutText = xcut_receive;
screen->setTranslateFunction = set_xlate_wrapper;
/* called from inetd, we need to treat stdio as our socket */
if (inetd && use_openssl) {

@ -23,7 +23,14 @@ extern void initialize_screen(int *argc, char **argv, XImage *fb);
extern void set_vnc_desktop_name(void);
extern void announce(int lport, int ssl, char *iface);
extern char *vnc_reflect_guess(char *str, char **raw_fb_addr);
extern void vnc_reflect_process_client(void);
extern rfbBool vnc_reflect_send_pointer(int x, int y, int mask);
extern rfbBool vnc_reflect_send_key(uint32_t key, rfbBool down);
extern rfbBool vnc_reflect_send_cuttext(char *str, int len);
extern int rawfb_reset;
extern int rawfb_dev_video;
extern int rawfb_vnc_reflect;
#endif /* _X11VNC_SCREEN_H */

@ -67,7 +67,10 @@ static int dt_cmd(char *cmd) {
set_env("DISPLAY", DisplayString(dpy));
}
rfbLog("running command:\n %s\n", cmd);
rfbLog("running command:\n");
if (!quiet) {
fprintf(stderr, "\n %s\n\n", cmd);
}
usr_bin_path(0);
close_exec_fds();
rc = system(cmd);
@ -96,7 +99,10 @@ static char *cmd_output(char *cmd) {
return "";
}
rfbLog("running pipe:\n %s\n", cmd);
rfbLog("running pipe:\n");
if (!quiet) {
fprintf(stderr, "\n %s\n\n", cmd);
}
usr_bin_path(0);
close_exec_fds();
p = popen(cmd, "r");
@ -113,6 +119,28 @@ static char *cmd_output(char *cmd) {
return(output);
}
static char *last_color = NULL;
unsigned long get_pixel(char *color) {
#if NO_X11
return 0;
#else
XColor cdef;
Colormap cmap;
unsigned long 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);
}
}
return pixel;
#endif
}
XImage *solid_root(char *color) {
#if NO_X11
RAWFB_RET_VOID
@ -126,7 +154,7 @@ XImage *solid_root(char *color) {
GC gc;
XSetWindowAttributes swa;
Visual visual;
unsigned long mask, pixel;
static unsigned long mask, pixel = 0;
XColor cdef;
Colormap cmap;
@ -148,8 +176,6 @@ XImage *solid_root(char *color) {
InputOutput, &visual, mask, &swa);
if (! color) {
/* restore the root window from the XImage snapshot */
pixmap = XCreatePixmap(dpy, window, wdpy_x, wdpy_y, depth);
if (! image) {
/* whoops */
@ -158,6 +184,8 @@ XImage *solid_root(char *color) {
return NULL;
}
/* restore the root window from the XImage snapshot */
pixmap = XCreatePixmap(dpy, window, wdpy_x, wdpy_y, depth);
/* draw the image to a pixmap: */
gcv.function = GXcopy;
@ -215,16 +243,7 @@ XImage *solid_root(char *color) {
}
/* 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);
}
}
pixel = get_pixel(color);
rfbLog("setting solid background...\n");
XSetWindowBackground(dpy, window, pixel);
@ -593,6 +612,100 @@ static void solid_gnome(char *color) {
#endif /* NO_X11 */
}
static char *dcop_session(void) {
#if NO_X11
RAWFB_RET("");
return "";
#else
char list_sessions[] = "dcop --user '%s' --list-sessions";
int len;
char *cmd, *host, *user = NULL;
char *out, *p, *ds, *dsn = NULL, *sess = NULL, *sess2 = NULL;
RAWFB_RET("");
if (getenv("SESSION_MANAGER")) {
return "";
}
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("invalid user: %s\n", user);
free(user);
return "";
}
len = strlen(list_sessions) + strlen(user) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, list_sessions, user);
out = strdup(cmd_output(cmd));
free(cmd);
free(user);
ds = DisplayString(dpy);
if (!ds || !strcmp(ds, "")) {
ds = getenv("DISPLAY");
}
if (!ds) {
ds = ":0";
}
ds = strdup(ds);
dsn = strchr(ds, ':');
if (dsn) {
*dsn = '_';
} else {
free(ds);
ds = strdup("_0");
dsn = ds;
}
host = this_host();
p = strtok(out, "\n");
while (p) {
char *q = strstr(p, ".DCOP");
if (q == NULL) {
;
} else if (host) {
if (strstr(q, host)) {
if(strstr(p, dsn)) {
sess = strdup(q);
break;
} else {
if (sess2) {
free(sess2);
}
sess2 = strdup(q);
}
}
} else {
if(strstr(p, dsn)) {
sess = strdup(q);
break;
}
}
p = strtok(NULL, "\n");
}
free(ds);
free(out);
if (!sess && sess2) {
sess = sess2;
}
if (!sess || strchr(sess, '\'')) {
if (sess) free(sess);
sess = strdup("--all-sessions");
} else {
len = strlen("--session ") + 2 + strlen(sess) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, "--session '%s'", sess);
free(sess);
sess = cmd;
}
return sess;
#endif
}
static void solid_kde(char *color) {
#if NO_X11
RAWFB_RET_VOID
@ -600,12 +713,12 @@ static void solid_kde(char *color) {
return;
#else
char set_color[] =
"dcop --user '%s' kdesktop KBackgroundIface setColor '%s' 1";
"dcop --user '%s' %s kdesktop KBackgroundIface setColor '%s' 1";
char bg_off[] =
"dcop --user '%s' kdesktop KBackgroundIface setBackgroundEnabled 0";
"dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 0";
char bg_on[] =
"dcop --user '%s' kdesktop KBackgroundIface setBackgroundEnabled 1";
char *cmd, *user = NULL;
"dcop --user '%s' %s kdesktop KBackgroundIface setBackgroundEnabled 1";
char *cmd, *user = NULL, *sess;
int len;
RAWFB_RET_VOID
@ -617,13 +730,19 @@ static void solid_kde(char *color) {
return;
}
set_env("DISPLAY", DisplayString(dpy));
if (! color) {
len = strlen(bg_on) + strlen(user) + 1;
sess = dcop_session();
len = strlen(bg_on) + strlen(user) + strlen(sess) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, bg_on, user);
sprintf(cmd, bg_on, user, sess);
dt_cmd(cmd);
free(cmd);
free(user);
free(sess);
return;
}
@ -633,21 +752,134 @@ static void solid_kde(char *color) {
return;
}
len = strlen(set_color) + strlen(user) + strlen(color) + 1;
sess = dcop_session();
len = strlen(set_color) + strlen(user) + strlen(sess) + strlen(color) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, set_color, user, color);
sprintf(cmd, set_color, user, sess, color);
dt_cmd(cmd);
free(cmd);
len = strlen(bg_off) + strlen(user) + 1;
len = strlen(bg_off) + strlen(user) + strlen(sess) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, bg_off, user);
sprintf(cmd, bg_off, user, sess);
dt_cmd(cmd);
free(cmd);
free(user);
#endif /* NO_X11 */
}
void kde_no_animate(int restore) {
#if NO_X11
if (!restore) {}
RAWFB_RET_VOID
return;
#else
char query_setting[] =
"kreadconfig --file kwinrc --group Windows --key AnimateMinimize";
char kwinrc_off[] =
"kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool false";
char kwinrc_on[] =
"kwriteconfig --file kwinrc --group Windows --key AnimateMinimize --type bool true";
char kwin_reconfigure[] =
"dcop --user '%s' %s kwin KWinInterface reconfigure";
char *cmd, *cmd2, *out, *user = NULL, *sess;
int len;
static int anim_state = 1;
RAWFB_RET_VOID
if (ncache_keep_anims) {
return;
}
if (restore) {
if (anim_state == 1) {
return;
}
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("invalid user: %s\n", user);
free(user);
return;
}
sess = dcop_session();
len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, kwin_reconfigure, user, sess);
rfbLog("\n");
rfbLog("Restoring KDE kwinrc settings.\n");
rfbLog("\n");
dt_cmd(cmd);
free(cmd);
free(user);
free(sess);
anim_state = 1;
return;
} else {
if (anim_state == 0) {
return;
}
anim_state = 0;
}
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("invalid user: %s\n", user);
free(user);
return;
}
out = cmd_output(query_setting);
if (!out || strstr(out, "false")) {
rfbLog("\n");
rfbLog("********************************************************\n");
rfbLog("KDE kwinrc AnimateMinimize is false. Good.\n");
rfbLog("********************************************************\n");
rfbLog("\n");
free(user);
return;
}
rfbLog("\n");
rfbLog("********************************************************\n");
rfbLog("To improve the -ncache client-side caching performance\n");
rfbLog("temporarily setting KDE kwinrc AnimateMinimize to false.\n");
rfbLog("It will be reset for the next session or when VNC client\n");
rfbLog("disconnects. Or you can use the Control Center GUI to\n");
rfbLog("change it now (toggle its setting a few times):\n");
rfbLog(" Desktop -> Window Behavior -> Moving\n");
rfbLog("********************************************************\n");
rfbLog("\n");
set_env("DISPLAY", DisplayString(dpy));
sess = dcop_session();
len = strlen(kwin_reconfigure) + strlen(user) + strlen(sess) + 1;
cmd = (char *) malloc(len);
sprintf(cmd, kwin_reconfigure, user, sess);
len = 1 + strlen(kwinrc_off) + 2 + strlen(cmd) + 2 + strlen("sleep 5") + 2 + strlen(kwinrc_on) + 3 + 1;
cmd2 = (char *) malloc(len);
sprintf(cmd2, "(%s; %s; sleep 5; %s) &", kwinrc_off, cmd, kwinrc_on);
dt_cmd(cmd2);
free(cmd);
free(cmd2);
free(user);
free(sess);
#endif /* NO_X11 */
}
void gnome_no_animate(void) {
;
}
char *guess_desktop(void) {
#if NO_X11
RAWFB_RET("root")
@ -710,6 +942,42 @@ char *guess_desktop(void) {
#endif /* NO_X11 */
}
XImage *solid_image(char *color) {
#if NO_X11
RAWFB_RET(NULL)
return NULL;
#else
XImage *image = NULL;
unsigned long pixel = 0;
int x, y;
RAWFB_RET(NULL)
if (!color) {
color = last_color;
}
if (!color) {
return NULL;
}
image = XGetImage(dpy, rootwin, 0, 0, wdpy_x, wdpy_y, AllPlanes,
ZPixmap);
if (!image) {
return NULL;
}
pixel = get_pixel(color);
for (y=0; y<wdpy_y; y++) {
for (x=0; x<wdpy_x; x++) {
XPutPixel(image, x, y, pixel);
}
}
return image;
#endif /* NO_X11 */
}
void solid_bg(int restore) {
static int desktop = -1;
static int solid_on = 0;
@ -770,6 +1038,11 @@ void solid_bg(int restore) {
color = solid_default;
}
}
if (last_color) {
free(last_color);
}
last_color = strdup(color);
if (!strcmp(dtname, "gnome")) {
desktop = 1;
solid_gnome(color);

@ -4,7 +4,11 @@
/* -- solid.h -- */
extern char *guess_desktop(void);
extern unsigned long get_pixel(char *color);
extern XImage *solid_image(char *color);
extern void solid_bg(int restore);
extern XImage *solid_root(char *color);
extern void kde_no_animate(int restore);
extern void gnome_no_animate(void);
#endif /* _X11VNC_SOLID_H */

@ -688,7 +688,7 @@ char find_display[] =
"# x11vnc then uses the info to open the display.\n"
"#\n"
"\n"
"FIND_DISPLAY_OUTPUT=/tmp/fdo.txt\n"
"#FIND_DISPLAY_OUTPUT=/tmp/fdo.$USER.txt\n"
"if [ \"X$FIND_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" if [ \"X$FIND_DISPLAY_EXEC\" = \"X\" ]; then\n"
" FIND_DISPLAY_EXEC=1\n"
@ -747,72 +747,112 @@ char find_display[] =
"# Now try to match X DISPLAY to user:\n"
"\n"
"# who(1) output column 2:\n"
"display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | head -1 \\\n"
" | awk '{print $2}'`\n"
"\n"
"if [ \"X$display\" = \"X\" ]; then\n"
" # who(1) output, last column:\n"
" display=`who | grep \"^${user}[ ]\" | awk '{print $NF}' \\\n"
" | grep '(:[0-9]' | sed -e 's/[()]//g' | head -1`\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
"#gone=`last $user | grep 'gone.*no.logout' | awk '{print $2}' | grep '^:' | sed -e 's,/.*,,' | tr '\\n' '|'`\n"
"#gone=\"${gone}__quite_impossible__\"\n"
"#display=`who | grep \"^${user}[ ][ ]*:[0-9]\" | egrep -v \" ($gone)\\>\" | head -1 \\\n"
"# | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
"poss=\"\"\n"
"list=`who | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
"list=\"$list \"`w -h \"$user\" | grep \"^${user}[ ][ ]*:[0-9]\" | awk '{print $2}' | sed -e 's,/.*$,,'`\n"
"list=\"$list \"`who | grep \"^${user}[ ]\" | awk '{print $NF}' | grep '(:[0-9]' | sed -e 's/[()]//g'`\n"
"host=`hostname | sed -e 's/\\..*$//'`\n"
"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" = \"X\" ]; then\n"
" list=\"$list \"`xauth list | awk '{print $1}' | grep /unix | grep \"^${host}\" | sed -e 's/^.*:/:/' | sort -n | uniq`\n"
"fi\n"
"uname=`uname`\n"
"nsout=`netstat -an`\n"
"psout=`ps -ef`\n"
"for p in $list\n"
"do\n"
" d=`echo \"$p\" | sed -e 's/://' -e 's/\\..*$//'`\n"
" ok=\"\"\n"
" xd=\"/tmp/.X11-unix/X$d\"\n"
" if [ -r \"$xd\" -o -w \"$xd\" -o -x \"$xd\" ]; then\n"
" if echo \"$nsout\" | grep \"/tmp/.X11-unix/X$d[ ]*\\$\" > /dev/null; then\n"
" ok=1\n"
" fi\n"
" # loop over xauth list items machine ^hostname/unix:N\n"
" host=`hostname | sed -e 's/\\..*$//'`\n"
" tries1=\"\"\n"
" tries2=\"\"\n"
" for d in `xauth list | awk '{print $1}' | grep /unix \\\n"
" | grep \"^${host}\" | sed -e 's/^.*://' | sort -n | uniq`\n"
" do\n"
" if [ -e \"/tmp/.X$d-lock\" -o -e \"/tmp/.X11-unix/X$d\" ]; then\n"
" tries1=\"$tries1 $d\"\n"
" else\n"
" # these are often ssh X redirs so try them last or skip:\n"
" #tries2=\"$tries2 $d\"\n"
" :\n"
" fi\n"
" if [ \"X$ok\" = \"X\" ]; then\n"
" if [ -f \"/tmp/.X$d-lock\" ]; then\n"
" pid=`cat \"/tmp/.X$d-lock\" | sed -e 's/[ ]//g'`\n"
" if echo \"$pid\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" if [ \"X$uname\" = \"XLinux\" -o \"X$uname\" = \"XSunOS\" ]; then\n"
" if [ -d \"/proc/$pid\" ]; then\n"
" ok=1\n"
" fi\n"
" elif echo \"$ps_out\" | awk '{print $2}' | grep -w \"$pid\" > /dev/null; then\n"
" ok=1\n"
" fi\n"
" fi\n"
" done\n"
" \n"
" fi\n"
" fi\n"
" if [ \"X$ok\" = \"X1\" ]; then\n"
" poss=\"$poss $p\"\n"
" fi\n"
"done\n"
"\n"
" for d in $tries1 $tries2\n"
" do\n"
" xdpyinfo -display \":$d\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" # try again with no authority:\n"
" env XAUTHORITY=/dev/null xdpyinfo \\\n"
" -display \":$d\" >/dev/null 2>&1\n"
" # 0 means got in for free... skip it.\n"
" if [ $? != 0 ]; then\n"
" # keep it\n"
" display=\":$d\"\n"
" break\n"
"poss=`echo \"$poss\" | sed -e 's/^ *//' -e 's/ *$//'`\n"
"\n"
"if [ \"X$X11VNC_FINDDISPLAY_SKIP_XAUTH\" != \"X\" ]; then\n"
" display=`echo \"$poss\" | tr ' ' '\\n' | head -1`\n"
"else\n"
" freebie=\"\"\n"
" for p in $poss\n"
" do\n"
" xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
" if [ $? = 0 ]; then\n"
" # try again with no authority:\n"
" env XAUTHORITY=/dev/null xdpyinfo -display \"$p\" >/dev/null 2>&1\n"
" # 0 means got in for free... skip it.\n"
" if [ $? != 0 ]; then\n"
" # keep it\n"
" display=\"$p\"\n"
" break\n"
" else\n"
" if [ \"X$freebie\" = \"X\" ]; then\n"
" freebie=\"$p\"\n"
" fi\n"
" fi\n"
" done\n"
" if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
" fi\n"
" done\n"
" if [ \"X$display\" = \"X\" -a \"X$freebie\" != \"X\" ]; then\n"
" display=\"$freebie\"\n"
" fi\n"
"fi\n"
"\n"
"if [ \"X$display\" = \"X\" ]; then\n"
" echo \"\" # failure\n"
" exit 1\n"
"fi\n"
"\n"
"chvt=\"\"\n"
"if [ \"X`uname`\" = \"XLinux\" ]; then\n"
" vt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | grep \" $display \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
"if [ \"X$uname\" = \"XLinux\" ]; then\n"
" d2=$display\n"
" d3=`echo \"$d2\" | sed -e 's/^.*:/:/' -e 's/\\..*$//'`\n"
" d4=\"($d2|$d3)\"\n"
" vt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | egrep ' vt([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* vt\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" fi\n"
" else\n"
" vt=`ps wwwwwaux | grep X | grep \" $display \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" vt=`ps wwwwwaux | grep X | egrep \" $d4 \" | egrep ' tty([789]|[1-9][0-9][0-9]*) ' | grep -v grep | head -1`\n"
" if [ \"X$vt\" != \"X\" ]; then\n"
" vt=`echo \"$vt\" | sed -e 's/^.* tty\\([0-9][0-9]*\\) .*$/\\1/'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" fi\n"
" else\n"
" pvt=`ps wwwwwaux | grep X | egrep -v 'startx|xinit' | egrep \" $d4 \" | head -1 | awk '{print $2}'`\n"
" if [ \"X$pvt\" != \"X\" ]; then\n"
" vt=`lsof -p \"$pvt\" | egrep '/dev/tty([789]|[1-9][0-9][0-9]*)$' | grep -v grep | head -1 | awk '{print $NF}' | sed -e 's,/dev/tty,,'`\n"
" if echo \"$vt\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" chvt=\",VT=$vt\"\n"
" else\n"
" chvt=\",XPID=$pvt\"\n"
" fi\n"
" fi\n"
" fi\n"
" fi\n"
"fi\n"
@ -822,7 +862,6 @@ char find_display[] =
" xauth extract - \"$display\" 2>/dev/null\n"
"fi\n"
"\n"
"\n"
"exit 0\n"
;
@ -830,17 +869,20 @@ char create_display[] =
"#!/bin/sh\n"
"\n"
"#CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\n"
"if [ \"X$CREATE_DISPLAY_EXEC\" = \"X\" ]; then\n"
" CREATE_DISPLAY_EXEC=1\n"
" export CREATE_DISPLAY_EXEC\n"
" if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" /bin/sh $0 \"$@\" 2> $CREATE_DISPLAY_OUTPUT\n"
" else\n"
" /bin/sh $0 \"$@\" 2> /dev/null\n"
"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" if [ \"X$CREATE_DISPLAY_EXEC\" = \"X\" ]; then\n"
" CREATE_DISPLAY_EXEC=1\n"
" export CREATE_DISPLAY_EXEC\n"
" if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" /bin/sh $0 \"$@\" 2> $CREATE_DISPLAY_OUTPUT\n"
" else\n"
" /bin/sh $0 \"$@\" 2> /dev/null\n"
" fi\n"
" exit $?\n"
" fi\n"
" exit $?\n"
"fi\n"
"\n"
"\n"
"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" set -xv\n"
"fi\n"
@ -848,17 +890,44 @@ char create_display[] =
"findfree() {\n"
" try=20\n"
" n=\"\"\n"
" nsout=\"\"\n"
" if [ \"X$have_netstat\" != \"X\" ]; then\n"
" nsout=`$have_netstat -an`\n"
" fi\n"
" while [ $try -lt 99 ]\n"
" do\n"
" if [ ! -e \"/tmp/.X${try}-lock\" ]; then\n"
" n=$try\n"
" break\n"
" if [ ! -f \"/tmp/.X${try}-lock\" ]; then\n"
" if echo \"$nsout\" | grep \"/tmp/.X11-unix/X${try}[ ]*\\$\" > /dev/null; then\n"
" :\n"
" else\n"
" n=$try\n"
" break\n"
" fi\n"
" fi\n"
" try=`expr $try + 1`\n"
" done\n"
" echo \"$n\"\n"
"}\n"
"\n"
"random() {\n"
" if [ \"X$RANDOM\" != \"X\" ]; then\n"
" echo \"$RANDOM\"\n"
" else\n"
" r1=`bash -c 'echo $RANDOM' 2>/dev/null`\n"
" if echo \"$r1\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" echo \"$r1\"\n"
" else\n"
" r2=`sh -c 'echo $$; date; ps -elf' 2>/dev/null | sum -r 2>/dev/null | awk '{print $1}'`\n"
" if echo \"$r2\" | grep '^[0-9][0-9]*$' > /dev/null; then\n"
" echo \"$r2\"\n"
" else\n"
" r3=`sh -c 'echo $$'`\n"
" echo \"$r3\"\n"
" fi\n"
" fi\n"
" fi\n"
"}\n"
"\n"
"findsession() {\n"
" if [ \"X$session\" != \"X\" ]; then\n"
" echo \"$session\"\n"
@ -927,21 +996,30 @@ char create_display[] =
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" sess=\"env DISPLAY=:$N $sess\"\n"
" fi\n"
" rmf=\"/nosuch\"\n"
" if echo \"$sess\" | grep '[ ]' > /dev/null; then\n"
" stmp=/tmp/.cd$$\n"
" stmp=/tmp/.cd$$`random`\n"
" rm -f $stmp\n"
" if [ -f $stmp ]; then\n"
" exit 1\n"
" fi\n"
" touch $stmp\n"
" chmod 755 $stmp\n"
" chmod 755 $stmp || exit 1\n"
" echo \"#!/bin/sh\" > $stmp\n"
" echo \"$sess\" >> $stmp\n"
" echo \"sleep 1\" >> $stmp\n"
" echo \"rm -f $stmp\" >> $stmp\n"
" sess=$stmp\n"
" rmf=\"$stmp\"\n"
" fi\n"
" if [ \"X$have_root\" != \"X\" -a \"X$USER\" != \"Xroot\" ]; then\n"
" ctmp=\"/tmp/.xa.$$\"\n"
" ctmp=/tmp/.xat$$`random`\n"
" rm -f $ctmp\n"
" if [ -f $ctmp ]; then\n"
" exit 1\n"
" fi\n"
" touch $ctmp\n"
" chmod 644 $ctmp\n"
" chmod 644 $ctmp || exit 1\n"
" $have_xauth -f $authfile nextract - :$N > $ctmp\n"
" su - $USER -c \"$have_xauth nmerge - < $ctmp\" 1>&2\n"
" $have_xauth -f $authfile nextract - `hostname`:$N > $ctmp\n"
@ -954,18 +1032,25 @@ char create_display[] =
" $have_xauth -f $authfile nextract - :$N | $have_xauth nmerge -\n"
" $have_xauth -f $authfile nextract - `hostname`:$N | $have_xauth nmerge -\n"
" fi\n"
" \n"
" if [ \"X$have_startx\" != \"X\" ]; then\n"
" echo \"$have_startx $sess -- $* -auth $authfile\" 1>&2\n"
" $have_startx $sess -- $* -auth $authfile 1>&2 &\n"
"\n"
" if [ \"X$use_xdmcp_query\" = \"X1\" ]; then\n"
" # we cannot use -nolisten tcp\n"
" #echo \"$* -from localhost -once -query localhost\"\n"
" #nohup $* -from localhost -once -query localhost 1>&2 &\n"
" echo \"$* -once -query localhost\" 1>&2\n"
" nohup $* -once -query localhost 1>&2 &\n"
" pid=$!\n"
" elif [ \"X$have_startx\" != \"X\" ]; then\n"
" echo \"$have_startx $sess -- $* -nolisten tcp -auth $authfile\" 1>&2\n"
" $have_startx $sess -- $* -nolisten tcp -auth $authfile 1>&2 &\n"
" pid=$!\n"
" elif [ \"X$have_xinit\" != \"X\" ]; then\n"
" echo \"$have_xinit $sess -- $* -auth $authfile\" 1>&2\n"
" $have_xinit $sess -- $* -auth $authfile 1>&2 &\n"
" echo \"$have_xinit $sess -- $* -nolisten tcp -auth $authfile\" 1>&2\n"
" $have_xinit $sess -- $* -nolisten tcp -auth $authfile 1>&2 &\n"
" pid=$!\n"
" else\n"
" echo \"$*\"\n"
" nohup $* 1>&2 &\n"
" echo \"$* -nolisten tcp -auth $authfile\" 1>&2\n"
" nohup $* -nolisten tcp -auth $authfile 1>&2 &\n"
" pid=$!\n"
" nohup $sess 1>&2 &\n"
" fi\n"
@ -975,15 +1060,31 @@ char create_display[] =
" else\n"
" result=0\n"
" fi\n"
" #(sleep 120; rm -f $authfile) &\n"
" if uname | grep SunOS > /dev/null; then\n"
" nohup sh -c \"(sleep 60; rm -f $rmf)\" 1>&2 &\n"
" else\n"
" nohup sh -c \"(sleep 60; rm -f $rmf $authfile)\" 1>&2 &\n"
" fi\n"
"}\n"
"\n"
"try_X() {\n"
" if [ \"X$have_xinit\" != \"X\" ]; then\n"
" if [ \"X$use_xdmcp_query\" = \"X1\" ]; then\n"
" if [ \"X$have_X\" != \"X\" ]; then\n"
" server $have_X :$N\n"
" elif [ \"X$have_Xorg\" != \"X\" ]; then\n"
" server $have_Xorg :$N\n"
" elif [ \"X$have_XFree86\" != \"X\" ]; then\n"
" server $have_XFree86 :$N\n"
" elif [ \"X$have_Xsun\" != \"X\" ]; then\n"
" server $have_Xsun :$N\n"
" fi\n"
" elif [ \"X$have_xinit\" != \"X\" ]; then\n"
" save_have_startx=$have_startx\n"
" have_startx=\"\"\n"
" server :$N\n"
" have_startx=$save_have_startx\n"
" else\n"
" server :$N\n"
" fi\n"
"}\n"
"\n"
@ -1008,7 +1109,17 @@ char create_display[] =
"\n"
" #save_have_startx=$have_startx\n"
" #have_startx=\"\"\n"
" server $have_Xvfb :$N -screen 0 ${geom}x${depth}\n"
" sarg=\"-screen\"\n"
" if uname | grep SunOS > /dev/null; then\n"
" if grep /usr/openwin/bin/Xsun $have_Xvfb > /dev/null; then\n"
" sarg=\"screen\"\n"
" if [ \"X$depth\" = \"X16\" ]; then\n"
" #depth=24\n"
" :\n"
" fi\n"
" fi\n"
" fi\n"
" server $have_Xvfb :$N $sarg 0 ${geom}x${depth}\n"
" #have_startx=$save_have_startx\n"
"\n"
" if [ \"X$result\" = \"X1\" -a \"X$have_xmodmap\" != \"X\" ]; then\n"
@ -1031,23 +1142,25 @@ char create_display[] =
" if [ \"X$have_mcookie\" != \"X\" ]; then\n"
" cookie=`mcookie`\n"
" elif [ \"X$have_md5sum\" != \"X\" ]; then\n"
" if [ -e /dev/urandom ]; then\n"
" if [ -c /dev/urandom ]; then\n"
" cookie=`dd if=/dev/urandom count=32 2>/dev/null | md5sum | awk '{print $1}'`\n"
" elif [ -e /dev/random ]; then\n"
" elif [ -c /dev/random ]; then\n"
" cookie=`dd if=/dev/random count=32 2>/dev/null | md5sum | awk '{print $1}'`\n"
" fi\n"
" if [ \"X$cookie\" = \"X\" ]; then\n"
" cookie=`(echo $RANDOM; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n"
" r=`random`\n"
" cookie=`(echo $r; date; uptime; ps -ealf 2>&1) | md5sum | awk '{print $1}'`\n"
" fi\n"
" elif [ \"X$have_xauth\" != \"X\" ]; then\n"
" cookie=`$have_xauth list | awk '{print $NF}' | tail -1`\n"
" fi\n"
" if [ \"X$cookie\" = \"X\" ]; then\n"
" # oh well..\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" cookie=$cookie`printf \"%08x\" \"$RANDOM$$\"`\n"
" for k in 1 2 3 4\n"
" do\n"
" r=`random`\n"
" cookie=$cookie`printf \"%08x\" \"${r}$$\"`\n"
" done\n"
" fi\n"
" echo \"$cookie\"\n"
"}\n"
@ -1056,10 +1169,13 @@ char create_display[] =
" if [ \"X$have_xauth\" = \"X\" ]; then\n"
" exit 1\n"
" fi\n"
" tmp=\"/tmp/.xauth$$$RANDOM\"\n"
" tmp=/tmp/.xas$$`random`\n"
" rm -f $tmp\n"
" if [ -f $tmp ]; then\n"
" exit 1\n"
" fi\n"
" touch $tmp\n"
" chmod 600 $tmp\n"
" chmod 600 $tmp || exit 1\n"
" if [ ! -f $tmp ]; then\n"
" exit 1\n"
" fi\n"
@ -1073,13 +1189,6 @@ char create_display[] =
"depth=${depth:-16}\n"
"geom=${geom:-1280x1024}\n"
"\n"
"N=`findfree`\n"
"\n"
"if [ \"X$N\" = \"X\" ]; then\n"
" exit 1\n"
"fi\n"
"echo \"trying N=$N ...\" 1>&2\n"
"\n"
"if [ \"X$USER\" = \"X\" ]; then\n"
" USER=$LOGNAME\n"
"fi\n"
@ -1087,7 +1196,7 @@ char create_display[] =
" USER=`whoami`\n"
"fi\n"
"\n"
"PATH=$PATH:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin\n"
"PATH=$PATH:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/usr/dt/bin:/opt/kde3/bin:/opt/gnome/bin:/usr/bin:/bin:/usr/sfw/bin\n"
"\n"
"have_root=\"\"\n"
"id0=`id`\n"
@ -1095,17 +1204,38 @@ char create_display[] =
" have_root=\"1\"\n"
"fi\n"
"\n"
"for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb xauth mcookie md5sum xmodmap startkde gnome-session blackbox fvwm mwm openbox twm windowmaker metacity\n"
"p_ok=0\n"
"if [ \"`type -p /bin/sh`\" = \"/bin/sh\" ]; then\n"
" p_ok=1\n"
"fi\n"
"\n"
"for prog in startx xinit xdm gdm kdm xterm Xdummy Xvfb xauth mcookie md5sum xmodmap startkde gnome-session blackbox fvwm mwm openbox twm windowmaker metacity X Xorg XFree86 Xsun Xsession netstat\n"
"do\n"
" p2=`echo \"$prog\" | sed -e 's/-/_/g'`\n"
" eval \"have_$p2=''\"\n"
" if type $prog > /dev/null 2>&1; then\n"
" eval \"have_$p2=`which $prog`\"\n"
" bpath=`which $prog | awk '{print $NF}'`\n"
" if [ ! -x \"$bpath\" -o -d \"$bpath\" ]; then\n"
" if [ \"X$p_ok\" = \"X1\" ]; then\n"
" bpath=`type -p $prog | awk '{print $NF}'`\n"
" fi\n"
" if [ ! -x \"$bpath\" -o -d \"$bpath\" ]; then\n"
" bpath=`type $prog | awk '{print $NF}'`\n"
" fi\n"
" fi\n"
" eval \"have_$p2=$bpath\"\n"
" fi\n"
"done\n"
"\n"
"N=`findfree`\n"
"\n"
"if [ \"X$N\" = \"X\" ]; then\n"
" exit 1\n"
"fi\n"
"echo \"trying N=$N ...\" 1>&2\n"
"\n"
"if [ \"X$CREATE_DISPLAY_OUTPUT\" != \"X\" ]; then\n"
" set | grep ^have_ 1>&2\n"
" set | grep \"^have_\" 1>&2\n"
"fi\n"
"\n"
"TRY=\"$1\"\n"
@ -1116,6 +1246,12 @@ char create_display[] =
"for curr_try in `echo \"$TRY\" | tr ',' ' '`\n"
"do\n"
" result=0\n"
" use_xdmcp_query=0\n"
" if echo \"$curr_try\" | egrep '[+.-]xdmcp' > /dev/null; then\n"
" use_xdmcp_query=1\n"
" fi\n"
" curr_try=`echo \"$curr_try\" | sed -e 's/[+.-]xdmcp//'`\n"
" \n"
" if echo \"$curr_try\" | grep -iw \"Xdummy\" > /dev/null; then\n"
" try_Xdummy\n"
" elif echo \"$curr_try\" | grep -iw \"Xvfb\" > /dev/null; then\n"

@ -135,6 +135,7 @@ Clients
Displays
=D display:
=F auth:
=S reflect:
=D desktop:
=D rfbport:
=0 gui:
@ -369,6 +370,7 @@ Tuning
ncache_no_moveraise
ncache_no_dtchange
ncache_no_rootpixmap
ncache_keep_anims
=A ncache_reset_rootpixmap
=GAL LOFF
--

@ -146,6 +146,7 @@ char gui_code[] = "";
"Displays\n"
" =D display:\n"
" =F auth:\n"
" =S reflect:\n"
" =D desktop:\n"
" =D rfbport:\n"
" =0 gui:\n"
@ -380,6 +381,7 @@ char gui_code[] = "";
" ncache_no_moveraise\n"
" ncache_no_dtchange\n"
" ncache_no_rootpixmap\n"
" ncache_keep_anims\n"
" =A ncache_reset_rootpixmap\n"
" =GAL LOFF\n"
" --\n"

@ -62,7 +62,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
void unixpw_accept(char *user);
void unixpw_deny(void);
void unixpw_msg(char *msg, int delay);
int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp);
int crypt_verify(char *user, char *pass);
int cmd_verify(char *user, char *pass);
@ -552,7 +552,7 @@ int cmd_verify(char *user, char *pass) {
}
}
int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp) {
#ifndef UNIXPW_SU
return 0;
#else
@ -624,6 +624,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
return 0;
}
if (db) fprintf(stderr, "cmd is: %s\n", cmd);
if (db) fprintf(stderr, "slave is: %s fd=%d\n", slave, fd);
if (fd < 0) {
@ -729,10 +730,19 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
set_env("LC_ALL", "C");
set_env("LANG", "C");
set_env("SHELL", "/bin/sh");
if (!cmd && getenv("DISPLAY")) {
if (nodisp) {
/* this will cause timeout problems with pam_xauth */
char *s = getenv("DISPLAY");
if (s) *(s-2) = '_'; /* quite... */
int k;
for (k=0; k<3; k++) {
if (getenv("DISPLAY")) {
char *s = getenv("DISPLAY");
if (s) *(s-2) = '_'; /* quite... */
}
if (getenv("XAUTHORITY")) {
char *s = getenv("XAUTHORITY");
if (s) *(s-2) = '_'; /* quite... */
}
}
}
/* synchronize with parent: */
@ -874,6 +884,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
return 0;
}
if (db > 2) fprintf(stderr, "\nsending passwd: %s\n", pass);
usleep(100 * 1000);
if (slow_pw) {
unsigned int k;
@ -899,6 +910,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
drain_size = *rbuf_size;
rsize = 0;
}
if (db) fprintf(stderr, "\ndraining:\n");
for (i = 0; i< drain_size; i++) {
int n;
@ -907,12 +919,13 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
n = read(fd, cbuf, 1);
if (n < 0 && errno == EINTR) {
if (db) fprintf(stderr, "\nEINTR n=%d i=%d --", n, i);
i--;
if (i < 0) i = 0;
continue;
}
if (db) fprintf(stderr, "%s", cbuf);
if (db) fprintf(stderr, "\nn=%d i=%d errno=%d %.6f '%s'", n, i, errno, dnowx(), cbuf);
if (n <= 0) {
break;
@ -921,6 +934,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
rbuf[rsize++] = cbuf[0];
}
}
if (db && rbuf) fprintf(stderr, "\nrbuf: '%s'\n", rbuf);
if (rbuf && *rbuf_size > 0) {
char *s = rbuf;
@ -961,7 +975,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size) {
free(p);
}
if (db) fprintf(stderr, "\n");
if (db) fprintf(stderr, "\n--\n");
alarm(0);
signal(SIGALRM, SIG_DFL);
@ -1042,7 +1056,7 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
ok = 0;
}
} else {
if (su_verify(user, pass, NULL, NULL, NULL)) {
if (su_verify(user, pass, NULL, NULL, NULL, 1)) {
rfbLog("unixpw_verify: su_verify login for '%s'"
" succeeded.\n", user);
ok = 1;

@ -9,7 +9,7 @@ extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
extern void unixpw_accept(char *user);
extern void unixpw_deny(void);
extern void unixpw_msg(char *msg, int delay);
extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
extern int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size, int nodisp);
extern int crypt_verify(char *user, char *pass);
extern int cmd_verify(char *user, char *pass);

@ -1241,6 +1241,10 @@ int wait_for_client(int *argc, char** argv, int http) {
return 0;
}
if (getenv("WAIT_FOR_CLIENT_DB")) {
db = 1;
}
for (i=0; i < *argc; i++) {
if (!strcmp(argv[i], "-desktop")) {
dt = 1;
@ -1435,6 +1439,7 @@ int wait_for_client(int *argc, char** argv, int http) {
char line2[16384];
char *q;
int n;
int nodisp = 0;
memset(line1, 0, 1024);
memset(line2, 0, 16384);
@ -1447,9 +1452,10 @@ int wait_for_client(int *argc, char** argv, int http) {
rfbLogPerror("mkstemp");
clean_up_exit(1);
}
chmod(tmp, 0644);
write(tmp_fd, find_display, strlen(find_display));
close(tmp_fd);
chmod(tmp, 0644);
nodisp = 1;
if (strstr(cmd, "FINDCREATEDISPLAY") == cmd) {
char *opts = strchr(cmd, '-');
@ -1487,10 +1493,10 @@ if (db) fprintf(stderr, "create_cmd: %s\n", create_cmd);
if (keep_unixpw_user && keep_unixpw_pass) {
n = 18000;
res = su_verify(keep_unixpw_user,
keep_unixpw_pass, cmd, line, &n);
keep_unixpw_pass, cmd, line, &n, nodisp);
}
if (db) write(2, line, n); write(2, "\n", 1);
if (db) {fprintf(stderr, "line: "); write(2, line, n); write(2, "\n", 1); fprintf(stderr, "res=%d n=%d\n", res, n);}
if (! res && create_cmd) {
FILE *mt = fopen(tmp, "w");
@ -1506,7 +1512,7 @@ if (db) write(2, line, n); write(2, "\n", 1);
/* if not root, run as the other user... */
n = 18000;
res = su_verify(keep_unixpw_user,
keep_unixpw_pass, create_cmd, line, &n);
keep_unixpw_pass, create_cmd, line, &n, nodisp);
/*if (1) fprintf(stderr, "line: '%s'\n", line); */
} else {
@ -1576,8 +1582,8 @@ if (db) fprintf(stderr, "line1: '%s'\n", line1);
line2[i] = q[k+j];
i++;
}
write(2, line, 100);
fprintf(stderr, "\n");
if (db) write(2, line, 100);
if (db) fprintf(stderr, "\n");
} else {
FILE *p;
int rc;
@ -1641,6 +1647,7 @@ fprintf(stderr, "\n");
}
}
if (db) fprintf(stderr, "line1=%s\n", line1);
if (strstr(line1, "DISPLAY=") != line1) {
rfbLog("wait_for_client: bad reply '%s'\n", line1);
@ -1648,6 +1655,7 @@ fprintf(stderr, "\n");
clean_up_exit(1);
}
if (strstr(line1, ",VT=")) {
int vt;
char *t = strstr(line1, ",VT=");
@ -1660,6 +1668,41 @@ fprintf(stderr, "\n");
system(chvt);
sleep(2);
}
} else if (strstr(line1, ",XPID=")) {
int i, pvt, vt = -1;
char *t = strstr(line1, ",XPID=");
pvt = atoi(t + strlen(",XPID="));
*t = '\0';
if (pvt > 0) {
for (i=3; i <= 10; i++) {
int k;
char proc[100];
char buf[100];
sprintf(proc, "/proc/%d/fd/%d", pvt, i);
if (db) fprintf(stderr, "%d -- %s\n", i, proc);
for (k=0; k < 100; k++) {
buf[k] = '\0';
}
if (readlink(proc, buf, 100) != -1) {
buf[100-1] = '\0';
if (db) fprintf(stderr, "%d -- %s -- %s\n", i, proc, buf);
if (strstr(buf, "/dev/tty") == buf) {
vt = atoi(buf + strlen("/dev/tty"));
if (vt > 0) {
break;
}
}
}
}
}
if (7 <= vt && vt <= 128) {
char chvt[100];
sprintf(chvt, "chvt %d >/dev/null 2>/dev/null &", vt);
rfbLog("running: %s\n", chvt);
system(chvt);
sleep(2);
}
}
use_dpy = strdup(line1 + strlen("DISPLAY="));

@ -275,6 +275,7 @@ void parse_fixscreen(void) {
/*
WIREFRAME_PARMS "0xff,2,0,30+6+6+6,Alt,0.05+0.3+2.0,8"
0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125
shade,linewidth,percent,T+B+L+R,mods,t1+t2+t3+t4
*/
#define LW_MAX 8
@ -874,11 +875,12 @@ static void draw_box(int x, int y, int w, int h, int restore) {
save[i]->saved = 0;
}
if (0) fprintf(stderr, " DrawBox: %04dx%04d+%04d+%04d B=%d rest=%d lw=%d %.4f\n", w, h, x, y, 2*(w+h)*(2-restore)*pixelsize*lw, restore, lw, dnowx());
if (restore) {
return;
}
if (0) fprintf(stderr, " DrawBox: %dx%d+%d+%d\n", w, h, x, y);
/*
* work out shade/color for the wireframe line, could be a color
@ -1824,12 +1826,12 @@ void do_copyregion(sraRegionPtr region, int dx, int dy, int mode) {
if (rfb_fb == main_fb && ! rotating && mode == DCR_Normal) {
/* normal case, no -scale or -8to24 */
get_client_regions(&req, &mod, &cpy, &ncli);
if (debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
if (0 || debug_scroll > 1) fprintf(stderr, ">>>-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
rfbDoCopyRegion(screen, region, dx, dy);
get_client_regions(&req, &mod, &cpy, &ncli);
if (debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
if (0 || debug_scroll > 1) fprintf(stderr, "<<<-rfbDoCopyRect req: %d mod: %d cpy: %d\n", req, mod, cpy);
return;
}
@ -1976,7 +1978,7 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
rfbClientIteratorPtr i;
rfbClientPtr cl;
int k, direct, mode, nrects = 0, bad = 0;
double start = dnow();
double t1, t2, start = dnow();
for (k=0; k < ncr; k++) {
sraRectangleIterator *iter;
@ -2011,6 +2013,8 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
}
fb_push_wait(delay, FB_COPY|FB_MOD);
t1 = dnow();
#if 0
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
@ -2048,6 +2052,9 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
for (k=0; k < ncr; k++) {
do_copyregion(region[k], dx[k], dy[k], mode);
}
t2 = dnow();
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (!direct) {
@ -2061,7 +2068,8 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
last_copyrect = dnow();
fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d dt=%.4f %.4f\n", nrects, ncr, dnow() - start, dnowx());
if (0) fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d tot=%.4f t10=%.4f t21=%.4f t32=%.4f %.4f\n",
nrects, ncr, last_copyrect - start, t1 - start, t2 - t1, last_copyrect - t2, dnowx());
}
@ -4123,7 +4131,7 @@ void check_macosx_iconify(Window orig_frame, Window frame, int flush) {
idx = lookup_win_index(orig_frame);
if (idx >= 0) {
if (cache_list[idx].map_state == IsUnmapped) {
fprintf(stderr, "FAW orig_frame unmapped.\n");
if (0) fprintf(stderr, "FAW orig_frame unmapped.\n");
unmapped = 1;
m = 3;
}
@ -4133,17 +4141,17 @@ fprintf(stderr, "FAW orig_frame unmapped.\n");
if (unmapped) {
;
} else if (orig_frame && macosxCGS_follow_animation_win(orig_frame, -1, 0)) {
fprintf(stderr, "FAW orig_frame %d\n", (int) orig_frame);
if (0) fprintf(stderr, "FAW orig_frame %d\n", (int) orig_frame);
} else if (0 && frame && macosxCGS_follow_animation_win(frame, -1, 0)) {
fprintf(stderr, "FAW frame %d\n", (int) frame);
if (0) fprintf(stderr, "FAW frame %d\n", (int) frame);
}
for (j=0; j<m; j++) {
macosxCGS_get_all_windows();
if (macosx_checkevent(NULL)) {
ok = 1;
fprintf(stderr, "Check Event 1\n");
if (0) fprintf(stderr, "Check Event 1\n");
} else {
fprintf(stderr, "Check Event 0\n");
if (0) fprintf(stderr, "Check Event 0\n");
}
if (ok) {
break;
@ -4400,6 +4408,10 @@ if (db) fprintf(stderr, "INTERIOR\n");
frame_changed_spin *= 2.0;
max_spin *= 2.0;
min_draw *= 1.5;
if (link == LR_DIALUP) {
max_spin *= 1.2;
min_draw *= 1.7;
}
if (! didmsg) {
rfbLog("increased wireframe timeouts for "
"slow network connection.\n");
@ -4706,7 +4718,7 @@ if (db) fprintf(stderr, "FRAME MOVE 1st-dt: %.3f\n", first_dt_ave/n);
} else {
if (drew_box && cnt > last_draw_cnt) {
doit = 1;
fprintf(stderr, "*** NO GPI DRAW_BOX\n");
if (0) fprintf(stderr, "*** NO GPI DRAW_BOX\n");
}
}
@ -5513,6 +5525,16 @@ 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 (rawfb_vnc_reflect) {
if (got_user_input) {
if (0) vnc_reflect_process_client();
}
if (got_user_input && *cnt % ui_skip != 0) {
/* every n-th drops thru to scan */
*cnt = *cnt + 1;
return 1; /* short circuit watch_loop */
}
}
#ifdef MACOSX
if (! macosx_console) {
RAWFB_RET(0)
@ -5549,7 +5571,7 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
if (pointer_mode == 1) {
if ((got_user_input || ui_skip < 0) && *cnt % ui_skip != 0) {
/* every ui_skip-th drops thru to scan */
*cnt++;
*cnt = *cnt + 1;
X_LOCK;
XFlush_wr(dpy);
X_UNLOCK;
@ -5565,7 +5587,7 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
* *keyboard* input.
*/
if (*cnt % ui_skip != 0) {
*cnt++;
*cnt = *cnt + 1;
return 1;
}
}
@ -5913,7 +5935,7 @@ void snap_old(void) {
int i;
old_stack_n = STACKMAX;
quick_snap(old_stack, &old_stack_n);
fprintf(stderr, "snap_old: %d %.4f\n", old_stack_n, dnowx());
if (0) fprintf(stderr, "snap_old: %d %.4f\n", old_stack_n, dnowx());
#if 0
for (i= old_stack_n - 1; i >= 0; i--) {
int idx = lookup_win_index(old_stack[i]);
@ -6069,7 +6091,7 @@ int free_rect(int idx) {
int x, y, w, h;
if (idx < 0 || idx >= cache_list_num) {
fprintf(stderr, "free_rect: bad index: %d\n", idx);
if (0) fprintf(stderr, "free_rect: bad index: %d\n", idx);
clean_up_exit(1);
}
@ -7071,6 +7093,13 @@ fprintf(stderr, "BS_save: FAIL FOR: %d\n", idx);
clip_region(r, win);
}
if (sraRgnEmpty(r)) {
if (verb) fprintf(stderr, "BS_save: Region Empty: %d\n", idx);
sraRgnDestroy(r0);
sraRgnDestroy(r);
return 0;
}
dx = x - x2;
dy = y - y2;
@ -7165,6 +7194,14 @@ fprintf(stderr, "SU_save: FAIL FOR: %d\n", idx);
clip_region(r, win);
}
if (sraRgnEmpty(r)) {
if (verb) fprintf(stderr, "SU_save: Region Empty: %d\n", idx);
sraRgnDestroy(r0);
sraRgnDestroy(r);
return 0;
}
dx = x - x2;
dy = y - y2;
@ -7608,6 +7645,7 @@ int Ev_order[EVMAX];
int Ev_area[EVMAX];
int Ev_tmp[EVMAX];
int Ev_tmp2[EVMAX];
Window Ev_tmpwin[EVMAX];
Window Ev_win[EVMAX];
Window Ev_map[EVMAX];
Window Ev_unmap[EVMAX];
@ -7811,12 +7849,12 @@ fprintf(stderr, "TRY_TO_FIX_SU(%d) 0x%lx 0x%lx was_unmapped=%d map_state=%s\n"
for (i = old_stack_n - 1; i >= 0; i--) {
win2 = old_stack[i];
if (win2 == above) {
fprintf(stderr, "0x%lx turn on: 0x%lx i=%d\n", win, win2, i);
if (0) fprintf(stderr, "0x%lx turn on: 0x%lx i=%d\n", win, win2, i);
on = 1;
found_above = 1;
}
if (win2 == win) {
fprintf(stderr, "0x%lx turn off: 0x%lx i=%d\n", win, win2, i);
if (0) fprintf(stderr, "0x%lx turn off: 0x%lx i=%d\n", win, win2, i);
found = 1;
on = 0;
break;
@ -8021,7 +8059,10 @@ void set_ncache_xrootpmap(void) {
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
pmap = XInternAtom(dpy, "_XROOTPMAP_ID", True);
if (pmap != None) {
if (use_solid_bg) {
image = solid_image(NULL);
} else if (pmap != None) {
Pixmap pixmap;
unsigned char *d_pmap;
@ -8083,17 +8124,23 @@ void set_ncache_xrootpmap(void) {
#define EV_VISIBILITY_UNOBS 10
#define EV_VISIBILITY_OBS 11
#define EV_PROPERTY 12
#define EV_OLD_WM_MAP 13
#define EV_OLD_WM_UNMAP 14
#define EV_OLD_WM_OFF 15
#define EV_OLD_WM_NOTMAPPED 16
Window _ev_list[EVLISTMAX];
int _ev_case[EVLISTMAX];
int _ev_list_cnt;
int n_CN = 0, n_RN = 0, n_DN = 0, n_ON = 0, n_MN = 0, n_UN = 0;
int n_VN = 0, n_VN_p = 0, n_VN_u = 0, n_ST = 0, n_PN = 0, n_DC = 0;
int n_ON_sz = 0, n_ON_po = 0, n_ON_st = 0;
int ev_store(Window win, int type) {
if (type == EV_RESET) {
n_CN = 0; n_RN = 0; n_DN = 0; n_ON = 0; n_MN = 0; n_UN = 0;
n_VN = 0; n_VN_p = 0; n_VN_u = 0; n_ST = 0; n_PN = 0; n_DC = 0;
n_ON_sz = 0; n_ON_po = 0; n_ON_st = 0;
_ev_list_cnt = 0;
return 1;
}
@ -8238,12 +8285,15 @@ if (type != ConfigureNotify) fprintf(stderr, "root: skip %s for 0x%lx\n", Etype
ev_store(win, EV_CONFIGURE);
if (cfg_size) {
ev_store(win, EV_CONFIGURE_SIZE);
n_ON_sz++;
}
if (cfg_pos) {
ev_store(win, EV_CONFIGURE_POS);
n_ON_po++;
}
if (cfg_stack) {
ev_store(win, EV_CONFIGURE_STACK);
n_ON_st++;
}
n++;
n_ON++;
@ -8448,6 +8498,9 @@ fprintf(stderr, " try_to_synth_su: 0x%lx %d idx=%d cnt=%d\n", win, i, idx, cnt
return 1;
}
static double last_vis_unobs_time = 0.0;
static double last_vis_obs_time = 0.0;
static int saw_desktop_change = 0;
void check_sched(int try_batch, int *did_sched) {
@ -8655,7 +8708,7 @@ fprintf(stderr, "*VIS BS_save: 0x%lx %d %d %d\n", win, cache_list[i].width, cac
if (now < cache_list[i].vis_unobs_time + 0.75 && now < cache_list[i].vis_obs_time + 0.75) {
continue;
}
bs_save(i, bat, &attr, !top_now[k], 0, &valid, 0);
bs_save(i, bat, &attr, !top_now[k], 0, &valid, 1);
if (valid) {
STORE(i, win, attr);
} else {
@ -8709,6 +8762,7 @@ int check_ncache(int reset, int mode) {
int su_fix_cnt;
int pixels = 0, ttot;
int desktop_change = 0, n1, n2;
int desktop_change_old_wm = 0;
int missed_su_restore = 0;
int missed_bs_restore = 0;
sraRegionPtr r0, r;
@ -8790,6 +8844,15 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
if (nofb) {
return -1;
}
if (now < last_client + 4) {
return -1;
}
if (! all_clients_initialized()) {
/* play it safe */
return -1;
}
if (reset) {
rfbLog("check_ncache: resetting cache\n");
@ -8846,19 +8909,22 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
"This is the Pixel buffer cache region. Your VNC Viewer is not hiding it from you.",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+2*dy,
"Try resizing your VNC Viewer so you don't see it!! Pay no attention to the man behind the curtain...",
"Try resizing your VNC Viewer so you don't see it!!",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+3*dy,
"To disable run the server with: x11vnc -ncache 0 ...",
"Pay no attention to the man behind the curtain...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+4*dy,
"If there are painting errors you can press 3 Alt_L's (Left \"Alt\" key) in a row to repaint the screen.",
"To disable caching run the server with: x11vnc -noncache ...",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+5*dy,
"If there are painting errors press 3 Alt_L's (Left \"Alt\" key) in a row to repaint the screen.",
white_pixel());
rfbDrawString(screen, &default8x16Font, dx, ds + Dy+6*dy,
"More info: http://www.karlrunge.com/x11vnc/#faq-client-caching",
white_pixel());
ds += 9 * dy;
ds += 11 * dy;
}
snapshot_cache_list(0, 100.0);
@ -8868,15 +8934,16 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
for (n = 1; n <= ncache; n++) {
rect_reg[n] = NULL;
}
if (ncache_xrootpmap) {
set_ncache_xrootpmap();
}
snap_old();
}
check_zero_rects();
if (now < last_client + 4) {
return -1;
}
if (hack_val == 2) {
block_stats();
hack_val = 1;
@ -8910,19 +8977,61 @@ if (hack_val == 2) {
} else if (dt_guess && !strcmp(dt_guess, "kde")) {
dt_kde = 1;
}
if (dt_kde) {
kde_no_animate(0);
}
ev_store(None, EV_RESET);
X_LOCK;
for (k = 1; k <= 3; k++) {
int j, retry = 0;
nsave = n;
if (k > 1) fprintf(stderr, "read_events-%d\n", k);
read_events(&n);
nxsel = 0;
#if 0
if (dt_gnome && (n_MN || n_UN)) {
retry = 1;
} else if (ncache_old_wm && n_ON_po >= 2) {
retry = 1;
} else if (n > nsave) {
/* XXX Y */
retry = 1;
}
if (retry) {
int n0 = n;
usleep(25 * 1000);
XFlush_wr(dpy);
read_events(&n);
fprintf(stderr, "read_events retry: %d -> %d\n", n0, n);
}
#endif
if (n > nsave) {
int n0 = n;
for (j=0; j<4; j++) {
if (j < 2) {
usleep(30 * 1000);
} else {
usleep(10 * 1000);
}
XFlush_wr(dpy);
read_events(&n);
fprintf(stderr, "read_events retry: %d -> %d\n", n0, n);
if (n == n0) {
break;
}
n0 = n;
}
}
nxsel = 0;
/* handle creates and reparenting: */
for (n1 = nsave; n1 < n; n1++) {
Window win2;
@ -9041,12 +9150,89 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%lx %d\n", twin, n2);
n_DC++;
}
} else {
if (n_MN + n_UN >= 4) {
if (n_MN + n_UN >= 3) {
desktop_change = 1;
n_DC++;
}
}
}
if (ncache_old_wm) {
int old_maps = 0;
int old_unmaps = 0;
int shifts = 0;
for (i=0; i < n; i++) {
XEvent ev;
int ns, skip = 0, type, idx = -1, state, valid;
int ik = Ev_order[i];
int x_new, y_new, w_new, h_new;
int x_old, y_old, w_old, h_old;
int old_wm = 0;
if (Ev_done[ik]) continue;
win = Ev_win[ik];
ev = Ev[ik];
type = ev.type;
if (type != ConfigureNotify) {
continue;
}
if (ev_lookup(win, EV_MAP)) {
continue;
} else if (ev_lookup(win, EV_UNMAP)) {
continue;
} else if (ev_lookup(win, EV_DESTROY)) {
continue;
}
idx = lookup_win_index(win);
if (idx < 0) {
continue;
}
x_new = ev.xconfigure.x;
y_new = ev.xconfigure.y;
w_new = ev.xconfigure.width;
h_new = ev.xconfigure.height;
x_old = cache_list[idx].x;
y_old = cache_list[idx].y;
w_old = cache_list[idx].width;
h_old = cache_list[idx].height;
if (w_new == w_old && h_new == h_old) {
if (nabs(x_new - x_old) >= dpy_x || nabs(y_new - y_old) >= dpy_y) {
sraRegionPtr r_old, r_new, r0;
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r_old = sraRgnCreateRect(x_old, y_old, x_old+w_old, y_old+h_old);
sraRgnAnd(r_old, r0);
r_new = sraRgnCreateRect(x_new, y_new, x_new+w_new, y_new+h_new);
sraRgnAnd(r_new, r0);
if (cache_list[idx].map_state != IsViewable) {
ev_store(win, EV_OLD_WM_NOTMAPPED);
} else if (sraRgnEmpty(r_old) && !sraRgnEmpty(r_new)) {
old_wm = 1;
ev_store(win, EV_OLD_WM_MAP);
Ev_map[i] = win;
} else if (!sraRgnEmpty(r_old) && sraRgnEmpty(r_new)) {
ev_store(win, EV_OLD_WM_UNMAP);
old_wm = -1;
Ev_unmap[i] = win;
} else {
ev_store(win, EV_OLD_WM_OFF);
}
sraRgnDestroy(r_old);
sraRgnDestroy(r_new);
sraRgnDestroy(r0);
shifts++;
fprintf(stderr, "old_wm[%d] +%04d+%04d +%04d+%04d old_wm: %d\n", i, x_old, y_old, x_new, y_new, old_wm);
}
}
}
if (shifts >= 3) {
fprintf(stderr, "DESKTOP_CHANGE_OLD_WM: %d\n", shifts);
desktop_change = 1;
desktop_change_old_wm = 1;
}
}
#define SKIPUMS \
ok = 1; \
@ -9060,7 +9246,100 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%lx %d\n", twin, n2);
} \
}
/* XXX Y not working well */
if (desktop_change) {
Window twin;
int ok, s, k, add, cnt, ns;
cnt = 0;
add = 0;
for (i=0; i < n; i++) {
twin = Ev_unmap[i];
SKIPUMS
if (ok) {
fprintf(stderr, "U Ev_tmp[%d] = %d\n", cnt, i);
Ev_tmp[cnt++] = i;
}
}
for (i=0; i < n; i++) {
twin = Ev_map[i];
SKIPUMS
if (ok) {
fprintf(stderr, "M Ev_tmp[%d] = %d\n", cnt, i);
Ev_tmp[cnt++] = i;
}
}
for (k = 0; k < cnt; k++) {
Ev_tmp2[k] = -1;
}
/* unmap from top to bottom */
for (s = old_stack_n - 1; s >= 0; s--) {
twin = old_stack[s];
if (twin == None || twin == rootwin) {
continue;
}
for (k = 0; k < cnt; k++) {
i = Ev_tmp[k];
if (twin == Ev_unmap[i]) {
fprintf(stderr, "U Ev_tmp2[%d] = %d\n", add, i);
Ev_tmp2[add++] = i;
break;
}
}
}
/* map from bottom to top */
for (s = 0; s < old_stack_n; s++) {
twin = old_stack[s];
if (twin == None || twin == rootwin) {
continue;
}
for (k = 0; k < cnt; k++) {
i = Ev_tmp[k];
if (twin == Ev_map[i]) {
fprintf(stderr, "M Ev_tmp2[%d] = %d\n", add, i);
Ev_tmp2[add++] = i;
break;
}
}
}
k = 0;
for (i=0; i < n; i++) {
Window wu, wm;
int j;
int oku = 0, okm = 0;
wu = Ev_unmap[i];
wm = Ev_map[i];
ok = 0;
if (wu != None && wu != rootwin) oku = 1;
if (wm != None && wm != rootwin) okm = 1;
if (!oku && !okm) {
continue;
}
if (oku) {
twin = wu;
SKIPUMS
if (!ok) {
oku = 0;
}
}
if (okm) {
twin = wm;
SKIPUMS
if (!ok) {
okm = 0;
}
}
if (!oku && !okm) {
continue;
}
j = Ev_tmp2[k++];
if (j >= 0) {
fprintf(stderr, "UM Ev_order[%d] = %d oku=%d okm=%d\n", i, j, oku, okm);
Ev_order[i] = j;
}
}
}
#if 0
if (desktop_change) {
Window twin;
int ok, s, k, add, cnt, ns;
@ -9137,6 +9416,64 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%lx %d\n", twin, n2);
}
}
}
#endif
if (!desktop_change && (n_VN_p && !n_UN && (n_MN || n_ON_st))) {
if (now < last_vis_unobs_time + 0.75 || now < last_vis_obs_time + 0.75) {
;
} else if (n_MN <= 2 && n_ON_st <= 1) {
for (i=0; i < n; i++) {
XEvent ev;
int ns, skip = 0, type, idx = -1, state, valid;
int ik = Ev_order[i];
if (Ev_done[ik]) continue;
win = Ev_win[ik];
ev = Ev[ik];
type = ev.type;
if (type != VisibilityNotify) {
continue;
}
state = ev.xvisibility.state;
if (state == VisibilityUnobscured) {
continue;
}
if (ev_lookup(win, EV_MAP)) {
continue;
} else if (ev_lookup(win, EV_UNMAP)) {
continue;
} else if (ev_lookup(win, EV_DESTROY)) {
continue;
}
idx = lookup_win_index(win);
if (idx < 0) {
continue;
}
if (cache_list[idx].vis_state == VisibilityFullyObscured) {
continue;
}
if (now < cache_list[idx].vis_unobs_time + 3.00 || now < cache_list[idx].vis_obs_time + 3.00) {
continue;
}
fprintf(stderr, "----%02d: VisibilityNotify 0x%lx %3d (*PRELOOP*) state: %s U/P %d/%d\n", ik, win, idx, VState(state), n_VN_u, n_VN_p);
valid = 0;
bs_save(idx, nbatch, &attr, 1, 0, &valid, 1);
if (valid) {
STORE(idx, win, attr);
} else {
DELETE(idx);
}
cache_list[idx].vis_state = state;
cache_list[idx].vis_obs_time = last_vis_obs_time = dnow();
Ev_done[ik] = 1;
}
}
}
if (desktop_change) {
if (ncache_dt_change) {
fprintf(stderr, "GUESSED DESKTOP CHANGE.\n");
@ -9147,6 +9484,7 @@ fprintf(stderr, "SKIPWINS: Ev_unmap/map: 0x%lx %d\n", twin, n2);
}
}
create_cnt = 0;
missed_su_restore = 0;
missed_bs_restore = 0;
@ -9234,7 +9572,7 @@ fprintf(stderr, "root%02d: ** IgnoringRoot 0x%lx type: %s\n", ik, win, Etype(ty
if (type == ConfigureNotify) {
int x_new, y_new, w_new, h_new;
int x_old, y_old, w_old, h_old;
int stack_change;
int stack_change, old_wm = 0;
Window oabove = None;
idx = lookup_win_index(win);
@ -9260,19 +9598,60 @@ fprintf(stderr, "----%02d: ConfigureNotify 0x%lx %3d -- above: 0x%lx -> 0x%lx
w_old = cache_list[idx].width;
h_old = cache_list[idx].height;
if (x_old != x_new || y_old != y_new) {
/* invalidate su */
cache_list[idx].su_time = 0.0;
fprintf(stderr, " INVALIDATE su: 0x%lx xy: +%d+%d +%d+%d \n", win, x_old, y_old, x_new, y_new);
if (desktop_change_old_wm) {
if (ev_lookup(win, EV_OLD_WM_MAP)) {
if (Ev_map[ik] == win) {
old_wm = 1;
} else {
old_wm = 2;
}
} else if (ev_lookup(win, EV_OLD_WM_UNMAP)) {
if (Ev_unmap[ik] == win) {
old_wm = -1;
} else {
old_wm = 2;
}
} else if (ev_lookup(win, EV_OLD_WM_OFF)) {
old_wm = 2;
} else if (ev_lookup(win, EV_OLD_WM_NOTMAPPED)) {
old_wm = 3;
}
}
if (w_old != w_new || h_old != h_new) {
/* invalidate bs */
cache_list[idx].bs_time = 0.0;
if (!old_wm) {
if (x_old != x_new || y_old != y_new) {
/* invalidate su */
cache_list[idx].su_time = 0.0;
fprintf(stderr, " INVALIDATE su: 0x%lx xy: +%d+%d +%d+%d \n", win, x_old, y_old, x_new, y_new);
}
if (w_old != w_new || h_old != h_new) {
/* invalidate bs */
cache_list[idx].bs_time = 0.0;
fprintf(stderr, " INVALIDATE bs: 0x%lx wh: %dx%d %dx%d \n", win, w_old, h_old, w_new, h_new);
}
} else {
int valid;
X_UNLOCK;
if (old_wm == 1) {
/* XXX Y */
fprintf(stderr, " OLD_WM_MAP: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d \n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new);
valid = 0;
bs_restore(idx, nbatch, NULL, &attr, 0, 0, &valid, 1);
} else if (old_wm == -1) {
fprintf(stderr, " OLD_WM_UNMAP: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d \n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new);
valid = 1;
su_restore(idx, nbatch, NULL, &attr, 1, 0, &valid, 1);
} else {
fprintf(stderr, " OLD_WM_OFF:: 0x%lx wh: %dx%d+%d+%d %dx%d+%d+%d old_wm=%d\n", win, w_old, h_old, x_old, y_old, w_new, h_new, x_new, y_new, old_wm);
}
X_LOCK;
}
stack_change = 0;
if (cache_list[idx].above != ev.xconfigure.above) {
if (old_wm) {
;
} else if (cache_list[idx].above != ev.xconfigure.above) {
stack_change = 1;
} else if (x_new == x_old && y_new == y_old && w_new == w_old && h_new == h_old) {
stack_change = 1;
@ -9430,9 +9809,9 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%lx %3d state: %s U/P %d/%d\n",
}
}
if (state == VisibilityUnobscured) {
cache_list[idx].vis_unobs_time = dnow();
cache_list[idx].vis_unobs_time = last_vis_unobs_time = dnow();
} else if (cache_list[idx].vis_state == VisibilityUnobscured) {
cache_list[idx].vis_obs_time = dnow();
cache_list[idx].vis_obs_time = last_vis_obs_time = dnow();
}
cache_list[idx].vis_state = state;

@ -287,6 +287,8 @@ char *this_host(void) {
if (gethostname(host, MAXN) == 0) {
host[MAXN-1] = '\0';
return strdup(host);
} else if (UT.nodename) {
return strdup(UT.nodename);
}
#endif
return NULL;

@ -2,7 +2,7 @@
.TH X11VNC "1" "January 2007" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.4, lastmod: 2007-01-10
version: 0.8.4, lastmod: 2007-01-31
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -42,10 +42,10 @@ Also, use of a VNC password (-rfbauth or \fB-passwdfile)\fR is strongly recommen
For additional info see: http://www.karlrunge.com/x11vnc/
and http://www.karlrunge.com/x11vnc/#faq
.PP
Rudimentary config file support: if the file $HOME/.x11vncrc exists then each
line in it is treated as a single command line option. Disable with \fB-norc.\fR
For each option name, the leading character "-" is not required. E.g. a
line that is either "forever" or "\fB-forever\fR" may be used and are equivalent.
Config file support: if the file $HOME/.x11vncrc exists then each line in
it is treated as a single command line option. Disable with \fB-norc.\fR For
each option name, the leading character "-" is not required. E.g. a line
that is either "forever" or "\fB-forever\fR" may be used and are equivalent.
Likewise "wait 100" or "\fB-wait\fR \fI100\fR" are acceptable and equivalent lines.
The "#" character comments out to the end of the line in the usual way
(backslash it for a literal). Leading and trailing whitespace is trimmed off.
@ -73,9 +73,29 @@ before startup. Same as \fB-xauth\fR file. See
.IR xauth (1)
man pages for more info.
.PP
\fB-N\fR
.IP
If the X display is :N, try to set the VNC display
to also be :N This just sets the \fB-rfbport\fR option
to 5900+N. The program will exit immediately if that
port is not available.
.PP
\fB-reflect\fR \fIhost:N\fR
.IP
Instead of connecting to and polling an X display,
connect to the remote VNC server host:N and be a
reflector/repeater for it. This is useful for trying
to manage the case of many simultaneous VNC viewers
(e.g. classroom broadcasting) where, e.g. you put
a repeater on each network switch, etc, to improve
performance by distributing the load and network
traffic. Implies \fB-shared\fR (use \fB-noshared\fR as a later
option to disable). See the discussion below under
\fB-rawfb\fR vnc:host:N for more details.
.PP
\fB-id\fR \fIwindowid\fR
.IP
Show the window corresponding to \fIwindowid\fR not
Show the X window corresponding to \fIwindowid\fR not
the entire display. New windows like popup menus,
transient toplevels, etc, may not be seen or may be
clipped. Disabling SaveUnders or BackingStore in the
@ -921,15 +941,16 @@ source code (x11vnc/misc/Xdummy) It should be available
in PATH and have run "Xdummy \fB-install"\fR once to create
the shared library. Xdummy requires root permission
and only works on Linux. Xvfb is available on most
platforms.
platforms and does not require root.
.IP
When x11vnc exits (i.e. user disconnects) the X server
session stays running in the background. Presumably the
FINDDISPLAY will find it next time. The user must exit
the X session in the usual way for it to terminate.
session stays running in the background. Presumably
the FINDDISPLAY will find it next time. The user must
exit the X session in the usual way for it to terminate
(or kill the X server process if all else fails).
.IP
So this is a somewhat odd mode for x11vnc in that it
will start up and poll virtual X servers. This can
will start up and poll virtual X servers! This can
be used from, say,
.IR inetd (8)
to provide a means of
@ -946,13 +967,30 @@ Where /.../x11vnc is the full path to x11vnc.
Use WAIT:cmd=FINDCREATEDISPLAY-print to print out the
script used. You can specify the preferred order via
e.g., WAIT:cmd=FINDCREATEDISPLAY-Xdummy,Xvfb,X and/or
leave out ones you do not want. The the extra case "X"
means try to start up a real, hardware X server using
.IR xinit (1).
If there is already an X server running the
X case may only work on Linux (see
leave out ones you do not want. The the extra case
"X" means try to start up a real, hardware X server
using
.IR xinit (1)
or
.IR startx (1).
If there is already an
X server running the X case may only work on Linux
(see
.IR startx (1)
).
.IP
If you want the FINDCREATEDISPLAY session to contact an
XDMCP login manager (xdm/gdm/kdm) on the same machine,
then use "Xvfb.xdmcp" instead of "Xvfb", etc.
The user will have to supply his username and password
one more time (but he gets to select his desktop type
so that can be useful). For this to work, you will
need to enable localhost XDMCP (udp port 177) for the
display manager. This seems to be:
.IP
for gdm in gdm.conf: Enable=true in section [xdmcp]
for kdm in kdmrc: Enable=true in section [Xdmcp]
for xdm in xdm-config: DisplayManager.requestPort: 177
.PP
\fB-ssl\fR \fI[pem]\fR
.IP
@ -1969,6 +2007,14 @@ the state of the modifiers: this usually works for
identical keyboards). Also useful in resolving cases
where a Keysym is bound to multiple keys (e.g. "<" + ">"
and "," + "<" keys). Default: \fB-modtweak\fR
.IP
On some HP-UX systems it is been noted that they have
an odd keymapping where a single keycode will have a
keysym, e.g. "#", up to three times. You can check
via "xmodmap \fB-pk"\fR or the \fB-dk\fR option. The failure
is when you try to type "#" it yields "3". If you
see this problem try setting the environment variable
MODTWEAK_LOWEST=1 to see if it helps.
.PP
\fB-xkb,\fR \fB-noxkb\fR
.IP
@ -2376,93 +2422,6 @@ slow setups, but you lose all visual feedback for drags,
text selection, and some menu traversals. It overrides
any \fB-pointer_mode\fR setting.
.PP
\fB-ncache\fR \fIn\fR
.IP
Client-side caching scheme. Framebuffer memory \fIn\fR
(an integer) times that of the full display is allocated
below the actual framebuffer to cache screen contents
for rapid retrieval. So a W x H frambuffer is expanded
to a W x (n+1)*H one. Use 0 to disable. Default: XXX.
.IP
This is an experimental option, currently implemented
in an awkward way in that in the VNC Viewer you can
see the cache contents if you scroll down, etc. So you
will have to set things up so you can't see that region.
If this method is successful, the changes required for
clients to do this less awkwardly will be investigated.
.IP
Note that this mode consumes a huge amount of memory,
both on the x11vnc server side and on the VNC Viewer
side. If n=2 then the amount of RAM used is roughly
tripled for both x11vnc and the VNC Viewer. As a rule
of thumb, note that 1280x1024 at depth 24 is about 5MB
of pixel data.
.IP
For reasonable response when cycling through 4 to 6
large (e.g. web browser) windows a value n of 6 to 12
is recommended. (that's right: ~10X more memory...)
.IP
Because of the way window backingstore and saveunders
are implemented, n must be even. It will be incremented
by 1 if it is not.
.IP
This mode also works for native MacOS X, but may not
be as effective as the X version. This is due to a
number of things, one is the drop-shadow compositing
that leaves extra areas that need to be repaired (see
\fB-ncache_pad).\fR Another is the window iconification
animations need to be avoided (see \fB-macicontime).\fR
It appears the that the 'Scale' animation mode gives
better results than the 'Genie' one. Also, window event
detection not as accurate as the X version.
.PP
\fB-ncache_cr\fR
.IP
In \fB-ncache\fR mode, try to do copyrect opaque window
moves/drags instead of wireframes (this can induce
painting errors). The wireframe will still be used when
moving a window whose save-unders has not yet been set
or has been invalidated.
.IP
Some VNC Viewers provide better response than others
with this option. On Unix, realvnc viewer gives
smoother drags than tightvnc viewer. Response may also
be choppy if the server side machine is too slow.
.IP
Sometimes on very slow modem connections, this actually
gives an improvement because no pixel data at all
(not even the box animation) is sent during the drag.
.PP
\fB-ncache_no_moveraise\fR
.IP
In \fB-ncache\fR mode, do not assume that moving a window
will cause the window manager to raise it to the top
of the stack. The default is to assume it does, and
so at the beginning of any wireframe, etc, window moves
the window will be pushed to top in the VNC viewer.
.PP
\fB-ncache_no_dtchange\fR
.IP
In \fB-ncache\fR mode, do not try to guess when the desktop
(viewport) changes to another one (i.e. another
workarea). The default is to try to guess and when
detected try to make the transistion more smoothly.
.PP
\fB-ncache_no_rootpixmap\fR
.IP
In \fB-ncache\fR mode, do not try to snapshot the desktop
background to use in guessing or reconstructing window
save-unders..
.PP
\fB-ncache_pad\fR \fIn\fR
.IP
In \fB-ncache\fR mode, pad each window with n pixels for the
caching rectangles. This can be used to try to improve
the situation with dropshadows or other compositing
(e.g. MacOS X window manager), although it could make
things worse. The default is 0 on Unix and 24 on
MacOS X.
.PP
\fB-wireframe\fR \fI[str],\fR \fB-nowireframe\fR
.IP
Try to detect window moves or resizes when a mouse
@ -2480,7 +2439,7 @@ The value "str" is optional and, of course, is
packed with many tunable parameters for this scheme:
.IP
Format: shade,linewidth,percent,T+B+L+R,mod,t1+t2+t3+t4
Default: 0xff,3,0,32+8+8+8,all,0.15+0.30+5.0+0.125
Default: 0xff,2,0,32+8+8+8,all,0.15+0.30+5.0+0.125
.IP
If you leave nothing between commas: ",," the default
value is used. If you don't specify enough commas,
@ -3197,6 +3156,10 @@ If the string begins with "console", "/dev/fb", or
the framebuffer device is opened and keystrokes (and
possibly mouse events) are inserted into the console.
.IP
If the string begins with "vnc", see the VNC HOST
discussion below where the framebuffer is taken as that
of another remote VNC server.
.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
@ -3222,6 +3185,7 @@ Examples:
\fB-rawfb\fR video0
\fB-rawfb\fR video \fB-pipeinput\fR VID
\fB-rawfb\fR console
\fB-rawfb\fR vnc:somehost:0
.IP
(see
.IR ipcs (1)
@ -3398,6 +3362,44 @@ Examples:
\fB-rawfb\fR consolex (no keystrokes or mouse)
\fB-rawfb\fR console:/dev/nonstd
\fB-rawfb\fR console \fB-pipeinput\fR UINPUT:accel=4.0
.IP
VNC HOST: if the \fB-rawfb\fR string is of the form
"vnc:host:N" then the VNC display "N" on the remote
VNC server "host" is connected to (i.e. x11vnc acts as
a VNC client itself) and that framebuffer is exported.
.IP
This mode is really only of use if you are trying
to improve performance in the case of many (e.g. >
10) simultaneous VNC viewers, and you try a divide
and conquer scheme to reduce bandwidth and improve
responsiveness.
.IP
For example, if there will be 64 simultaneous VNC
viewers this can lead to a lot of redundant VNC traffic
to and from the server host:N, extra CPU usage,
and all viewers response can be reduced by having
to wait for writes to the slowest client to finish.
However, if you set up 8 reflectors/repeaters started
with option \fB-rawfb\fR vnc:host:N, then there are only
8 connections to host:N. Each repeater then handles
8 vnc viewer connections thereby spreading the load
around. In classroom broadcast usage, try to put the
repeaters on different switches. This mode is the same
as \fB-reflect\fR host:N. Replace "host:N" by "listen"
or "listen:port" for a reverse connection.
.IP
Overall performance will not be as good as a single
direct connection because, among other things,
there is an additional level of framebuffer polling
and pointer motion can still induce many changes per
second that must be propagated. Tip: if the remote VNC
is x11vnc doing wireframing, or an X display that does
wireframing that gives much better response than opaque
window dragging. Consider the \fB-nodragging\fR option if
the problem is severe.
.IP
The VNC HOST mode implies \fB-shared.\fR Use \fB-noshared\fR as
a subsequent cmdline option to disable sharing.
.PP
\fB-freqtab\fR \fIfile\fR
.IP
@ -3507,7 +3509,7 @@ Use reset=0 to disable.
If the uinput device has an absolute pointer (as opposed
to a normal mouse that is a relative pointer) you can
specify the option "abs". Note that a touchpad
on a laptop is an absolute device t some degree.
on a laptop is an absolute device to some degree.
This (usually) avoids all the problems with mouse
acceleration. If x11vnc has trouble deducing the size
of the device, use "abs=WxH". Furthermore, if the
@ -4040,6 +4042,10 @@ noncache_no_rootpixmap disable ncache_no_rootpixmap.
.IP
ncache_reset_rootpixmap recheck the root pixmap
.IP
ncache_keep_anims enable ncache_keep_anims.
.IP
noncache_keep_anims disable ncache_keep_anims.
.IP
wireframe enable \fB-wireframe\fR mode. same as "wf"
.IP
nowireframe disable \fB-wireframe\fR mode. same as "nowf"
@ -4307,26 +4313,27 @@ 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 rotate padgeom
quiet q noquiet modtweak nomodtweak xkb noxkb capslock
nocapslock skip_lockkeys noskip_lockkeys 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
bell nobell sel nosel primary noprimary setprimary
nosetprimary clipboard noclipboard setclipboard
nosetclipboard seldir cursorshape nocursorshape
cursorpos nocursorpos cursor_drag nocursor_drag cursor
show_cursor noshow_cursor nocursor arrow xfixes
noxfixes xdamage noxdamage xd_area xd_mem alphacut
alphafrac alpharemove noalpharemove alphablend
noalphablend xwarppointer xwarp noxwarppointer
noxwarp buttonmap dragging nodragging ncache_cr
noncache_cr ncache_no_moveraise noncache_no_moveraise
ncache_no_dtchange noncache_no_dtchange
ncache_no_rootpixmap noncache_no_rootpixmap
ncache_reset_rootpixmap ncache noncache ncache_size
wireframe_mode wireframe wf nowireframe nowf
xtrap noxtrap xrandr noxrandr xrandr_mode rotate
padgeom quiet q noquiet modtweak nomodtweak xkb noxkb
capslock nocapslock skip_lockkeys noskip_lockkeys
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 bell nobell sel nosel primary
noprimary setprimary nosetprimary clipboard noclipboard
setclipboard nosetclipboard seldir cursorshape
nocursorshape cursorpos nocursorpos cursor_drag
nocursor_drag cursor show_cursor noshow_cursor
nocursor arrow xfixes noxfixes xdamage noxdamage
xd_area xd_mem alphacut alphafrac alpharemove
noalpharemove alphablend noalphablend xwarppointer
xwarp noxwarppointer noxwarp buttonmap dragging
nodragging ncache_cr noncache_cr ncache_no_moveraise
noncache_no_moveraise ncache_no_dtchange
noncache_no_dtchange ncache_no_rootpixmap
noncache_no_rootpixmap ncache_reset_rootpixmap
ncache_keep_anims noncache_keep_anims ncache noncache
ncache_size wireframe_mode wireframe wf nowireframe nowf
wireframelocal wfl nowireframelocal nowfl wirecopyrect
wcr nowirecopyrect nowcr scr_area scr_skip scr_inc
scr_keys scr_term scr_keyrepeat scr_parms scrollcopyrect

@ -582,6 +582,14 @@ static void watch_loop(void) {
}
}
if (rawfb_vnc_reflect) {
static time_t lastone = 0;
if (time(NULL) > lastone + 10) {
lastone = time(NULL);
vnc_reflect_process_client();
}
}
if (! screen || ! screen->clientHead) {
/* waiting for a client */
if (first_conn_timeout) {
@ -633,6 +641,10 @@ static void watch_loop(void) {
}
if (unixpw_in_progress) continue;
if (rawfb_vnc_reflect) {
vnc_reflect_process_client();
}
dtime0(&tm);
if (use_snapfb) {
int t, tries = 3;
@ -1072,7 +1084,7 @@ static void quick_pw(char *str) {
exit(1);
}
} else {
if (su_verify(p, q+1, NULL, NULL, NULL)) {
if (su_verify(p, q+1, NULL, NULL, NULL, 1)) {
fprintf(stdout, "Y %s\n", p);
exit(0);
} else {
@ -1461,7 +1473,7 @@ char msg[] =
"perhaps even report back your observations. However, if you do not want\n"
"to test or use the feature, run x11vnc like this:\n"
"\n"
" x11vnc -ncache 0 ...\n"
" x11vnc -noncache ...\n"
"\n"
"Your current setting is: -ncache %d\n"
"\n"
@ -1517,6 +1529,7 @@ int main(int argc, char* argv[]) {
int got_rfbwait = 0;
int got_httpdir = 0, try_http = 0;
int waited_for_client = 0;
int orig_use_xdamage = use_xdamage;
XImage *fb0 = NULL;
/* used to pass args we do not know about to rfbGetScreen(): */
@ -1644,6 +1657,13 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-auth") || !strcmp(arg, "-xauth")) {
CHECK_ARGC
auth_file = strdup(argv[++i]);
} else if (!strcmp(arg, "-N")) {
display_N = 1;
} else if (!strcmp(arg, "-reflect")) {
CHECK_ARGC
raw_fb_str = (char *) malloc(4 + strlen(argv[i]) + 1);
sprintf(raw_fb_str, "vnc:%s", argv[++i]);
shared = 1;
} else if (!strcmp(arg, "-id") || !strcmp(arg, "-sid")) {
CHECK_ARGC
if (!strcmp(arg, "-sid")) {
@ -1716,6 +1736,8 @@ int main(int argc, char* argv[]) {
got_noviewonly = 1;
} else if (!strcmp(arg, "-shared")) {
shared = 1;
} else if (!strcmp(arg, "-noshared")) {
shared = 0;
} else if (!strcmp(arg, "-once")) {
connect_once = 1;
got_connect_once = 1;
@ -2159,21 +2181,27 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-nodragging")) {
show_dragging = 0;
#ifndef NO_NCACHE
} else if (!strcmp(arg, "-ncache")) {
} else if (!strcmp(arg, "-ncache") || !strcmp(arg, "-nc")) {
CHECK_ARGC
ncache = atoi(argv[++i]);
if (ncache % 2 != 0) {
ncache++;
}
} else if (!strcmp(arg, "-ncache_cr")) {
} else if (!strcmp(arg, "-noncache") || !strcmp(arg, "-nonc")) {
ncache = 0;
} else if (!strcmp(arg, "-ncache_cr") || !strcmp(arg, "-nc_cr")) {
ncache_copyrect = 1;
} else if (!strcmp(arg, "-ncache_no_moveraise")) {
} else if (!strcmp(arg, "-ncache_no_moveraise") || !strcmp(arg, "-nc_no_moveraise")) {
ncache_wf_raises = 1;
} else if (!strcmp(arg, "-ncache_no_dtchange")) {
} else if (!strcmp(arg, "-ncache_no_dtchange") || !strcmp(arg, "-nc_no_dtchange")) {
ncache_dt_change = 0;
} else if (!strcmp(arg, "-ncache_no_rootpixmap")) {
} else if (!strcmp(arg, "-ncache_no_rootpixmap") || !strcmp(arg, "-nc_no_rootpixmap")) {
ncache_xrootpmap = 0;
} else if (!strcmp(arg, "-ncache_pad")) {
} else if (!strcmp(arg, "-ncache_keep_anims") || !strcmp(arg, "-nc_keep_anims")) {
ncache_keep_anims = 1;
} else if (!strcmp(arg, "-ncache_old_wm") || !strcmp(arg, "-nc_old_wm")) {
ncache_old_wm = 1;
} else if (!strcmp(arg, "-ncache_pad") || !strcmp(arg, "-nc_pad")) {
CHECK_ARGC
ncache_pad = atoi(argv[++i]);
#endif
@ -2281,6 +2309,8 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-debug_keyboard")
|| !strcmp(arg, "-dk")) {
debug_keyboard++;
} else if (!strcmp(arg, "-debug_xdamage")) {
debug_xdamage++;
} else if (!strcmp(arg, "-defer")) {
CHECK_ARGC
defer_update = atoi(argv[++i]);
@ -2375,6 +2405,9 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-rawfb")) {
CHECK_ARGC
raw_fb_str = strdup(argv[++i]);
if (strstr(raw_fb_str, "vnc:") == raw_fb_str) {
shared = 1;
}
} else if (!strcmp(arg, "-freqtab")) {
CHECK_ARGC
freqtab = strdup(argv[++i]);
@ -2527,6 +2560,7 @@ int main(int argc, char* argv[]) {
}
}
orig_use_xdamage = use_xdamage;
if (getenv("X11VNC_LOOP_MODE")) {
if (bg) {
@ -3067,6 +3101,34 @@ int main(int argc, char* argv[]) {
initialize_allowed_input();
if (display_N && !got_rfbport) {
char *ud = use_dpy;
if (ud == NULL) {
ud = getenv("DISPLAY");
}
if (ud && strstr(ud, "cmd=") == NULL) {
char *p;
ud = strdup(ud);
p = strrchr(ud, ':');
if (p) {
int N;
char *q = strchr(p, '.');
if (q) {
*q = '\0';
}
N = atoi(p+1);
if (argc_vnc+1 < argc_vnc_max) {
char Nstr[16];
sprintf(Nstr, "%d", (5900 + N) % 65536);
argv_vnc[argc_vnc++] = strdup("-rfbport");
argv_vnc[argc_vnc++] = strdup(Nstr);
got_rfbport = 1;
}
}
free(ud);
}
}
if (users_list && strstr(users_list, "lurk=")) {
if (use_dpy) {
rfbLog("warning: -display does not make sense in "
@ -3094,6 +3156,7 @@ int main(int argc, char* argv[]) {
dpy = XOpenDisplay_wr("");
}
#ifdef MACOSX
if (! dpy && ! raw_fb_str) {
raw_fb_str = strdup("console");
@ -3497,21 +3560,29 @@ int main(int argc, char* argv[]) {
raw_fb_pass_go_and_collect_200_dollars:
#ifdef MACOSX
if (! dpy) {
if (! dpy || raw_fb_str) {
int doit = 0;
/* XXX this needs improvement (esp. for remote control) */
if (! raw_fb_str || strstr(raw_fb_str, "console") == raw_fb_str) {
#ifdef MACOSX
doit = 1;
#endif
}
if (raw_fb_str && strstr(raw_fb_str, "vnc") == raw_fb_str) {
doit = 1;
}
if (doit) {
if (! multiple_cursors_mode) {
multiple_cursors_mode = strdup("most");
}
initialize_cursors_mode();
use_xdamage = orig_use_xdamage;
if (use_xdamage) {
xdamage_present = 1;
initialize_xdamage();
}
}
}
#endif
if (! dt) {
static char str[] = "-desktop";

@ -137,6 +137,7 @@
/* these are for delaying features: */
#define xxNO_SSL_OR_UNIXPW
#define xxNO_NCACHE
#define NO_NCACHE
/*
* Beginning of support for small binary footprint build for embedded

@ -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.4 lastmod: 2007-01-10";
char lastmod[] = "0.8.4 lastmod: 2007-01-31";
/* X display info */
@ -110,14 +110,14 @@ int scale_cursor_numer = 0, scale_cursor_denom = 0;
/* size of the basic tile unit that is polled for changes: */
int tile_x = 32;
int tile_y = 32;
int ntiles, ntiles_x, ntiles_y;
int ntiles, ntiles_x = 0, ntiles_y = 0;
/* arrays that indicate changed or checked tiles. */
unsigned char *tile_has_diff = NULL, *tile_tried = NULL, *tile_copied = NULL;
unsigned char *tile_has_xdamage_diff = NULL, *tile_row_has_xdamage_diff = NULL;
/* times of recent events */
time_t last_event, last_input = 0, last_client = 0;
time_t last_event = 0, last_input = 0, last_client = 0;
time_t last_local_input = 0;
time_t last_keyboard_input = 0, last_pointer_input = 0;
time_t last_fb_bytes_sent = 0;

@ -8,6 +8,7 @@
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
Damage xdamage = 0;
#endif
#ifndef XDAMAGE
#define XDAMAGE 1
#endif
@ -30,7 +31,7 @@ int XD_skip = 0, XD_tot = 0, XD_des = 0; /* for stats */
void add_region_xdamage(sraRegionPtr new_region);
void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
int collect_xdamage(int scancnt, int call);
int xdamage_hint_skip(int y);
void initialize_xdamage(void);
@ -118,6 +119,11 @@ static void record_desired_xdamage_rect(int x, int y, int w, int h) {
xdamage_direct_count++;
X_LOCK;
} else {
if (ntiles_x == 0 || ntiles_y == 0) {
/* too early. */
return;
}
nt_x1 = nfix( (x)/tile_x, ntiles_x);
nt_x2 = nfix((x+w)/tile_x, ntiles_x);
nt_y1 = nfix( (y)/tile_y, ntiles_y);
@ -217,7 +223,7 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
#endif
}
int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call) {
int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call) {
sraRegionPtr tmpregion;
sraRegionPtr reg;
static int rect_count = 0;
@ -227,7 +233,7 @@ int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call) {
double tm, dt;
int x, y, w, h, x2, y2;
if (call && debug_xdamage > 1) fprintf(stderr, "collect_macosx_damage: %d %d %d %d - %d / %d\n", x_in, y_in, w_in, h_in, call, use_xdamage);
if (call && debug_xdamage > 1) fprintf(stderr, "collect_non_X_xdamage: %d %d %d %d - %d / %d\n", x_in, y_in, w_in, h_in, call, use_xdamage);
if (! use_xdamage) {
return 0;
@ -248,6 +254,9 @@ if (call && debug_xdamage > 1) fprintf(stderr, "collect_macosx_damage: %d %d %d
sraRgnMakeEmpty(reg);
}
} else {
if (xdamage_ticker < 0) {
xdamage_ticker = 0;
}
reg = xdamage_regions[xdamage_ticker];
}
if (reg == NULL) {
@ -315,7 +324,7 @@ if (call && debug_xdamage > 1) fprintf(stderr, "collect_macosx_damage: %d %d %d
dt = dtime(&tm);
if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
|| debug_xdamage > 1) {
fprintf(stderr, "collect_macosx_damage(%d): %.4f t: %.4f ev/dup/accept"
fprintf(stderr, "collect_non_X_xdamage(%d): %.4f t: %.4f ev/dup/accept"
"/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
dcount, ccount, xdamage_direct_count);
}
@ -389,6 +398,9 @@ int collect_xdamage(int scancnt, int call) {
sraRgnMakeEmpty(reg);
}
} else {
if (xdamage_ticker < 0) {
xdamage_ticker = 0;
}
reg = xdamage_regions[xdamage_ticker];
}
if (reg == NULL) {

@ -19,7 +19,7 @@ extern int XD_skip, XD_tot, XD_des;
extern void add_region_xdamage(sraRegionPtr new_region);
extern void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
extern int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
extern int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
extern int collect_xdamage(int scancnt, int call);
extern int xdamage_hint_skip(int y);
extern void initialize_xdamage(void);

@ -1152,6 +1152,7 @@ void check_xevents(int reset) {
#endif /* NO_X11 */
}
extern int rawfb_vnc_reflect;
/*
* hook called when a VNC client sends us some "XCut" text (rfbClientCutText).
*/
@ -1188,6 +1189,11 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) {
}
#endif
if (rawfb_vnc_reflect) {
vnc_reflect_send_cuttext(text, len);
return;
}
RAWFB_RET_VOID
#if NO_X11

Loading…
Cancel
Save