summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrunge <runge>2007-01-02 05:15:07 +0000
committerrunge <runge>2007-01-02 05:15:07 +0000
commitc88d830f5591913f2e5e763814978e2877f367ec (patch)
tree217ae1113daa5bced6f21c34eb1a923bcd8cec18
parent833f06025fbd2fa8d4d83ccf8ab068c8060663de (diff)
downloadlibtdevnc-c88d830f.tar.gz
libtdevnc-c88d830f.zip
x11vnc: more -ncache improvements.
-rw-r--r--x11vnc/ChangeLog3
-rw-r--r--x11vnc/README92
-rw-r--r--x11vnc/help.c30
-rw-r--r--x11vnc/options.c20
-rw-r--r--x11vnc/options.h9
-rw-r--r--x11vnc/remote.c30
-rw-r--r--x11vnc/scan.c2
-rw-r--r--x11vnc/ssltools.h2
-rwxr-xr-xx11vnc/tkx11vnc22
-rw-r--r--x11vnc/tkx11vnc.h22
-rw-r--r--x11vnc/user.c6
-rw-r--r--x11vnc/userinput.c1330
-rw-r--r--x11vnc/x11vnc.140
-rw-r--r--x11vnc/x11vnc.c16
-rw-r--r--x11vnc/x11vnc.h4
-rw-r--r--x11vnc/x11vnc_defs.c6
-rw-r--r--x11vnc/xevents.c25
-rw-r--r--x11vnc/xevents.h1
18 files changed, 1417 insertions, 243 deletions
diff --git a/x11vnc/ChangeLog b/x11vnc/ChangeLog
index cbcfa9d..f86d22c 100644
--- a/x11vnc/ChangeLog
+++ b/x11vnc/ChangeLog
@@ -1,3 +1,6 @@
+2007-01-01 Karl Runge <runge@karlrunge.com>
+ * x11vnc: more -ncache improvements.
+
2006-12-28 Karl Runge <runge@karlrunge.com>
* x11vnc: more work on -ncache, add macosx support, fix X errors
and improve cache expiration algorithm.
diff --git a/x11vnc/README b/x11vnc/README
index 80eb701..1e3e08f 100644
--- a/x11vnc/README
+++ b/x11vnc/README
@@ -1,5 +1,5 @@
-x11vnc README file Date: Fri Dec 29 01:37:39 EST 2006
+x11vnc README file Date: Mon Jan 1 21:04:46 EST 2007
The following information is taken from these URLs:
@@ -9262,7 +9262,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions)
-x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2006-12-29
+x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-01
x11vnc options:
-display disp -auth file -id windowid
@@ -9308,34 +9308,34 @@ x11vnc options:
-noalphablend -nocursorshape -cursorpos
-nocursorpos -xwarppointer -noxwarppointer
-buttonmap string -nodragging -ncache n
- -ncache_cr -ncache_pad n -wireframe [str]
- -nowireframe -nowireframelocal -wirecopyrect mode
- -nowirecopyrect -debug_wireframe -scrollcopyrect mode
- -noscrollcopyrect -scr_area n -scr_skip list
- -scr_inc list -scr_keys list -scr_term list
- -scr_keyrepeat lo-hi -scr_parms string -fixscreen string
- -debug_scroll -noxrecord -grab_buster
- -nograb_buster -debug_grabs -debug_sel
- -pointer_mode n -input_skip n -allinput
- -speeds rd,bw,lat -wmdt string -debug_pointer
- -debug_keyboard -defer time -wait time
- -wait_ui factor -nowait_bog -slow_fb time
- -readtimeout n -nap -nonap
- -sb time -nofbpm -fbpm
- -nodpms -dpms -noxdamage
- -xd_area A -xd_mem f -sigpipe string
- -threads -nothreads -fs f
- -gaps n -grow n -fuzz n
- -debug_tiles -snapfb -rawfb string
- -freqtab file -pipeinput cmd -macnodim
- -macnosleep -macnosaver -macnowait
- -macwheel n -macnoswap -macnoresize
- -maciconanim n -macmenu -gui [gui-opts]
- -remote command -query variable -QD variable
- -sync -noremote -yesremote
- -unsafe -safer -privremote
- -nocmds -allowedcmds list -deny_all
-
+ -ncache_cr -ncache_no_moveraise -ncache_no_dtchange
+ -ncache_pad n -wireframe [str] -nowireframe
+ -nowireframelocal -wirecopyrect mode -nowirecopyrect
+ -debug_wireframe -scrollcopyrect mode -noscrollcopyrect
+ -scr_area n -scr_skip list -scr_inc list
+ -scr_keys list -scr_term list -scr_keyrepeat lo-hi
+ -scr_parms string -fixscreen string -debug_scroll
+ -noxrecord -grab_buster -nograb_buster
+ -debug_grabs -debug_sel -pointer_mode n
+ -input_skip n -allinput -speeds rd,bw,lat
+ -wmdt string -debug_pointer -debug_keyboard
+ -defer time -wait time -wait_ui factor
+ -nowait_bog -slow_fb time -readtimeout n
+ -nap -nonap -sb time
+ -nofbpm -fbpm -nodpms
+ -dpms -noxdamage -xd_area A
+ -xd_mem f -sigpipe string -threads
+ -nothreads -fs f -gaps n
+ -grow n -fuzz n -debug_tiles
+ -snapfb -rawfb string -freqtab file
+ -pipeinput cmd -macnodim -macnosleep
+ -macnosaver -macnowait -macwheel n
+ -macnoswap -macnoresize -maciconanim n
+ -macmenu -gui [gui-opts] -remote command
+ -query variable -QD variable -sync
+ -noremote -yesremote -unsafe
+ -safer -privremote -nocmds
+ -allowedcmds list -deny_all
libvncserver options:
-rfbport port TCP port for RFB protocol
@@ -9369,7 +9369,7 @@ libvncserver-tight-extension options:
% x11vnc -help
-x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2006-12-29
+x11vnc: allow VNC connections to real X11 displays. 0.8.4 lastmod: 2007-01-01
(type "x11vnc -opts" to just list the options.)
@@ -11388,7 +11388,7 @@ Options:
better results than the 'Genie' one. Also, window event
detection not as accurate as the X version.
--ncache_cr In -nache mode, try do to copyrect opaque window
+-ncache_cr In -ncache 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
@@ -11399,7 +11399,18 @@ Options:
smoother drags than tightvnc viewer. Response may also
be choppy if the server side machine is too slow.
--ncache_pad n In -nache mode, pad each window with n pixels for the
+-ncache_no_moveraise In -ncache 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.
+
+-ncache_no_dtchange In -ncache 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.
+
+-ncache_pad n In -ncache 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
@@ -12656,6 +12667,8 @@ n
ncache_size:n set -ncache size to n.
ncache_cr enable -ncache_cr mode.
noncache_cr disable -ncache_cr mode.
+ ncache_no_moveraise enable no_moveraise mode.
+ noncache_no_moveraise disable no_moveraise mode.
wireframe enable -wireframe mode. same as "wf"
nowireframe disable -wireframe mode. same as "nowf"
wireframe:str enable -wireframe mode string.
@@ -12817,12 +12830,13 @@ n
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
+ 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
noncache ncache_size wireframe_mode wireframe wf
nowireframe nowf wireframelocal wfl nowireframelocal
nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area
diff --git a/x11vnc/help.c b/x11vnc/help.c
index 6592407..d4c9aad 100644
--- a/x11vnc/help.c
+++ b/x11vnc/help.c
@@ -2053,7 +2053,7 @@ void print_help(int mode) {
" better results than the 'Genie' one. Also, window event\n"
" detection not as accurate as the X version.\n"
"\n"
-"-ncache_cr In -nache mode, try do to copyrect opaque window\n"
+"-ncache_cr In -ncache mode, try to do copyrect opaque window\n"
" moves/drags instead of wireframes (this can induce\n"
" painting errors). The wireframe will still be used when\n"
" moving a window whose save-unders has not yet been set\n"
@@ -2064,7 +2064,18 @@ void print_help(int mode) {
" smoother drags than tightvnc viewer. Response may also\n"
" be choppy if the server side machine is too slow.\n"
"\n"
-"-ncache_pad n In -nache mode, pad each window with n pixels for the\n"
+"-ncache_no_moveraise In -ncache mode, do not assume that moving a window\n"
+" will cause the window manager to raise it to the top\n"
+" of the stack. The default is to assume it does, and\n"
+" so at the beginning of any wireframe, etc, window moves\n"
+" the window will be pushed to top in the VNC viewer.\n"
+"\n"
+"-ncache_no_dtchange In -ncache mode, do not try to guess when the desktop\n"
+" (viewport) changes to another one (i.e. another\n"
+" workarea). The default is to try to guess and when\n"
+" detected try to make the transistion more smoothly.\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"
" the situation with dropshadows or other compositing\n"
" (e.g. MacOS X window manager), although it could make\n"
@@ -3329,6 +3340,8 @@ void print_help(int mode) {
" ncache_size:n set -ncache size to n.\n"
" ncache_cr enable -ncache_cr mode.\n"
" noncache_cr disable -ncache_cr mode.\n"
+" ncache_no_moveraise enable no_moveraise mode.\n"
+" noncache_no_moveraise disable no_moveraise mode.\n"
" wireframe enable -wireframe mode. same as \"wf\"\n"
" nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n"
@@ -3488,12 +3501,13 @@ void print_help(int mode) {
" 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 noxfixes\n"
-" xdamage noxdamage xd_area xd_mem alphacut alphafrac\n"
-" alpharemove noalpharemove alphablend noalphablend\n"
-" xwarppointer xwarp noxwarppointer noxwarp buttonmap\n"
-" dragging nodragging ncache_cr noncache_cr ncache\n"
+" cursorpos nocursorpos cursor_drag nocursor_drag\n"
+" cursor show_cursor noshow_cursor nocursor arrow\n"
+" xfixes noxfixes xdamage noxdamage xd_area xd_mem\n"
+" alphacut alphafrac alpharemove noalpharemove alphablend\n"
+" noalphablend xwarppointer xwarp noxwarppointer noxwarp\n"
+" buttonmap dragging nodragging ncache_cr noncache_cr\n"
+" ncache_no_moveraise noncache_no_moveraise ncache\n"
" noncache ncache_size wireframe_mode wireframe wf\n"
" nowireframe nowf wireframelocal wfl nowireframelocal\n"
" nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
diff --git a/x11vnc/options.c b/x11vnc/options.c
index f25582f..fcb1961 100644
--- a/x11vnc/options.c
+++ b/x11vnc/options.c
@@ -197,16 +197,26 @@ int wireframe_local = 1;
#ifndef NCACHE
#define NCACHE -10
#endif
-int ncache = NCACHE;
-int ncache0 = 0;
-int ncache_copyrect = 0;
-int macosx_ncache_macmenu = 0;
-int ncache_beta_tester = 0;
#ifdef MACOSX
+int ncache = 0;
int ncache_pad = 24;
#else
+int ncache = NCACHE;
int ncache_pad = 0;
#endif
+int ncache0 = 0;
+int ncache_copyrect = 0;
+int ncache_wf_raises = 1;
+int ncache_dt_change = 1;
+int macosx_ncache_macmenu = 0;
+int ncache_beta_tester = 0;
+
+Atom atom_NET_ACTIVE_WINDOW = None;
+Atom atom_NET_CURRENT_DESKTOP = None;
+Atom atom_NET_CLIENT_LIST_STACKING = None;
+double got_NET_ACTIVE_WINDOW = 0.0;
+double got_NET_CURRENT_DESKTOP = 0.0;
+double got_NET_CLIENT_LIST_STACKING = 0.0;
/* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
char *scroll_copyrect_str = NULL;
diff --git a/x11vnc/options.h b/x11vnc/options.h
index 856df15..cc53a29 100644
--- a/x11vnc/options.h
+++ b/x11vnc/options.h
@@ -159,10 +159,19 @@ extern int wireframe_in_progress;
extern int ncache;
extern int ncache0;
extern int ncache_copyrect;
+extern int ncache_wf_raises;
+extern int ncache_dt_change;
extern int ncache_pad;
extern int macosx_ncache_macmenu;
extern int ncache_beta_tester;
+extern Atom atom_NET_ACTIVE_WINDOW;
+extern Atom atom_NET_CURRENT_DESKTOP;
+extern Atom atom_NET_CLIENT_LIST_STACKING;
+extern double got_NET_ACTIVE_WINDOW;
+extern double got_NET_CURRENT_DESKTOP;
+extern double got_NET_CLIENT_LIST_STACKING;
+
extern char *scroll_copyrect_str;
extern char *scroll_copyrect;
extern char *scroll_copyrect_default;
diff --git a/x11vnc/remote.c b/x11vnc/remote.c
index 775816c..64a6369 100644
--- a/x11vnc/remote.c
+++ b/x11vnc/remote.c
@@ -2748,6 +2748,36 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ncache_copyrect = 0;
rfbLog("remote_cmd: disabled -ncache_cr %d\n", ncache_copyrect);
+ } else if (!strcmp(p, "ncache_no_moveraise")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !ncache_wf_raises);
+ goto qry;
+ }
+ ncache_wf_raises = 0;
+ rfbLog("remote_cmd: set -ncache_no_moveraise\n");
+ } else if (!strcmp(p, "noncache_no_moveraise")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, ncache_wf_raises);
+ goto qry;
+ }
+ ncache_wf_raises = 1;
+ rfbLog("remote_cmd: disabled -ncache_no_moveraise\n");
+
+ } else if (!strcmp(p, "ncache_no_dtchange")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !ncache_dt_change);
+ goto qry;
+ }
+ ncache_dt_change = 0;
+ rfbLog("remote_cmd: set -ncache_no_dt_change\n");
+ } else if (!strcmp(p, "noncache_no_dtchange")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, ncache_dt_change);
+ goto qry;
+ }
+ ncache_dt_change = 1;
+ rfbLog("remote_cmd: disabled -ncache_no_dt_change\n");
+
} else if (!strcmp(p, "ncache")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);
diff --git a/x11vnc/scan.c b/x11vnc/scan.c
index 7ffc24f..a05d063 100644
--- a/x11vnc/scan.c
+++ b/x11vnc/scan.c
@@ -2897,7 +2897,7 @@ if (ncache > 0) {
nomsg = 0;
}
} else {
-fprintf(stderr, "*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d rescan=%d\n", gotone, y, rescan);
+fprintf(stderr, "\n*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d rescan=%d\n", gotone, y, rescan);
}
X_UNLOCK;
check_ncache(0, 1);
diff --git a/x11vnc/ssltools.h b/x11vnc/ssltools.h
index 06520ab..dc38ef7 100644
--- a/x11vnc/ssltools.h
+++ b/x11vnc/ssltools.h
@@ -829,7 +829,7 @@ char find_display[] =
char create_display[] =
"#!/bin/sh\n"
"\n"
-"CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\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"
diff --git a/x11vnc/tkx11vnc b/x11vnc/tkx11vnc
index 6974778..d0ce05a 100755
--- a/x11vnc/tkx11vnc
+++ b/x11vnc/tkx11vnc
@@ -360,6 +360,13 @@ Tuning
xd_area:
xd_mem:
=GAL LOFF
+ =GAL Ncache::
+ ncache
+ ncache_size:
+ ncache_cr
+ ncache_no_moveraise
+ ncache_no_dtchange
+ =GAL LOFF
--
=GAL SharedMemory::
noshm
@@ -381,10 +388,6 @@ Tuning
rfbwait:
nodpms
nofbpm
- --
- ncache
- ncache_size:
- ncache_cr
=GAL LOFF
"
}
@@ -1056,6 +1059,17 @@ effectively as hints to improve its performance.
The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.
"
+ set helptext(Ncache:) "
+A simple client-side (viewer) caching scheme is enabled with the
+\"-ncache n\" option. It simply uses \"n\" framebuffer sized areas
+below the actual display for caching window pixel data.
+
+Drawbacks are it uses a lot of RAM (roughly n times more), and the
+pixels cache area is visible in the viewers.
+
+The items in the sub-menu allow tweaking x11vnc's -ncache algorithm.
+"
+
set helptext(SharedMemory:) "
This sub-menu provides some options regarding SYSV shared memory usage
(shm) by x11vnc. Usually you want shm turned on because the x11vnc
diff --git a/x11vnc/tkx11vnc.h b/x11vnc/tkx11vnc.h
index 593637e..823e026 100644
--- a/x11vnc/tkx11vnc.h
+++ b/x11vnc/tkx11vnc.h
@@ -371,6 +371,13 @@ char gui_code[] = "";
" xd_area:\n"
" xd_mem:\n"
" =GAL LOFF\n"
+" =GAL Ncache::\n"
+" ncache\n"
+" ncache_size:\n"
+" ncache_cr\n"
+" ncache_no_moveraise\n"
+" ncache_no_dtchange\n"
+" =GAL LOFF\n"
" --\n"
" =GAL SharedMemory::\n"
" noshm\n"
@@ -392,10 +399,6 @@ char gui_code[] = "";
" rfbwait:\n"
" nodpms\n"
" nofbpm\n"
-" --\n"
-" ncache\n"
-" ncache_size:\n"
-" ncache_cr\n"
" =GAL LOFF\n"
"\"\n"
"}\n"
@@ -1067,6 +1070,17 @@ char gui_code[] = "";
"The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.\n"
"\"\n"
"\n"
+" set helptext(Ncache:) \"\n"
+"A simple client-side (viewer) caching scheme is enabled with the\n"
+"\\\"-ncache n\\\" option. It simply uses \\\"n\\\" framebuffer sized areas\n"
+"below the actual display for caching window pixel data. \n"
+"\n"
+"Drawbacks are it uses a lot of RAM (roughly n times more), and the\n"
+"pixels cache area is visible in the viewers.\n"
+"\n"
+"The items in the sub-menu allow tweaking x11vnc's -ncache algorithm.\n"
+"\"\n"
+"\n"
" set helptext(SharedMemory:) \"\n"
"This sub-menu provides some options regarding SYSV shared memory usage\n"
"(shm) by x11vnc. Usually you want shm turned on because the x11vnc\n"
diff --git a/x11vnc/user.c b/x11vnc/user.c
index cf7cbe4..1a2bbd8 100644
--- a/x11vnc/user.c
+++ b/x11vnc/user.c
@@ -1235,6 +1235,7 @@ int wait_for_client(int *argc, char** argv, int http) {
char *create_cmd = NULL;
char *users_list_save = NULL;
int created_disp = 0;
+ int ncache_save;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0;
@@ -1341,6 +1342,9 @@ int wait_for_client(int *argc, char** argv, int http) {
*argc = (*argc) + 1;
}
+ ncache_save = ncache;
+ ncache = 0;
+
initialize_allowed_input();
if (! multiple_cursors_mode) {
@@ -1745,6 +1749,8 @@ if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
free(create_cmd);
}
+ ncache = ncache_save;
+
return 1;
}
diff --git a/x11vnc/userinput.c b/x11vnc/userinput.c
index 4099ca5..57a302a 100644
--- a/x11vnc/userinput.c
+++ b/x11vnc/userinput.c
@@ -80,8 +80,8 @@ static void set_bdpush(int type, double *last_bdpush, int *pushit);
static int repeat_check(double last_key_scroll);
static int check_xrecord_keys(void);
static int check_xrecord_mouse(void);
-static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy,
- int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch);
+static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
+ int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch);
static int wireframe_mod_state();
static void check_user_input2(double dt);
static void check_user_input3(double dt, double dtr, int tile_diffs);
@@ -1369,7 +1369,7 @@ if (n) { \
int batch_dxs[], batch_dys[];
sraRegionPtr batch_reg[];
-void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double delay);
+void batch_push(int ncr, double delay);
static int push_scr_ev(double *age, int type, int bdpush, int bdx, int bdy,
int bdskinny, int first_push) {
@@ -1568,7 +1568,7 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
if (fast_push) {
int k, nbatch = 0;
double delay, d1 = 0.1, d2 = 0.02;
- rc = try_copyrect(frame, x, y, w, h, dx, dy, &obscured,
+ rc = try_copyrect(frame, frame, x, y, w, h, dx, dy, &obscured,
tmpregion, waittime, &nbatch);
if (first_push) {
@@ -1577,13 +1577,10 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
delay = d2;
}
- batch_copyregion(batch_reg, batch_dxs, batch_dys, nbatch, delay);
- for (k=0; k < nbatch; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
+ batch_push(nbatch, delay);
fb_push();
} else {
- rc = try_copyrect(frame, x, y, w, h, dx, dy, &obscured,
+ rc = try_copyrect(frame, frame, x, y, w, h, dx, dy, &obscured,
tmpregion, waittime, NULL);
if (rc) {
last_scroll_type = type;
@@ -1972,19 +1969,43 @@ if (0) fprintf(stderr, "s... %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy)
void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double delay) {
rfbClientIteratorPtr i;
rfbClientPtr cl;
- int k, direct, mode, nrects = 0;
+ int k, direct, mode, nrects = 0, bad = 0;
/* XXX Y */
+ for (k=0; k < ncr; k++) {
+ sraRectangleIterator *iter;
+ sraRect rect;
+
+ iter = sraRgnGetIterator(region[k]);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ int x1 = rect.x1;
+ int y1 = rect.y1;
+ int x2 = rect.x2;
+ int y2 = rect.y2;
+ int ym = dpy_y * (ncache+1);
+ int xm = dpy_x;
+ if (x1 > xm || y1 > ym || x2 > xm || y2 > ym) {
+ fprintf(stderr, "batch_copyregion: BAD RECTANGLE: %d,%d %d,%d\n", x1, y1, x2, y2);
+ bad = 1;
+ }
+ if (x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0) {
+ fprintf(stderr, "batch_copyregion: BAD RECTANGLE: %d,%d %d,%d\n", x1, y1, x2, y2);
+ bad = 1;
+ }
+ }
+ sraRgnReleaseIterator(iter);
+ nrects += sraRgnCountRects(region[k]);
+ }
+ if (bad || nrects == 0) {
+ return;
+ }
+
if (delay < 0.0) {
delay = 0.1;
}
fb_push_wait(delay, FB_COPY|FB_MOD);
- for (k=0; k < ncr; k++) {
- nrects += sraRgnCountRects(region[k]);
- }
-
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
@@ -2022,6 +2043,14 @@ fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d\n", nrects, ncr);
}
+void batch_push(int nreg, double delay) {
+ int k;
+ batch_copyregion(batch_reg, batch_dxs, batch_dys, nreg, delay);
+ for (k=0; k < nreg; k++) {
+ sraRgnDestroy(batch_reg[k]);
+ }
+}
+
void fb_push0(void) {
char *httpdir = screen->httpDir;
int defer = screen->deferUpdateTime;
@@ -3041,8 +3070,8 @@ if (0) fprintf(stderr, "check_xrecord: button_mask: %d mouse_wants_back_in: %d\
int batch_dxs[NBATCHMAX], batch_dys[NBATCHMAX];
sraRegionPtr batch_reg[NBATCHMAX];
-static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy,
- int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch) {
+static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
+ int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch) {
static int dt_bad = 0;
static time_t dt_bad_check = 0;
@@ -3075,7 +3104,7 @@ static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy
*/
if (time(NULL) > dt_bad_check + 5) {
char *dt = guess_desktop();
- if (!strcmp(dt, "kde")) {
+ if (!strcmp(dt, "kde_maybe_is_ok_now...")) {
dt_bad = 1;
} else if (!strcmp(dt, "xfce")) {
dt_bad = 1;
@@ -3093,7 +3122,10 @@ static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy
x -= off_x;
y -= off_y;
}
-if (db2) fprintf(stderr, "try_copyrect: 0x%lx bad: %d stack_list_num: %d\n", frame, dt_bad, stack_list_num);
+if (db2) fprintf(stderr, "try_copyrect: 0x%lx/0x%lx bad: %d stack_list_num: %d\n", orig_frame, frame, dt_bad, stack_list_num);
+
+/* XXX Y */
+//dt_bad = 0;
if (dt_bad && wireframe_in_progress) {
sraRegionPtr rect;
@@ -3171,16 +3203,13 @@ if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n",
swin = stack_list[k].win;
if (db2) fprintf(stderr, "sw: %d/%lx\n", k, swin);
- if (swin == frame) {
+ if (swin == frame || swin == orig_frame) {
if (db2) {
saw_me = 1; fprintf(stderr, " ----------\n");
} else {
break;
}
}
-#if 0
-fprintf(stderr, "bo: %d/%lx\n", k, swin);
-#endif
/* skip some unwanted cases: */
#ifndef MACOSX
@@ -3224,6 +3253,7 @@ fprintf(stderr, "bo: %d/%lx\n", k, swin);
if (attr.map_state != IsViewable) {
continue;
}
+if (db2) fprintf(stderr, "sw: %d/%lx %dx%d+%d+%d\n", k, swin, stack_list[k].width, stack_list[k].height, stack_list[k].x, stack_list[k].y);
if (clipshift) {
attr.x -= coff_x;
@@ -3544,29 +3574,32 @@ static sraRegionPtr NPP_roffscreen = NULL;
static sraRegionPtr NPP_r_bs_tmp = NULL;
static Window NPP_nwin = None;
-void clear_win_events(void) {
+void clear_win_events(Window win, int vis) {
#if !NO_X11
- if (dpy && NPP_nwin != None) {
+ if (dpy && win != None && ncache) {
XEvent ev;
XErrorHandler old_handler;
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
- while (XCheckTypedWindowEvent(dpy, NPP_nwin, ConfigureNotify, &ev)) {
+ while (XCheckTypedWindowEvent(dpy, win, ConfigureNotify, &ev)) {
fprintf(stderr, ".");
if (trapped_xerror) {
break;
}
trapped_xerror = 0;
}
- while (XCheckTypedWindowEvent(dpy, NPP_nwin, VisibilityNotify, &ev)) {
- fprintf(stderr, "+");
- if (trapped_xerror) {
- break;
+/* XXX Y */
+ if (vis) {
+ while (XCheckTypedWindowEvent(dpy, win, VisibilityNotify, &ev)) {
+ fprintf(stderr, "+");
+ if (trapped_xerror) {
+ break;
+ }
+ trapped_xerror = 0;
}
- trapped_xerror = 0;
}
XSetErrorHandler(old_handler);
- fprintf(stderr, " 0x%x\n", (unsigned int) NPP_nwin);
+ fprintf(stderr, " 0x%x\n", (unsigned int) win);
}
#endif
}
@@ -3962,11 +3995,7 @@ void ncache_post_portions(int nidx, int use_batch, int orig_x, int orig_y, int o
sraRgnDestroy(r1);
if (use_batch) {
- int k;
- batch_copyregion(batch_reg, batch_dxs, batch_dys, NPP_nreg, batch_delay);
- for (k=0; k < NPP_nreg; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
+ batch_push(NPP_nreg, batch_delay);
fprintf(stderr, "FB_COPY: %.4f XX did batch 0x%x %3d su: %dx%d+%d+%d bs: %dx%d+%d+%d\n", dnow() - ntim,
(unsigned int) cache_list[nidx].win, nidx, su_w, su_h, su_x, su_y, bs_w, bs_h, bs_x, bs_y);
}
@@ -3978,11 +4007,7 @@ fprintf(stderr, "FB_COPY: %.4f XX did batch 0x%x %3d su: %dx%d+%d+%d bs: %dx%d+
}
} else {
if (use_batch) {
- int k;
- batch_copyregion(batch_reg, batch_dxs, batch_dys, NPP_nreg, batch_delay);
- for (k=0; k < NPP_nreg; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
+ batch_push(NPP_nreg, batch_delay);
}
}
@@ -4126,6 +4151,58 @@ void check_macosx_click_frame(void) {
#endif
}
+int clipped(int idx);
+void snap_old(void);
+
+int check_copyrect_raise(int idx, Window orig_frame, int try_batch) {
+ char *no = "none";
+ int doraise = 1;
+
+ if (! ncache_wf_raises) {
+ doraise = 0;
+ no = "ncache_wf_raises";
+ } else if (cache_list[idx].bs_time == 0.0) {
+ doraise = 0;
+ no = "bs_time";
+ } else if (0 && cache_list[idx].vis_state == VisibilityUnobscured) {
+ doraise = 0;
+ no = "VisibilityUnobscured";
+ } else if (!clipped(idx)) {
+ doraise = 0;
+ no = "!clipped()";
+ }
+ if (doraise) {
+ int nr = 0, *nb = NULL;
+fprintf(stderr, "--YES, wf_raise\n");
+ if (try_batch) {
+ nb = &nr;
+ }
+ bs_restore(idx, nb, 0, 1, 1, 1);
+ try_to_fix_su(orig_frame, idx, 0x1, nb, NULL);
+ if (nb && nr) {
+ batch_push(nr, -1.0);
+ }
+ fb_push(); /* XXX Y */
+ } else {
+if (no) fprintf(stderr, "--NO, wf_raise: %s\n", no);
+ }
+ if (ncache_wf_raises) {
+ snapshot_stack_list(0, 0.0);
+ snap_old();
+ }
+}
+
+int set_copyrect_drag(int idx, Window orig_frame, int try_batch) {
+ if (idx < 0) {
+ return 0;
+ }
+ if (cache_list[idx].su_time > 0.0) {
+ check_copyrect_raise(idx, orig_frame, try_batch);
+ return 1;
+ }
+ return 0;
+}
+
/*
* Applied just before any check_user_input() modes. Look for a
* ButtonPress; find window it happened in; find the wm frame window
@@ -4244,7 +4321,11 @@ if (db) fprintf(stderr, "NO get_wm_frame_pos-1: 0x%lx\n", frame);
return 0;
}
X_UNLOCK;
-if (db) fprintf(stderr, "a: %d wf: %.3f A: %d frm: 0x%lx\n", w*h, wireframe_frac, (dpy_x*dpy_y), frame);
+
+ last_get_wm_frame_time = dnow();
+ last_get_wm_frame = frame;
+
+if (db) fprintf(stderr, "a: %d wf: %.3f A: %d origfrm: 0x%lx\n", w*h, wireframe_frac, (dpy_x*dpy_y), frame);
/*
* apply the percentage size criterion (allow opaque moves for
@@ -4378,7 +4459,7 @@ if (db) fprintf(stderr, "INTERIOR\n");
XFlush_wr(dpy);
X_UNLOCK;
- /* try do induce/waitfor some more user input */
+ /* try to induce/waitfor some more user input */
if (use_threads) {
usleep(1000);
} else if (drew_box && do_copyrect_drag != 1) {
@@ -4609,17 +4690,20 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} else if (w != box_w || h != box_h) {
do_copyrect_drag = 0;
} else if (do_copyrect_drag < 0) {
- int idx = lookup_win_index(orig_frame);
+ Window fr = orig_frame;
+ int idx = lookup_win_index(fr);
if (idx < 0) {
- idx = lookup_win_index(frame);
+ fr = frame;
+ idx = lookup_win_index(fr);
}
if (idx >= 0) {
- if (cache_list[idx].su_time > 0.0) {
- /* XXX Y */
+ do_copyrect_drag = set_copyrect_drag(idx, fr, try_batch);
+ if (do_copyrect_drag) {
min_draw *= 0.66;
- do_copyrect_drag = 1;
}
nidx = idx;
+ } else {
+ do_copyrect_drag = 0;
}
now_x = orig_x;
now_y = orig_y;
@@ -4631,8 +4715,18 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
}
}
- drew_box = 1;
if (do_copyrect_drag <= 0) {
+ if (!drew_box && ncache_wf_raises) {
+ Window fr = orig_frame;
+ int idx = lookup_win_index(fr);
+ if (idx < 0) {
+ fr = frame;
+ idx = lookup_win_index(fr);
+ }
+ if (idx >= 0) {
+ check_copyrect_raise(idx, fr, try_batch);
+ }
+ }
draw_box(x, y, w, h, 0);
fb_push(); /* XXX Y */
rfbPE(1000);
@@ -4648,6 +4742,8 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
}
#endif
}
+ drew_box = 1;
+ last_wireframe = dnow();
last_draw = spin;
last_draw_cnt = cnt;
@@ -4712,11 +4808,17 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
} else if (skip_cr_when_scaling("wireframe")) {
;
} else if (w != orig_w || h != orig_h) {
- ;
+ if (ncache > 0) {
+ try_to_fix_resize_su(orig_frame, orig_x, orig_y, orig_w, orig_h, x, y, w, h, try_batch);
+ clear_win_events(orig_frame, 1);
+ if (frame != orig_frame) {
+ clear_win_events(frame, 1);
+ }
+ }
} else if (dx == 0 && dy == 0) {
;
} else if (do_copyrect_drag > 0) {
- clear_win_events();
+ clear_win_events(NPP_nwin, 0);
} else {
int spin_ms = (int) (spin * 1000 * 1000);
int obscured, sent_copyrect = 0;
@@ -4758,16 +4860,16 @@ fprintf(stderr, "FB_COPY failed again! %.4f", dnow() - ntim);
/* 2) try to send a clipped copyrect of translation: */
if (! try_batch) {
- sent_copyrect = try_copyrect(frame, x, y, w, h, dx, dy,
+ sent_copyrect = try_copyrect(orig_frame, frame, x, y, w, h, dx, dy,
&obscured, NULL, 0.15, NULL);
} else {
- try_copyrect(frame, x, y, w, h, dx, dy,
+ try_copyrect(orig_frame, frame, x, y, w, h, dx, dy,
&obscured, NULL, 0.15, &NPP_nreg); /* XXX */
sent_copyrect = 1;
use_batch = 1;
}
-if (db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copyrect, obscured, frame);
+if (1 || db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copyrect, obscured, frame);
if (sent_copyrect) {
/* try to push the changes to viewers: */
if (use_batch) {
@@ -4781,7 +4883,7 @@ if (db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copy
#ifndef NO_NCACHE
ncache_post_portions(nidx, use_batch,
orig_x, orig_y, orig_w, orig_h, x, y, w, h, -1.0, ntim);
- clear_win_events();
+ clear_win_events(NPP_nwin, 0);
#endif
if (scaling && !use_batch) {
@@ -5415,10 +5517,8 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
if (wireframe) {
if (check_wireframe()) {
-fprintf(stderr, "check_wireframe: 1\n");
return 0;
}
-//fprintf(stderr, "check_wireframe: 0\n");
}
if (pointer_mode == 1) {
@@ -5583,6 +5683,56 @@ void snapshot_cache_list(int free_only, double allowed_age) {
#endif /* NO_X11 */
}
+void quick_snap(Window *wins, int *size) {
+ int num, rc, i;
+ unsigned int ui;
+ Window r, w;
+ Window *list;
+
+#ifdef MACOSX
+ if (1 || ! macosx_console) {
+ RAWFB_RET_VOID
+ }
+#else
+ RAWFB_RET_VOID
+#endif
+
+
+#if NO_X11 && !defined(MACOSX)
+ num = rc = i = 0; /* compiler warnings */
+ ui = 0;
+ r = w = None;
+ list = NULL;
+ return;
+#else
+
+ X_LOCK;
+ /* no need to trap error since rootwin */
+ rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
+ X_UNLOCK;
+ num = (int) ui;
+
+ if (! rc || num == 0) {
+ *size = 0;
+ return;
+ } else {
+ int m = *size;
+ if (num < m) {
+ m = num;
+ }
+ for (i=0; i < m; i++) {
+ wins[i] = list[i];
+ }
+ if (num) {
+ X_LOCK;
+ XFree_wr(list);
+ X_UNLOCK;
+ }
+ *size = m;
+ }
+#endif /* NO_X11 */
+}
+
int get_bs_n(int y) {
int n;
for (n = 1; n < ncache; n += 2) {
@@ -5698,6 +5848,63 @@ fprintf(stderr, "lookup_freeB: %d\n", rfree);
return rfree;
}
+#define STACKMAX 4096
+Window old_stack[STACKMAX];
+Window new_stack[STACKMAX];
+Window old_stack_map[STACKMAX];
+Window new_stack_map[STACKMAX];
+int old_stack_index[STACKMAX];
+int old_stack_mapped[STACKMAX];
+int old_stack_n = 0;
+int new_stack_n = 0;
+int old_stack_map_n = 0;
+int new_stack_map_n = 0;
+
+void snap_old(void) {
+ int i;
+ old_stack_n = STACKMAX;
+ quick_snap(old_stack, &old_stack_n);
+ for (i=0; i < old_stack_n; i++) {
+ old_stack_mapped[i] = -1;
+ }
+}
+
+void snap_old_index(void) {
+ int i, idx;
+ for (i=0; i < old_stack_n; i++) {
+ idx = lookup_win_index(old_stack[i]);
+ old_stack_index[i] = idx;
+ if (idx >= 0) {
+ if (cache_list[idx].map_state == IsViewable) {
+ old_stack_mapped[i] = 1;
+ } else {
+ old_stack_mapped[i] = 0;
+ }
+ }
+ }
+}
+
+int lookup_old_stack_index(int ic) {
+ int idx = old_stack_index[ic];
+
+ if (idx < 0) {
+ return -1;
+ }
+ if (cache_list[idx].win != old_stack[ic]) {
+ snap_old_index();
+ }
+ idx = old_stack_index[ic];
+ if (idx < 0 || cache_list[idx].win != old_stack[ic]) {
+ return -1;
+ }
+ if (cache_list[idx].map_state == IsViewable) {
+ old_stack_mapped[ic] = 1;
+ } else {
+ old_stack_mapped[ic] = 0;
+ }
+ return idx;
+}
+
#define STORE(k, w, attr) \
cache_list[k].win = w; \
cache_list[k].fetched = 1; \
@@ -6292,7 +6499,6 @@ int find_rect(int idx, int x, int y, int w, int h) {
rect_reg[n] = sraRgnCreateRect(0, n * dpy_y, dpy_x, (n+1) * dpy_y);
}
} else if (now > last_clean + 60) {
-//fprintf(stderr, "free_rect: cleaning up regions:\n");
last_clean = now;
for (n = 1; n < ncache; n += 2) {
int i, n2 = n+1;
@@ -6384,7 +6590,7 @@ fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hi
fr_BIG1t++;
return 0;
}
- if (w == dpy_x && h && dpy_y) {
+ if (w == dpy_x && h == dpy_y) {
fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d (FULL DISPLAY)\n", w, h, x, y, x_hit, y_hit);
fr_BIG1++;
fr_BIG1t++;
@@ -6573,21 +6779,124 @@ int valid_wr(int idx, Window win, XWindowAttributes *attr) {
return valid_window(win, attr, 1);
}
-int bs_save(int idx, int *nbatch, int verb) {
+int clipped(int idx) {
+ int ic;
+ sraRegionPtr r0, r1, r2;
+ int x1, y1, w1, h1;
+ Window win;
+ int clip = 0;
+
+ if (idx < 0) {
+ return 0;
+ }
+ r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
+
+ x1 = cache_list[idx].x;
+ y1 = cache_list[idx].y;
+ w1 = cache_list[idx].width;
+ h1 = cache_list[idx].height;
+
+ win = cache_list[idx].win;
+
+ r1 = sraRgnCreateRect(x1, y1, x1+w1, y1+h1);
+ sraRgnAnd(r1, r0);
+
+ for (ic = old_stack_n - 1; ic >= 0; ic--) {
+ int xc, yc, wc, hc, idx2;
+
+ if (old_stack[ic] == win) {
+ break;
+ }
+ if (old_stack_mapped[ic] == 0) {
+ continue;
+ }
+ idx2 = lookup_old_stack_index(ic);
+ if (idx2 < 0) {
+ continue;
+ }
+ if (cache_list[idx2].win == win) {
+ break;
+ }
+ if (cache_list[idx2].map_state != IsViewable) {
+ continue;
+ }
+ xc = cache_list[idx2].x;
+ yc = cache_list[idx2].y;
+ wc = cache_list[idx2].width;
+ hc = cache_list[idx2].height;
+
+ r2 = sraRgnCreateRect(xc, yc, xc+wc, yc+hc);
+ sraRgnAnd(r2, r0);
+ if (sraRgnAnd(r2, r1)) {
+//fprintf(stderr, "clip[0x%x]: 0x%x, %d/%d\n", win, cache_list[idx2].win, ic, idx2);
+ clip = 1;
+ }
+ sraRgnDestroy(r2);
+ if (clip) {
+ break;
+ }
+ }
+ sraRgnDestroy(r0);
+ sraRgnDestroy(r1);
+//fprintf(stderr, "clip[0x%x]: %s\n", win, clip ? "clipped" : "no-clipped");
+ return clip;
+}
+
+void clip_region(sraRegionPtr r, Window win) {
+ int ic, idx2;
+ sraRegionPtr r1;
+ for (ic = old_stack_n - 1; ic >= 0; ic--) {
+ int xc, yc, wc, hc;
+
+//fprintf(stderr, "----[0x%x]: 0x%x, %d %d\n", win, old_stack[ic], ic, old_stack_mapped[ic]);
+ if (old_stack[ic] == win) {
+ break;
+ }
+ if (old_stack_mapped[ic] == 0) {
+ continue;
+ }
+ idx2 = lookup_old_stack_index(ic);
+ if (idx2 < 0) {
+ continue;
+ }
+ if (cache_list[idx2].win == win) {
+ break;
+ }
+ if (cache_list[idx2].map_state != IsViewable) {
+ continue;
+ }
+ xc = cache_list[idx2].x;
+ yc = cache_list[idx2].y;
+ wc = cache_list[idx2].width;
+ hc = cache_list[idx2].height;
+ r1 = sraRgnCreateRect(xc, yc, xc+wc, yc+hc);
+ if (sraRgnAnd(r1, r)) {
+ sraRgnSubtract(r, r1);
+//fprintf(stderr, "clip[0x%x]: 0x%x, %d/%d\n", win, cache_list[idx2].win, ic, idx2);
+ }
+ sraRgnDestroy(r1);
+ }
+}
+
+int bs_save(int idx, int *nbatch, int clip, int only_if_tracking, int verb) {
Window win = cache_list[idx].win;
XWindowAttributes attr;
int x1, y1, w1, h1;
int x2, y2, w2, h2;
int x, y, w, h;
int dx, dy, rc = 1;
- sraRegionPtr r, r0;
+ sraRegionPtr r, r0, r1;
x1 = cache_list[idx].x;
y1 = cache_list[idx].y;
w1 = cache_list[idx].width;
h1 = cache_list[idx].height;
-if (verb) fprintf(stderr, "backingstore save: 0x%x %3d \n", (unsigned int) win, idx);
+ if (only_if_tracking && cache_list[idx].bs_x < 0) {
+ return;
+ }
+
+if (verb) fprintf(stderr, "backingstore save: 0x%x %3d clip=%d\n", (unsigned int) win, idx, clip);
X_LOCK;
if (! valid_wr(idx, win, &attr)) {
@@ -6635,12 +6944,17 @@ fprintf(stderr, "BS_save: FAIL FOR: %d\n", idx);
y2 -= coff_y;
}
- dx = x - x2;
- dy = y - y2;
-
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(r, r0);
+
+ if (clip) {
+ clip_region(r, win);
+ }
+
+ dx = x - x2;
+ dy = y - y2;
+
sraRgnOffset(r, dx, dy);
dtA = dnowx();
@@ -6660,7 +6974,7 @@ if (verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
return 1;
}
-int su_save(int idx, int *nbatch, int verb) {
+int su_save(int idx, int *nbatch, int clip, int verb) {
Window win = cache_list[idx].win;
XWindowAttributes attr;
int x1, y1, w1, h1;
@@ -6721,12 +7035,17 @@ fprintf(stderr, "SU_save: FAIL FOR: %d\n", idx);
y2 -= coff_y;
}
- dx = x - x2;
- dy = y - y2;
-
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(r, r0);
+
+ if (clip) {
+ clip_region(r, win);
+ }
+
+ dx = x - x2;
+ dy = y - y2;
+
sraRgnOffset(r, dx, dy);
dtA = dnowx();
@@ -6746,7 +7065,7 @@ if (verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
return 1;
}
-int bs_restore(int idx, int *nbatch, int nopad, int verb) {
+int bs_restore(int idx, int *nbatch, int clip, int nopad, int novalidate, int verb) {
Window win = cache_list[idx].win;
XWindowAttributes attr;
int x1, y1, w1, h1;
@@ -6763,7 +7082,12 @@ if (verb) fprintf(stderr, "backingstore restore: 0x%x %3d \n", (unsigned int
h1 = cache_list[idx].height;
X_LOCK;
- if (! valid_wr(idx, win, &attr)) {
+ if (novalidate) {
+ attr.x = x1;
+ attr.y = y1;
+ attr.width = w1;
+ attr.height = h1;
+ } else if (! valid_wr(idx, win, &attr)) {
fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
DELETE(idx);
X_UNLOCK;
@@ -6782,7 +7106,9 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
h = cache_list[idx].bs_h;
if (x < 0 || cache_list[idx].bs_time == 0.0) {
- STORE(idx, win, attr);
+ if (!novalidate) {
+ STORE(idx, win, attr);
+ }
return 0;
}
@@ -6805,9 +7131,6 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
y2 -= coff_y;
}
- dx = x2 - x;
- dy = y2 - y;
-
if (w2 > w) {
w2 = w;
}
@@ -6817,9 +7140,17 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x, y, x+w2, y+h2);
+
+ dx = x2 - x;
+ dy = y2 - y;
+
sraRgnOffset(r, dx, dy);
sraRgnAnd(r, r0);
+ if (clip) {
+ clip_region(r, win);
+ }
+
dtA = dnowx();
if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
if (w2 > 0 && h2 > 0) {
@@ -6831,12 +7162,14 @@ if (verb) fprintf(stderr, "BS_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
sraRgnDestroy(r0);
sraRgnDestroy(r);
- STORE(idx, win, attr);
+ if (!novalidate) {
+ STORE(idx, win, attr);
+ }
return 1;
}
-int su_restore(int idx, int *nbatch, int nopad, int verb) {
+int su_restore(int idx, int *nbatch, int clip, int nopad, int verb) {
Window win = cache_list[idx].win;
XWindowAttributes attr;
int x1, y1, w1, h1;
@@ -6901,9 +7234,6 @@ fprintf(stderr, "SU_rest: su_x/bs_x/su_time: %d %d %.3f\n", x, cache_list[idx].b
y2 -= coff_y;
}
- dx = x2 - x;
- dy = y2 - y;
-
if (w2 > w) {
w2 = w;
}
@@ -6913,9 +7243,17 @@ fprintf(stderr, "SU_rest: su_x/bs_x/su_time: %d %d %.3f\n", x, cache_list[idx].b
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x, y, x+w2, y+h2);
+
+ dx = x2 - x;
+ dy = y2 - y;
+
sraRgnOffset(r, dx, dy);
sraRgnAnd(r, r0);
+ if (clip) {
+ clip_region(r, win);
+ }
+
dtA = dnowx();
if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
if (w2 > 0 && h2 > 0) {
@@ -6929,11 +7267,10 @@ if (verb) fprintf(stderr, "SU_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
if (invalid) {
DELETE(idx);
- return 0;
} else {
STORE(idx, win, attr);
- return 1;
}
+ return 1;
}
void check_zero_rects(void) {
@@ -7051,7 +7388,7 @@ void block_stats(void) {
fprintf(stderr, "\n");
}
-#define NSCHED 64
+#define NSCHED 128
Window sched_bs[NSCHED];
double sched_tm[NSCHED];
double last_sched_bs = 0.0;
@@ -7142,19 +7479,386 @@ Bool xcheckmaskevent(Display *d, long mask, XEvent *ev) {
#define EVMAX 2048
XEvent Ev[EVMAX];
int Ev_done[EVMAX];
+int Ev_order[EVMAX];
int Ev_area[EVMAX];
+int Ev_tmp[EVMAX];
+int Ev_tmp2[EVMAX];
Window Ev_win[EVMAX];
Window Ev_map[EVMAX];
Window Ev_unmap[EVMAX];
sraRect Ev_rects[EVMAX];
+int tmp_stack[STACKMAX];
+sraRegionPtr tmp_reg[STACKMAX];
+
+#define CLEAN_OUT \
+ for (i=0; i < n; i++) { \
+ sraRgnDestroy(tmp_reg[i]); \
+ } \
+ sraRgnDestroy(r1); \
+ sraRgnDestroy(r0);
+
+int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w, int orig_h,
+ int x, int y, int w, int h, int try_batch) {
+
+ int idx = lookup_win_index(orig_frame);
+ sraRegionPtr r0, r1, r2, r3;
+ int sx1, sy1, sw1, sh1, dx, dy;
+ int sx2, sy2, sw2, sh2;
+ int bx1, by1, bw1, bh1;
+ int bx2, by2, bw2, bh2;
+ int nr = 0, *nbat = NULL;
+
+ if (idx < 0) {
+ return 0;
+ }
+ if (cache_list[idx].bs_x < 0 || cache_list[idx].su_time == 0.0) {
+ return 0;
+ }
+
+ r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
+ r1 = sraRgnCreateRect(orig_x, orig_y, orig_x+orig_w, orig_y+orig_h);
+ r2 = sraRgnCreateRect(x, y, x+w, y+h);
+
+ sraRgnAnd(r1, r0);
+ sraRgnAnd(r2, r0);
+
+ if (try_batch) {
+ nbat = &nr;
+ }
+
+ if (orig_w >= w && orig_h >= h) {
+
+fprintf(stderr, "Shrinking resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
+ r3 = sraRgnCreateRgn(r1);
+ sraRgnSubtract(r3, r2);
+
+ sx1 = cache_list[idx].su_x;
+ sy1 = cache_list[idx].su_y;
+ sw1 = cache_list[idx].su_w;
+ sh1 = cache_list[idx].su_h;
+
+ dx = orig_x - sx1;
+ dy = orig_y - sy1;
+
+ cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
+ sraRgnDestroy(r3);
+
+ r3 = sraRgnCreateRgn(r1);
+ sraRgnAnd(r3, r2);
+
+ dx = sx1 - orig_x;
+ dy = sy1 - orig_y;
+ sraRgnOffset(r3, dx, dy);
+
+ dx = orig_x - x;
+ dy = orig_y - y;
+ sraRgnOffset(r3, dx, dy);
+
+ cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
+ sraRgnDestroy(r3);
+
+ if (nr) {
+ batch_push(nr, -1.0);
+ }
+
+ cache_list[idx].x = x;
+ cache_list[idx].y = y;
+ cache_list[idx].width = w;
+ cache_list[idx].height = h;
+
+ cache_list[idx].bs_w = w;
+ cache_list[idx].bs_h = h;
+ cache_list[idx].su_w = w;
+ cache_list[idx].su_h = h;
+
+ cache_list[idx].bs_time = 0.0;
+ cache_list[idx].su_time = dnow();
+ } else {
+fprintf(stderr, "Growing resize %d %dx%d+%d+%d -> %dx%d+%d+%d\n", idx, orig_w, orig_h, orig_x, orig_y, w, h, x, y);
+
+ sx1 = cache_list[idx].su_x;
+ sy1 = cache_list[idx].su_y;
+ sw1 = cache_list[idx].su_w;
+ sh1 = cache_list[idx].su_h;
+
+ bx1 = cache_list[idx].bs_x;
+ by1 = cache_list[idx].bs_y;
+ bw1 = cache_list[idx].bs_w;
+ bh1 = cache_list[idx].bs_h;
+
+ if (find_rect(idx, x, y, w, h)) {
+ r3 = sraRgnCreateRgn(r2);
+ sraRgnAnd(r3, r1);
+
+ dx = cache_list[idx].su_x - x;
+ dy = cache_list[idx].su_y - y;
+
+ sraRgnOffset(r3, dx, dy);
+
+ dx = dx - (sx1 - orig_x);
+ dy = dy - (sy1 - orig_y);
+
+ cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
+ sraRgnDestroy(r3);
+
+ r3 = sraRgnCreateRgn(r2);
+ sraRgnSubtract(r3, r1);
+
+ dx = cache_list[idx].su_x - x;
+ dy = cache_list[idx].su_y - y;
+
+ sraRgnOffset(r3, dx, dy);
+
+ cache_cr(r3, dx, dy, 0.075, 0.05, nbat);
+ sraRgnDestroy(r3);
+
+ if (nr) {
+ batch_push(nr, -1.0);
+ }
+
+ cache_list[idx].bs_time = 0.0;
+ cache_list[idx].su_time = dnow();
+ }
+ }
+
+ sraRgnDestroy(r0);
+ sraRgnDestroy(r1);
+ sraRgnDestroy(r2);
+}
+
+int try_to_fix_su(Window win, int idx, Window above, int *nbatch, char *mode) {
+ int i, idx2, n = 0, found = 0;
+ sraRegionPtr r0, r1, r2, r3;
+ Window win2;
+ int x, y, w, h, on = 0;
+ int x0, y0, w0, h0;
+ int x1, y1, w1, h1;
+ int x2, y2, w2, h2;
+ int unmapped = 0;
+ int moved = 0;
+
+fprintf(stderr, "TRY_TO_FIX_SU(%d) 0x%x 0x%x unmapped=%d\n", idx, win, above, unmapped);
+
+ if (mode && !strcmp(mode, "unmapped")) {
+ unmapped = 1;
+ } else if (mode && !strcmp(mode, "moved")) {
+ moved = 1;
+ }
+
+ if (idx < 0) {
+ return 0;
+ }
+ if (cache_list[idx].map_state != IsViewable && !unmapped) {
+ return 0;
+ }
+ if (cache_list[idx].su_time == 0.0) {
+ return 0;
+ }
+ if (cache_list[idx].bs_x < 0) {
+ return 0;
+ }
+
+ r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
+
+ x = cache_list[idx].x;
+ y = cache_list[idx].y;
+ w = cache_list[idx].width;
+ h = cache_list[idx].height;
+
+ r1 = sraRgnCreateRect(x, y, x+w, y+h);
+
+ sraRgnAnd(r1, r0);
+
+ if (sraRgnEmpty(r1)) {
+ CLEAN_OUT
+ return 0;
+ }
+
+ if (unmapped) {
+ on = 1;
+ }
+ if (above == 0x1) {
+ on = 1;
+ }
+ for (i = old_stack_n - 1; i >= 0; i--) {
+ win2 = old_stack[i];
+ if (win2 == above) {
+fprintf(stderr, "0x%x turn on: 0x%x\n", win, win2);
+ on = 1;
+ }
+ if (win2 == win) {
+fprintf(stderr, "0x%x turn off: 0x%x\n", win, win2);
+ found = 1;
+ on = 0;
+ break;
+ }
+ if (! on) {
+ continue;
+ }
+ idx2 = lookup_win_index(win2);
+ if (idx2 < 0) {
+ continue;
+ }
+ if (cache_list[idx2].map_state != IsViewable) {
+ continue;
+ }
+ if (cache_list[idx2].bs_x < 0) {
+ continue;
+ }
+ /* XXX Invalidate? */
+
+ x2 = cache_list[idx2].x;
+ y2 = cache_list[idx2].y;
+ w2 = cache_list[idx2].width;
+ h2 = cache_list[idx2].height;
+
+ r2 = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
+ sraRgnAnd(r2, r0);
+ if (! sraRgnAnd(r2, r1)) {
+ sraRgnDestroy(r2);
+ continue;
+ }
+
+ tmp_reg[n] = r2;
+ tmp_stack[n++] = idx2;
+ }
+
+ if (! found) {
+ CLEAN_OUT
+ return 0;
+ }
+
+ for (i = n - 1; i >= 0; i--) {
+ int i2;
+ r2 = sraRgnCreateRgn(tmp_reg[i]);
+ for (i2 = i + 1; i2 < n; i2++) {
+ sraRgnSubtract(r2, tmp_reg[i2]);
+ }
+ idx2 = tmp_stack[i];
+ if (!sraRgnEmpty(r2)) {
+ int dx, dy;
+ int dx2, dy2;
+
+ x0 = cache_list[idx2].x;
+ y0 = cache_list[idx2].y;
+ w0 = cache_list[idx2].width;
+ h0 = cache_list[idx2].height;
+
+ x1 = cache_list[idx].su_x; /* SU -> SU */
+ y1 = cache_list[idx].su_y;
+ w1 = cache_list[idx].su_w;
+ h1 = cache_list[idx].su_h;
+
+ x2 = cache_list[idx2].su_x;
+ y2 = cache_list[idx2].su_y;
+ w2 = cache_list[idx2].su_w;
+ h2 = cache_list[idx2].su_h;
+
+ dx = x2 - x0;
+ dy = y2 - y0;
+ sraRgnOffset(r2, dx, dy);
+
+ dx2 = x1 - x;
+ dy2 = y1 - y;
+ dx = dx - dx2;
+ dy = dy - dy2;
+ cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
+ }
+ sraRgnDestroy(r2);
+ }
+
+ if (unmapped) {
+ CLEAN_OUT
+ return 1;
+ }
+
+ for (i = n - 1; i >= 0; i--) {
+ r2 = sraRgnCreateRgn(tmp_reg[i]);
+ idx2 = tmp_stack[i];
+ if (!sraRgnEmpty(r2)) {
+ int dx, dy;
+ int dx2, dy2;
+
+ x0 = cache_list[idx2].x;
+ y0 = cache_list[idx2].y;
+ w0 = cache_list[idx2].width;
+ h0 = cache_list[idx2].height;
+
+ x1 = cache_list[idx].su_x; /* BS -> SU */
+ y1 = cache_list[idx].su_y;
+ w1 = cache_list[idx].su_w;
+ h1 = cache_list[idx].su_h;
+
+ x2 = cache_list[idx2].bs_x;
+ y2 = cache_list[idx2].bs_y;
+ w2 = cache_list[idx2].bs_w;
+ h2 = cache_list[idx2].bs_h;
+
+ dx = x1 - x;
+ dy = y1 - y;
+ sraRgnOffset(r2, dx, dy);
+
+ dx2 = x2 - x0;
+ dy2 = y2 - y0;
+ dx = dx - dx2;
+ dy = dy - dy2;
+ cache_cr(r2, dx, dy, save_delay0, save_delay1, nbatch);
+ }
+ sraRgnDestroy(r2);
+ }
+
+ CLEAN_OUT
+ return 1;
+}
+
+void idx_add_rgn(sraRegionPtr r, sraRegionPtr r0, int idx) {
+ int x, y, w, h;
+ sraRegionPtr rtmp;
+
+ if (idx < 0) {
+ return;
+ }
+ x = cache_list[idx].x;
+ y = cache_list[idx].y;
+ w = cache_list[idx].width;
+ h = cache_list[idx].height;
+
+ rtmp = sraRgnCreateRect(x, y, w, h);
+ if (r0) {
+ sraRgnAnd(rtmp, r0);
+ }
+ sraRgnOr(r, rtmp);
+ sraRgnDestroy(rtmp);
+}
+
+sraRegionPtr idx_create_rgn(sraRegionPtr r0, int idx) {
+ int x, y, w, h;
+ sraRegionPtr rtmp;
+
+ if (idx < 0) {
+ return NULL;
+ }
+ x = cache_list[idx].x;
+ y = cache_list[idx].y;
+ w = cache_list[idx].width;
+ h = cache_list[idx].height;
+
+ rtmp = sraRgnCreateRect(x, y, w, h);
+ if (r0) {
+ sraRgnAnd(rtmp, r0);
+ }
+ return rtmp;
+}
+
int check_ncache(int reset, int mode) {
static double last_root = 0.0;
static int first = 1;
static int last_client_count = -1;
int i, k, n;
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;
+ int n_VN = 0, n_VN_p = 0, n_VN_u = 0, n_ST = 0, n_PN = 0;
+ int did_sched = 0;
double now, refresh = 60.0;
Window win, win2;
@@ -7165,12 +7869,24 @@ int check_ncache(int reset, int mode) {
int try_batch = 1; /* XXX Y */
int use_batch = 0;
int nreg = 0, *nbatch;
- static int didtopmost = 0;
int create_cnt, create_tot;
- int pixels = 0;
+ int pixels = 0, ttot;
+ int desktop_change = 0, n1, n2;
+ static int saw_desktop_change = 0;
+ int missed_su_restore = 0;
+ int missed_bs_restore = 0;
+ sraRegionPtr r0, r;
+ sraRegionPtr missed_su_restore_rgn;
+ sraRegionPtr missed_bs_restore_rgn;
int nrects = 0;
+ int skipwins_n = 0;
+ int skipwins_max = 16;
+ Window skipwins[16];
+
+ if (unixpw_in_progress) return -1;
+
#ifdef MACOSX
if (! macosx_console) {
RAWFB_RET(-1)
@@ -7188,7 +7904,7 @@ int check_ncache(int reset, int mode) {
if (ncache0) {
if (reset) {
;
- } else if (! client_count || !ncache || nofb) {
+ } else if (!client_count || !ncache || nofb) {
static double last_purge = 0.0;
double delay = client_count ? 0.5 : 2.0;
if (now > last_purge + delay) {
@@ -7241,6 +7957,8 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
}
zero_fb(0, dpy_y, dpy_x, (ncache+1)*dpy_y);
mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0);
+
+ snap_old();
return -1;
}
@@ -7290,16 +8008,16 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
}
snapshot_cache_list(0, 100.0);
-fprintf(stderr, "cache_list_num: %d\n", cache_list_num);
for (i=0; i < cache_list_num; i++) {
CLEAR(i);
}
for (n = 1; n <= ncache; n++) {
rect_reg[n] = NULL;
}
+ snap_old();
}
- if (now < last_client + 2) {
+ if (now < last_client + 4) {
return -1;
}
@@ -7322,7 +8040,6 @@ if (hack_val == 2) {
#endif
if (now > last_root + refresh) {
- Window topmapped = None;
fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
block_stats();
@@ -7337,7 +8054,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
;
} else if (valid_window(win, &attr, 1)) {
STORE(k, win, attr);
-//fprintf(stderr, "STORE(%2d) %03dx%03d+%03d+%03d\n", k, cache_list[k].width, cache_list[k].height, cache_list[k].x, cache_list[k].y);
if (! cache_list[k].selectinput) {
xselectinput(win, win_ev, 0);
CLEAR(k);
@@ -7345,9 +8061,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
} else {
;
}
- if (attr.map_state == IsViewable) {
- topmapped = win;
- }
valid = 1;
} else {
fprintf(stderr, "DELETE(%d) %dx%d+%d+%d\n", k, cache_list[k].width, cache_list[k].height, cache_list[k].x, cache_list[k].y);
@@ -7365,32 +8078,44 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned
}
}
last_root = dnow();
- if (0 && ! didtopmost && topmapped != None) {
- int idx = lookup_win_index(topmapped);
- if (idx >= 0) {
- if (! macosx_console) {
- bs_save(idx, NULL, 1);
- }
- }
- }
- didtopmost = 1;
}
check_zero_rects();
- if (now > last_sched_bs + 0.2) {
+ if (now > last_sched_bs + 0.30) {
static double last_sched_vis = 0.0;
int nr = 0, *bat = NULL;
if (try_batch) {
bat = &nr;
}
+ if (now < last_wireframe + 2.0) {
+ for (i=0; i < NSCHED; i++) {
+ sched_bs[i] = None;
+ }
+ }
+ if (now < last_get_wm_frame_time + 1.0) {
+ if (last_get_wm_frame != None) {
+ int idx = lookup_win_index(last_get_wm_frame);
+ if (idx >= 0) {
+ if (cache_list[idx].bs_x < 0) {
+ int x = cache_list[idx].x;
+ int y = cache_list[idx].y;
+ int w = cache_list[idx].width;
+ int h = cache_list[idx].height;
+ if (find_rect(idx, x, y, w, h)) {
+ SCHED(last_get_wm_frame, 1);
+ }
+ }
+ }
+ }
+ }
for (i=0; i < NSCHED; i++) {
if (sched_bs[i] != None) {
int idx;
win = sched_bs[i];
- if (now < sched_tm[i] + 0.65) {
+ if (now < sched_tm[i] + 0.55) {
continue;
}
idx = lookup_win_index(win);
@@ -7404,39 +8129,68 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned
} else if (aw * ah < 64 * 64) {
;
} else {
-fprintf(stderr, "*SNAP BS_save: 0x%x %d %d %d\n", (unsigned int) win, aw, ah, cache_list[idx].map_state);
- bs_save(idx, bat, 0);
+//fprintf(stderr, "*SNAP BS_save: 0x%x %d %d %d\n", (unsigned int) win, aw, ah, cache_list[idx].map_state);
+ bs_save(idx, bat, 1, 0, 0);
}
}
}
sched_bs[i] = None;
}
- if (nr) {
- int k;
- batch_copyregion(batch_reg, batch_dxs, batch_dys, nr, -1.0);
- for (k=0; k < nr; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
- }
- last_sched_bs = dnow();
+ did_sched = 1;
- if (now > last_sched_vis + 3.0) {
+ if (now > last_sched_vis + 3.0 && now > last_wireframe + 2.0) {
for (i=0; i < cache_list_num; i++) {
- if (cache_list[i].map_state == IsViewable) {
+ Window win = cache_list[i].win;
+ int ok = 0;
+ int top_only = 1;
+ int aw = cache_list[i].width;
+ int ah = cache_list[i].height;
+
+ if (saw_desktop_change) {
+ top_only = 0;
+ }
+
+ if (win == None) {
+ continue;
+ }
+ if (!valid_window(win, &attr, 1)) {
+ continue;
+ }
+ STORE(i, win, attr);
+ if (!cache_list[i].valid) {
+ continue;
+ }
+ if (cache_list[i].map_state != IsViewable) {
+ continue;
+ }
+ if (aw * ah < 64 * 64) {
+ continue;
+ }
+ if (top_only) {
if (cache_list[i].vis_state == VisibilityUnobscured) {
- if (cache_list[i].valid) {
- if (cache_list[i].win != None) {
- SCHED(cache_list[i].win, 0)
- }
- }
+ ok = 1;
+ } else if (!clipped(i)) {
+ ok = 1;
}
+ } else {
+ ok = 1;
+ }
+ if (ok) {
+ bs_save(i, bat, !top_only, 0, 0);
}
}
last_sched_vis = dnow();
+ saw_desktop_change = 0;
+ }
+
+ if (nr) {
+ batch_push(nr, -1.0);
}
+ last_sched_bs = dnow();
}
n = 0;
+ ttot = 0;
create_tot = 0;
X_LOCK;
@@ -7445,18 +8199,25 @@ fprintf(stderr, "*SNAP BS_save: 0x%x %d %d %d\n", (unsigned int) win, aw, ah, ca
win = Ev[n].xany.window;
Ev_done[n] = 0;
Ev_area[n] = 0;
- Ev_win[n] = None;
+ Ev_win[n] = win;
Ev_map[n] = None;
Ev_unmap[n] = None;
+ Ev_order[n] = n;
+
+//fprintf(stderr, "----- %d/%d inputev 0x%x %s\n", n, ttot++, win, Etype(type));
if (win == rootwin) {
if (type == CreateNotify) {
- n++;
create_tot++;
+ n++;
n_CN++;
} else if (type == ReparentNotify) {
n++;
n_RN++;
+ } else if (type == PropertyNotify) {
+ set_prop_atom(Ev[n].xproperty.atom);
+ n++;
+ n_PN++;
} else {
/* skip rest */
#if 0
@@ -7489,9 +8250,11 @@ if (type != ConfigureNotify) fprintf(stderr, "root: skip %s for 0x%x\n", Etype(
n++;
n_VN++;
} else if (type == MapNotify) {
+ Ev_map[n] = win;
n++;
n_MN++;
} else if (type == UnmapNotify) {
+ Ev_unmap[n] = win;
n++;
n_UN++;
} else {
@@ -7505,16 +8268,21 @@ fprintf(stderr, "----- skip %s\n", Etype(type));
}
X_UNLOCK;
+ if (got_NET_CURRENT_DESKTOP > 0.0) {
+ if (dnow() < got_NET_CURRENT_DESKTOP + 0.25) {
+ fprintf(stderr, "***got_NET_CURRENT_DESKTOP n=%d\n", n);
+ desktop_change = 1;
+ } else {
+ fprintf(stderr, "***got_NET_CURRENT_DESKTOP n=%d STALE\n", n);
+ }
+ got_NET_CURRENT_DESKTOP = 0.0;
+ }
+
if (n == 0) {
return 0;
}
fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
- for (i=0; i < n; i++) {
- XEvent ev = Ev[i];
- Ev_win[i] = ev.xany.window;
- }
-
if (try_batch) {
use_batch = 1;
}
@@ -7533,19 +8301,163 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
nbatch = &nreg;
}
+ /* XXX Y */
+ for (n1 = 0; n1 < n; n1++) {
+ Window twin = Ev_map[n1];
+ if (twin == None || twin == rootwin) {
+ continue;
+ }
+ for (n2 = 0; n2 < n; n2++) {
+ if (Ev_unmap[n2] == twin) {
+ if (skipwins_n < skipwins_max) {
+ skipwins[skipwins_n++] = twin;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!desktop_change) {
+ if (skipwins_n) {
+ if (n_MN + n_UN >= 2 + 2*skipwins_n) {
+ desktop_change = 1;
+ }
+ } else {
+ if (n_MN + n_UN >= 4) {
+ desktop_change = 1;
+ }
+ }
+ }
+
+#define SKIPUMS \
+ ok = 1; \
+ if (twin == None || twin == rootwin) { \
+ continue; \
+ } \
+ for (ns = 0; ns < skipwins_n; ns++) { \
+ if (skipwins[ns] == twin) { \
+ ok = 0; \
+ break; \
+ } \
+ }
+
+ /* 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) {
+ 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];
+ for (k = 0; k < cnt; k++) {
+ i = Ev_tmp[k];
+ if (twin == Ev_unmap[i]) {
+ Ev_tmp2[add++] = i;
+ break;
+ }
+ }
+ }
+ k = 0;
+ for (i=0; i < n; i++) {
+ int j;
+ twin = Ev_unmap[i];
+ SKIPUMS
+ if (ok) {
+ j = Ev_tmp2[k++];
+ if (j >= 0) {
+ Ev_order[i] = j;
+ }
+ }
+ }
+
+ cnt = 0;
+ add = 0;
+ for (i=0; i < n; i++) {
+ twin = Ev_map[i];
+ SKIPUMS
+ if (ok) {
+ Ev_tmp[cnt++] = i;
+ }
+ }
+ for (k = 0; k < cnt; k++) {
+ Ev_tmp2[k] = -1;
+ }
+ /* map from bottom to top */
+ for (s = 0; s < old_stack_n; s++) {
+ twin = old_stack[s];
+ for (k = 0; k < cnt; k++) {
+ i = Ev_tmp[k];
+ if (twin == Ev_map[i]) {
+ Ev_tmp2[add++] = i;
+ break;
+ }
+ }
+ }
+ k = 0;
+ for (i=0; i < n; i++) {
+ int j;
+ twin = Ev_map[i];
+ SKIPUMS
+ if (ok) {
+ j = Ev_tmp2[k++];
+ if (j >= 0) {
+ Ev_order[i] = j;
+ }
+ }
+ }
+ }
+ if (desktop_change) {
+ if (ncache_dt_change) {
+ fprintf(stderr, "GUESSED DESKTOP CHANGE.\n");
+ saw_desktop_change = 1;
+ } else {
+ fprintf(stderr, "GUESSED DESKTOP CHANGE. Skipping.\n");
+ desktop_change = 0;
+ }
+ }
+
create_cnt = 0;
+ missed_su_restore = 0;
+ missed_bs_restore = 0;
+ missed_su_restore_rgn = sraRgnCreate();
+ missed_bs_restore_rgn = sraRgnCreate();
+ r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
X_LOCK;
for (i=0; i < n; i++) {
XEvent ev;
- int type, idx = -1;
+ int ns, skip = 0, type, idx = -1;
+ int ik = Ev_order[i];
- if (Ev_done[i]) continue;
- win = Ev_win[i];
+ if (Ev_done[ik]) continue;
+ win = Ev_win[ik];
- ev = Ev[i];
+ ev = Ev[ik];
type = ev.type;
- Ev_done[i] = 1;
+ Ev_done[ik] = 1;
+
+ for (ns = 0; ns < skipwins_n; ns++) {
+ if (win == skipwins[ns]) {
+ skip = 1;
+ break;
+ }
+ }
+ if (skip) {
+fprintf(stderr, "skip%02d: ** SpecialSkip 0x%x type: %s\n", ik, (unsigned int) win, Etype(type));
+ continue;
+ }
if (win == rootwin) {
if (type == CreateNotify) {
@@ -7567,14 +8479,15 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
y=attr.y;
w=attr.width;
h=attr.height;
-/* XXX Y */
if (create_tot <= 6 && create_cnt++ < 3) {
if (w*h > 64 * 64) {
X_UNLOCK;
- su_save(idx, nbatch, 1);
+ su_save(idx, nbatch, 0, 1);
X_LOCK;
if (cache_list[idx].valid) {
- SCHED(win2, 1)
+ if (! desktop_change) {
+ SCHED(win2, 1)
+ }
}
create_cnt++;
}
@@ -7588,25 +8501,28 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
DELETE(idx);
}
}
-fprintf(stderr, "root%02d: ** CreateNotify 0x%x %3d -- %dx%d+%d+%d valid=%d\n", i, (unsigned int) win2, idx, w, h, x, y, valid);
+fprintf(stderr, "root%02d: ** CreateNotify 0x%x %3d -- %dx%d+%d+%d valid=%d\n", ik, (unsigned int) win2, idx, w, h, x, y, valid);
} else if (type == ReparentNotify) {
if (ev.xreparent.parent != rootwin) {
win2 = ev.xreparent.window;
if (win2 != rootwin) {
idx = lookup_win_index(win2);
-fprintf(stderr, "root%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2, idx);
+fprintf(stderr, "root%02d: ReparentNotifyRM 0x%x %3d\n", ik, (unsigned int) win2, idx);
if (idx >= 0) {
DELETE(idx);
}
xselectinput(win2, 0, 1);
}
}
+ } else {
+fprintf(stderr, "root%02d: ** IgnoringRoot 0x%x type: %s\n", ik, (unsigned int) win, Etype(type));
}
} else {
if (type == ConfigureNotify) {
int x_new, y_new, w_new, h_new;
int x_old, y_old, w_old, h_old;
+ int stack_change;
Window oabove = None;
idx = lookup_win_index(win);
@@ -7615,7 +8531,7 @@ fprintf(stderr, "root%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2
oabove = cache_list[idx].above;
}
-fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x %dx%d+%d+%d\n", i, (unsigned int) win, idx,
+fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x %dx%d+%d+%d\n", ik, (unsigned int) win, idx,
(unsigned int) oabove, (unsigned int) ev.xconfigure.above, ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.x, ev.xconfigure.y);
if (idx < 0) {
@@ -7634,12 +8550,31 @@ fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x %
if (x_old != x_new || y_old != y_new) {
/* invalidate su */
cache_list[idx].su_time = 0.0;
-fprintf(stderr, " invalidate su: 0x%x xy: %d/%d %d/%d \n", (unsigned int) win, x_old, y_old, x_new, y_new);
+fprintf(stderr, " INVALIDATE su: 0x%x xy: %d/%d %d/%d \n", (unsigned int) 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%x wh: %d/%d %d/%d \n", (unsigned int) win, w_old, h_old, w_new, h_new);
+fprintf(stderr, " INVALIDATE bs: 0x%x wh: %d/%d %d/%d \n", (unsigned int) win, w_old, h_old, w_new, h_new);
+ }
+ stack_change = 0;
+ 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;
+ }
+ if (stack_change) {
+ int i2, ok = 1;
+ for (i2=0; i2 < n; i2++) {
+ if (Ev_map[i2] == win) {
+ ok = 0;
+ break;
+ }
+ }
+ if (ok) {
+ try_to_fix_su(win, idx, ev.xconfigure.above, nbatch, NULL);
+ n_ST++;
+ }
}
cache_list[idx].x = x_new;
@@ -7652,12 +8587,14 @@ fprintf(stderr, " invalidate bs: 0x%x wh: %d/%d %d/%d \n", (unsigned i
} else if (type == VisibilityNotify) {
int state = ev.xvisibility.state;
idx = lookup_win_index(win);
-fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i, (unsigned int) win, idx, VState(state), n_VN_u, n_VN_p);
+fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", ik, (unsigned int) win, idx, VState(state), n_VN_u, n_VN_p);
if (idx < 0) {
continue;
}
- if (macosx_console && n_VN_p == 0) {
+ if (desktop_change) {
+ ;
+ } else if (macosx_console && n_VN_p == 0) {
; /* XXXX not working well yet with UnmapNotify ... */
} else if (state == VisibilityUnobscured) {
int i2, ok = 1;
@@ -7672,11 +8609,11 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
}
if (ok) {
X_UNLOCK;
- bs_restore(idx, nbatch, 1, 1);
+ bs_restore(idx, nbatch, 0, 1, 0, 1);
X_LOCK;
cache_list[idx].time = dnow();
cache_list[idx].vis_cnt++;
- Ev_map[i] = win;
+ Ev_map[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width;
@@ -7689,16 +8626,47 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
} else if (type == MapNotify) {
idx = lookup_win_index(win);
-fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win, idx);
+fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", ik, (unsigned int) win, idx);
if (idx < 0) {
continue;
}
- if (cache_list[idx].map_state == IsUnmapped || macosx_console) {
+ if (cache_list[idx].map_state == IsUnmapped || desktop_change || macosx_console) {
X_UNLOCK;
- su_save(idx, nbatch, 1);
- bs_restore(idx, nbatch, 0, 1);
+ if (desktop_change) {
+ /* XXX Y */
+ int save = 1;
+ sraRegionPtr r;
+ if (cache_list[idx].su_time != 0.0) {
+ save = 0;
+ } else if (missed_su_restore) {
+ r = idx_create_rgn(r0, idx);
+ if (sraRgnAnd(r, missed_su_restore_rgn)) {
+ save = 0;
+ }
+ sraRgnDestroy(r);
+ }
+ if (missed_bs_restore) {
+ r = idx_create_rgn(r0, idx);
+ if (sraRgnAnd(r, missed_bs_restore_rgn)) {
+ save = 0;
+ }
+ sraRgnDestroy(r);
+ }
+ if (save) {
+ su_save(idx, nbatch, 1, 1);
+ }
+ } else {
+ su_save(idx, nbatch, 0, 1);
+ }
+ if (bs_restore(idx, nbatch, 0, 0, 0, 1)) { /* XXX clip? */
+ ;
+ } else {
+ idx_add_rgn(missed_bs_restore_rgn, r0, idx);
+ missed_bs_restore++;
+ }
+
if (macosx_console) {
#ifdef MACOSX
macosxCGS_follow_animation_win(win, -1, 1);
@@ -7716,7 +8684,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win,
pixels += cache_list[idx].width * cache_list[idx].height;
cache_list[idx].time = dnow();
cache_list[idx].map_cnt++;
- Ev_map[i] = win;
+ Ev_map[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width;
@@ -7727,7 +8695,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win,
} else if (type == UnmapNotify) {
idx = lookup_win_index(win);
-fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win, idx);
+fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", ik, (unsigned int) win, idx);
if (idx < 0) {
continue;
@@ -7738,15 +8706,45 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win,
}
}
- if (cache_list[idx].map_state == IsViewable || macosx_console) {
+ if (cache_list[idx].map_state == IsViewable || desktop_change || macosx_console) {
X_UNLOCK;
- bs_save(idx, nbatch, 1);
- su_restore(idx, nbatch, 0, 1);
+ if (desktop_change) {
+ int save = 1;
+ sraRegionPtr r;
+ if (cache_list[idx].bs_time > 0.0) {
+ save = 0;
+ } else if (missed_su_restore) {
+ r = idx_create_rgn(r0, idx);
+ if (sraRgnAnd(r, missed_su_restore_rgn)) {
+ save = 0;
+ }
+ sraRgnDestroy(r);
+ }
+ if (missed_bs_restore) {
+ r = idx_create_rgn(r0, idx);
+ if (sraRgnAnd(r, missed_bs_restore_rgn)) {
+ save = 0;
+ }
+ sraRgnDestroy(r);
+ }
+ if (save) {
+ bs_save(idx, nbatch, 1, 0, 1);
+ }
+ } else {
+ bs_save(idx, nbatch, 1, 0, 1);
+ }
+ if (su_restore(idx, nbatch, 1, 0, 1)) {
+ try_to_fix_su(win, idx, None, nbatch, "unmapped");
+ } else {
+ idx_add_rgn(missed_su_restore_rgn, r0, idx);
+ missed_su_restore++;
+ }
X_LOCK;
+
pixels += cache_list[idx].width * cache_list[idx].height;
cache_list[idx].time = dnow();
cache_list[idx].unmap_cnt++;
- Ev_unmap[i] = win;
+ Ev_unmap[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width;
@@ -7760,7 +8758,7 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win,
win2 = ev.xreparent.window;
if (win2 != rootwin) {
idx = lookup_win_index(win2);
-fprintf(stderr, "----%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2, idx);
+fprintf(stderr, "----%02d: ReparentNotifyRM 0x%x %3d\n", ik, (unsigned int) win2, idx);
if (idx >= 0) {
DELETE(idx);
}
@@ -7771,11 +8769,13 @@ fprintf(stderr, "----%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2
} else if (type == DestroyNotify) {
win2 = ev.xdestroywindow.window;
idx = lookup_win_index(win2);
-fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", i, (unsigned int) win2, idx);
+fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", ik, (unsigned int) win2, idx);
if (idx >= 0) {
DELETE(idx);
}
+ } else {
+fprintf(stderr, "igno%02d: ** Ignoring 0x%x type: %s\n", ik, (unsigned int) win, Etype(type));
}
}
@@ -7783,11 +8783,7 @@ fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", i, (unsigned int) win2
X_UNLOCK;
if (use_batch && nreg) {
- int k;
- batch_copyregion(batch_reg, batch_dxs, batch_dys, nreg, -1.0);
- for (k=0; k < nreg; k++) {
- sraRgnDestroy(batch_reg[k]);
- }
+ batch_push(nreg, -1.0);
}
if (nrects) {
if (scaling) {
@@ -7795,6 +8791,14 @@ fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", i, (unsigned int) win2
}
}
+ if (n_CN || n_RN || n_DN || n_MN || n_UN || n_ST || did_sched) {
+ snap_old();
+ }
+
+ sraRgnDestroy(r0);
+ sraRgnDestroy(missed_su_restore_rgn);
+ sraRgnDestroy(missed_bs_restore_rgn);
+
rfbLog("OUT check_ncache(): %.6f events: %d pixels: %d\n", dnow() - now, n, pixels);
return pixels;
}
diff --git a/x11vnc/x11vnc.1 b/x11vnc/x11vnc.1
index 389fb12..a7ca7de 100644
--- a/x11vnc/x11vnc.1
+++ b/x11vnc/x11vnc.1
@@ -1,8 +1,8 @@
.\" This file was automatically generated from x11vnc -help output.
-.TH X11VNC "1" "December 2006" "x11vnc " "User Commands"
+.TH X11VNC "1" "January 2007" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
- version: 0.8.4, lastmod: 2006-12-29
+ version: 0.8.4, lastmod: 2007-01-01
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@@ -2418,7 +2418,7 @@ detection not as accurate as the X version.
.PP
\fB-ncache_cr\fR
.IP
-In \fB-nache\fR mode, try do to copyrect opaque window
+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
@@ -2429,9 +2429,24 @@ 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.
.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_pad\fR \fIn\fR
.IP
-In \fB-nache\fR mode, pad each window with n pixels for the
+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
@@ -4001,6 +4016,10 @@ ncache_cr enable \fB-ncache_cr\fR mode.
.IP
noncache_cr disable \fB-ncache_cr\fR mode.
.IP
+ncache_no_moveraise enable no_moveraise mode.
+.IP
+noncache_no_moveraise disable no_moveraise mode.
+.IP
wireframe enable \fB-wireframe\fR mode. same as "wf"
.IP
nowireframe disable \fB-wireframe\fR mode. same as "nowf"
@@ -4277,12 +4296,13 @@ 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
+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
noncache ncache_size wireframe_mode wireframe wf
nowireframe nowf wireframelocal wfl nowireframelocal
nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area
diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c
index 73adb8f..6a44907 100644
--- a/x11vnc/x11vnc.c
+++ b/x11vnc/x11vnc.c
@@ -1451,7 +1451,7 @@ char msg[] =
"\n"
"Hello! Exciting News!!\n"
"\n"
-"You have been selected at random to beta test the x11vnc '-ncache' VNC\n"
+"You have been selected at random to beta-test the x11vnc '-ncache' VNC\n"
"client-side pixel caching feature!\n"
"\n"
"This scheme stores pixel data offscreen on the VNC viewer side for faster\n"
@@ -1468,12 +1468,13 @@ char msg[] =
"would notice and use the -ncache option (e.g. the wireframe and scroll\n"
"detection features are on by default). A couple things to note:\n"
"\n"
-" 1) It uses a large amount of RAM (on both viewer and server)\n"
+" 1) It uses a large amount of RAM (on both viewer and server sides)\n"
"\n"
" 2) You can actually see the cached pixel data if you scroll down\n"
" to it in your viewer; adjust your viewer's size to hide it.\n"
"\n"
"More info: http://www.karlrunge.com/x11vnc/#faq-client-caching\n"
+"waiting for connections:\n"
;
if (raw_fb_str && !macosx_console) {
@@ -2161,6 +2162,10 @@ int main(int argc, char* argv[]) {
}
} else if (!strcmp(arg, "-ncache_cr")) {
ncache_copyrect = 1;
+ } else if (!strcmp(arg, "-ncache_no_moveraise")) {
+ ncache_wf_raises = 1;
+ } else if (!strcmp(arg, "-ncache_no_dtchange")) {
+ ncache_dt_change = 0;
} else if (!strcmp(arg, "-ncache_pad")) {
CHECK_ARGC
ncache_pad = atoi(argv[++i]);
@@ -3249,6 +3254,7 @@ int main(int argc, char* argv[]) {
multiple_cursors_mode = strdup("most");
if (! quiet && ! raw_fb_str) {
+ rfbLog("\n");
rfbLog("XFIXES available on display, resetting cursor mode\n");
rfbLog(" to: '-cursor most'.\n");
rfbLog(" to disable this behavior use: '-cursor arrow'\n");
@@ -3390,13 +3396,13 @@ int main(int argc, char* argv[]) {
if (! quiet && ncache && ! raw_fb_str) {
rfbLog("\n");
rfbLog("Client Side Caching: -ncache mode is in effect to provide\n");
- rfbLog(" some client-side pixel data caching. This speeds up\n");
+ rfbLog(" client-side pixel data caching. This speeds up\n");
rfbLog(" iconifying/deiconifying windows, moving and raising\n");
rfbLog(" windows, and reposting menus. In the simple CopyRect\n");
rfbLog(" encoding scheme used (no compression) a huge amount\n");
rfbLog(" of extra memory (20-80MB) is used on both the server and\n");
- rfbLog(" client sides. This mode works with any VNC viewer,\n");
- rfbLog(" however in most you can actually see the cached pixel\n");
+ rfbLog(" client sides. This mode works with any VNC viewer.\n");
+ rfbLog(" However, in most you can actually see the cached pixel\n");
rfbLog(" data by scrolling down, so you need to re-adjust its size.\n");
rfbLog(" See http://www.karlrunge.com/x11vnc/#faq-client-caching.\n");
rfbLog(" If this mode yields undesired behavior (poor response,\n");
diff --git a/x11vnc/x11vnc.h b/x11vnc/x11vnc.h
index 589736b..5dad134 100644
--- a/x11vnc/x11vnc.h
+++ b/x11vnc/x11vnc.h
@@ -464,9 +464,13 @@ extern double last_pointer_motion_time;
extern double last_key_to_button_remap_time;
extern double last_copyrect;
extern double last_copyrect_fix;
+extern double last_wireframe;
extern double servertime_diff;
extern double x11vnc_start;
+extern double last_get_wm_frame_time;
+extern Window last_get_wm_frame;
+
extern int hack_val;
/* last client to move pointer */
diff --git a/x11vnc/x11vnc_defs.c b/x11vnc/x11vnc_defs.c
index 170be87..78ebe42 100644
--- a/x11vnc/x11vnc_defs.c
+++ b/x11vnc/x11vnc_defs.c
@@ -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: 2006-12-29";
+char lastmod[] = "0.8.4 lastmod: 2007-01-01";
/* X display info */
@@ -128,9 +128,13 @@ double last_pointer_motion_time = 0.0;
double last_key_to_button_remap_time = 0.0;
double last_copyrect = 0.0;
double last_copyrect_fix = 0.0;
+double last_wireframe = 0.0;
double servertime_diff = 0.0;
double x11vnc_start = 0.0;
+double last_get_wm_frame_time = 0.0;
+Window last_get_wm_frame = None;
+
int hack_val = 0;
/* last client to move pointer */
diff --git a/x11vnc/xevents.c b/x11vnc/xevents.c
index 5f22e9b..a9c6549 100644
--- a/x11vnc/xevents.c
+++ b/x11vnc/xevents.c
@@ -19,7 +19,7 @@
int grab_buster = 0;
int grab_kbd = 0;
int grab_ptr = 0;
-int sync_tod_delay = 3;
+int sync_tod_delay = 20;
void initialize_vnc_connect_prop(void);
void initialize_x11vnc_remote_prop(void);
@@ -28,6 +28,7 @@ void spawn_grab_buster(void);
void sync_tod_with_servertime(void);
void check_keycode_state(void);
void check_autorepeat(void);
+void set_prop_atom(Atom atom);
void check_xevents(int reset);
void xcut_receive(char *text, int len, rfbClientPtr cl);
@@ -600,6 +601,16 @@ void sync_tod_with_servertime(void) {
RAWFB_RET_VOID
+ if (atom_NET_ACTIVE_WINDOW == None) {
+ atom_NET_ACTIVE_WINDOW = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
+ }
+ if (atom_NET_CURRENT_DESKTOP == None) {
+ atom_NET_CURRENT_DESKTOP = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False);
+ }
+ if (atom_NET_CLIENT_LIST_STACKING == None) {
+ atom_NET_CLIENT_LIST_STACKING = XInternAtom(dpy, "_NET_CLIENT_LIST_STACKING", False);
+ }
+
if (! ticker_atom) {
ticker_atom = XInternAtom(dpy, "X11VNC_TICKER", False);
}
@@ -609,7 +620,7 @@ void sync_tod_with_servertime(void) {
XSync(dpy, False);
while (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {
- ;
+ set_prop_atom(xev.xproperty.atom);
}
snprintf(diff, 128, "%d/%08d/%lu/%.6f", (int) getpid(), seq++,
@@ -739,6 +750,13 @@ void check_autorepeat(void) {
}
}
+void set_prop_atom(Atom atom) {
+ if (atom == None) return;
+ if (atom == atom_NET_ACTIVE_WINDOW) got_NET_ACTIVE_WINDOW = dnow();
+ if (atom == atom_NET_CURRENT_DESKTOP) got_NET_CURRENT_DESKTOP = dnow();
+ if (atom == atom_NET_CLIENT_LIST_STACKING) got_NET_CLIENT_LIST_STACKING = dnow();
+}
+
/*
* This routine is periodically called to check for selection related
* and other X11 events and respond to them as needed.
@@ -871,7 +889,10 @@ void check_xevents(int reset) {
* Go retrieve X11VNC_REMOTE string.
*/
read_x11vnc_remote_prop(0);
+
+
}
+ set_prop_atom(xev.xproperty.atom);
}
}
diff --git a/x11vnc/xevents.h b/x11vnc/xevents.h
index 3200063..30c4c15 100644
--- a/x11vnc/xevents.h
+++ b/x11vnc/xevents.h
@@ -15,6 +15,7 @@ extern void spawn_grab_buster(void);
extern void sync_tod_with_servertime(void);
extern void check_keycode_state(void);
extern void check_autorepeat(void);
+extern void set_prop_atom(Atom atom);
extern void check_xevents(int reset);
extern void xcut_receive(char *text, int len, rfbClientPtr cl);