Commit c88d830f authored by runge's avatar runge

x11vnc: more -ncache improvements.

parent 833f0602
2007-01-01 Karl Runge <runge@karlrunge.com>
* x11vnc: more -ncache improvements.
2006-12-28 Karl Runge <runge@karlrunge.com> 2006-12-28 Karl Runge <runge@karlrunge.com>
* x11vnc: more work on -ncache, add macosx support, fix X errors * x11vnc: more work on -ncache, add macosx support, fix X errors
and improve cache expiration algorithm. and improve cache expiration algorithm.
......
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: The following information is taken from these URLs:
...@@ -9262,7 +9262,7 @@ x11vnc: a VNC server for real X displays ...@@ -9262,7 +9262,7 @@ x11vnc: a VNC server for real X displays
Here are all of x11vnc command line options: Here are all of x11vnc command line options:
% x11vnc -opts (see below for -help long descriptions) % 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: x11vnc options:
-display disp -auth file -id windowid -display disp -auth file -id windowid
...@@ -9308,34 +9308,34 @@ x11vnc options: ...@@ -9308,34 +9308,34 @@ x11vnc options:
-noalphablend -nocursorshape -cursorpos -noalphablend -nocursorshape -cursorpos
-nocursorpos -xwarppointer -noxwarppointer -nocursorpos -xwarppointer -noxwarppointer
-buttonmap string -nodragging -ncache n -buttonmap string -nodragging -ncache n
-ncache_cr -ncache_pad n -wireframe [str] -ncache_cr -ncache_no_moveraise -ncache_no_dtchange
-nowireframe -nowireframelocal -wirecopyrect mode -ncache_pad n -wireframe [str] -nowireframe
-nowirecopyrect -debug_wireframe -scrollcopyrect mode -nowireframelocal -wirecopyrect mode -nowirecopyrect
-noscrollcopyrect -scr_area n -scr_skip list -debug_wireframe -scrollcopyrect mode -noscrollcopyrect
-scr_inc list -scr_keys list -scr_term list -scr_area n -scr_skip list -scr_inc list
-scr_keyrepeat lo-hi -scr_parms string -fixscreen string -scr_keys list -scr_term list -scr_keyrepeat lo-hi
-debug_scroll -noxrecord -grab_buster -scr_parms string -fixscreen string -debug_scroll
-nograb_buster -debug_grabs -debug_sel -noxrecord -grab_buster -nograb_buster
-pointer_mode n -input_skip n -allinput -debug_grabs -debug_sel -pointer_mode n
-speeds rd,bw,lat -wmdt string -debug_pointer -input_skip n -allinput -speeds rd,bw,lat
-debug_keyboard -defer time -wait time -wmdt string -debug_pointer -debug_keyboard
-wait_ui factor -nowait_bog -slow_fb time -defer time -wait time -wait_ui factor
-readtimeout n -nap -nonap -nowait_bog -slow_fb time -readtimeout n
-sb time -nofbpm -fbpm -nap -nonap -sb time
-nodpms -dpms -noxdamage -nofbpm -fbpm -nodpms
-xd_area A -xd_mem f -sigpipe string -dpms -noxdamage -xd_area A
-threads -nothreads -fs f -xd_mem f -sigpipe string -threads
-gaps n -grow n -fuzz n -nothreads -fs f -gaps n
-debug_tiles -snapfb -rawfb string -grow n -fuzz n -debug_tiles
-freqtab file -pipeinput cmd -macnodim -snapfb -rawfb string -freqtab file
-macnosleep -macnosaver -macnowait -pipeinput cmd -macnodim -macnosleep
-macwheel n -macnoswap -macnoresize -macnosaver -macnowait -macwheel n
-maciconanim n -macmenu -gui [gui-opts] -macnoswap -macnoresize -maciconanim n
-remote command -query variable -QD variable -macmenu -gui [gui-opts] -remote command
-sync -noremote -yesremote -query variable -QD variable -sync
-unsafe -safer -privremote -noremote -yesremote -unsafe
-nocmds -allowedcmds list -deny_all -safer -privremote -nocmds
-allowedcmds list -deny_all
libvncserver options: libvncserver options:
-rfbport port TCP port for RFB protocol -rfbport port TCP port for RFB protocol
...@@ -9369,7 +9369,7 @@ libvncserver-tight-extension options: ...@@ -9369,7 +9369,7 @@ libvncserver-tight-extension options:
% x11vnc -help % 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.) (type "x11vnc -opts" to just list the options.)
...@@ -11388,7 +11388,7 @@ Options: ...@@ -11388,7 +11388,7 @@ Options:
better results than the 'Genie' one. Also, window event better results than the 'Genie' one. Also, window event
detection not as accurate as the X version. 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 moves/drags instead of wireframes (this can induce
painting errors). The wireframe will still be used when painting errors). The wireframe will still be used when
moving a window whose save-unders has not yet been set moving a window whose save-unders has not yet been set
...@@ -11399,7 +11399,18 @@ Options: ...@@ -11399,7 +11399,18 @@ Options:
smoother drags than tightvnc viewer. Response may also smoother drags than tightvnc viewer. Response may also
be choppy if the server side machine is too slow. 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 caching rectangles. This can be used to try to improve
the situation with dropshadows or other compositing the situation with dropshadows or other compositing
(e.g. MacOS X window manager), although it could make (e.g. MacOS X window manager), although it could make
...@@ -12656,6 +12667,8 @@ n ...@@ -12656,6 +12667,8 @@ n
ncache_size:n set -ncache size to n. ncache_size:n set -ncache size to n.
ncache_cr enable -ncache_cr mode. ncache_cr enable -ncache_cr mode.
noncache_cr disable -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" wireframe enable -wireframe mode. same as "wf"
nowireframe disable -wireframe mode. same as "nowf" nowireframe disable -wireframe mode. same as "nowf"
wireframe:str enable -wireframe mode string. wireframe:str enable -wireframe mode string.
...@@ -12817,12 +12830,13 @@ n ...@@ -12817,12 +12830,13 @@ n
bell nobell sel nosel primary noprimary setprimary bell nobell sel nosel primary noprimary setprimary
nosetprimary clipboard noclipboard setclipboard nosetprimary clipboard noclipboard setclipboard
nosetclipboard seldir cursorshape nocursorshape nosetclipboard seldir cursorshape nocursorshape
cursorpos nocursorpos cursor_drag nocursor_drag cursor cursorpos nocursorpos cursor_drag nocursor_drag
show_cursor noshow_cursor nocursor arrow xfixes noxfixes cursor show_cursor noshow_cursor nocursor arrow
xdamage noxdamage xd_area xd_mem alphacut alphafrac xfixes noxfixes xdamage noxdamage xd_area xd_mem
alpharemove noalpharemove alphablend noalphablend alphacut alphafrac alpharemove noalpharemove alphablend
xwarppointer xwarp noxwarppointer noxwarp buttonmap noalphablend xwarppointer xwarp noxwarppointer noxwarp
dragging nodragging ncache_cr noncache_cr ncache buttonmap dragging nodragging ncache_cr noncache_cr
ncache_no_moveraise noncache_no_moveraise ncache
noncache ncache_size wireframe_mode wireframe wf noncache ncache_size wireframe_mode wireframe wf
nowireframe nowf wireframelocal wfl nowireframelocal nowireframe nowf wireframelocal wfl nowireframelocal
nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area
......
...@@ -2053,7 +2053,7 @@ void print_help(int mode) { ...@@ -2053,7 +2053,7 @@ void print_help(int mode) {
" better results than the 'Genie' one. Also, window event\n" " better results than the 'Genie' one. Also, window event\n"
" detection not as accurate as the X version.\n" " detection not as accurate as the X version.\n"
"\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" " moves/drags instead of wireframes (this can induce\n"
" painting errors). The wireframe will still be used when\n" " painting errors). The wireframe will still be used when\n"
" moving a window whose save-unders has not yet been set\n" " moving a window whose save-unders has not yet been set\n"
...@@ -2064,7 +2064,18 @@ void print_help(int mode) { ...@@ -2064,7 +2064,18 @@ void print_help(int mode) {
" smoother drags than tightvnc viewer. Response may also\n" " smoother drags than tightvnc viewer. Response may also\n"
" be choppy if the server side machine is too slow.\n" " be choppy if the server side machine is too slow.\n"
"\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" " caching rectangles. This can be used to try to improve\n"
" the situation with dropshadows or other compositing\n" " the situation with dropshadows or other compositing\n"
" (e.g. MacOS X window manager), although it could make\n" " (e.g. MacOS X window manager), although it could make\n"
...@@ -3329,6 +3340,8 @@ void print_help(int mode) { ...@@ -3329,6 +3340,8 @@ void print_help(int mode) {
" ncache_size:n set -ncache size to n.\n" " ncache_size:n set -ncache size to n.\n"
" ncache_cr enable -ncache_cr mode.\n" " ncache_cr enable -ncache_cr mode.\n"
" noncache_cr disable -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" " wireframe enable -wireframe mode. same as \"wf\"\n"
" nowireframe disable -wireframe mode. same as \"nowf\"\n" " nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n" " wireframe:str enable -wireframe mode string.\n"
...@@ -3488,12 +3501,13 @@ void print_help(int mode) { ...@@ -3488,12 +3501,13 @@ void print_help(int mode) {
" bell nobell sel nosel primary noprimary setprimary\n" " bell nobell sel nosel primary noprimary setprimary\n"
" nosetprimary clipboard noclipboard setclipboard\n" " nosetprimary clipboard noclipboard setclipboard\n"
" nosetclipboard seldir cursorshape nocursorshape\n" " nosetclipboard seldir cursorshape nocursorshape\n"
" cursorpos nocursorpos cursor_drag nocursor_drag cursor\n" " cursorpos nocursorpos cursor_drag nocursor_drag\n"
" show_cursor noshow_cursor nocursor arrow xfixes noxfixes\n" " cursor show_cursor noshow_cursor nocursor arrow\n"
" xdamage noxdamage xd_area xd_mem alphacut alphafrac\n" " xfixes noxfixes xdamage noxdamage xd_area xd_mem\n"
" alpharemove noalpharemove alphablend noalphablend\n" " alphacut alphafrac alpharemove noalpharemove alphablend\n"
" xwarppointer xwarp noxwarppointer noxwarp buttonmap\n" " noalphablend xwarppointer xwarp noxwarppointer noxwarp\n"
" dragging nodragging ncache_cr noncache_cr ncache\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" " noncache ncache_size wireframe_mode wireframe wf\n"
" nowireframe nowf wireframelocal wfl nowireframelocal\n" " nowireframe nowf wireframelocal wfl nowireframelocal\n"
" nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n" " nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
......
...@@ -197,16 +197,26 @@ int wireframe_local = 1; ...@@ -197,16 +197,26 @@ int wireframe_local = 1;
#ifndef NCACHE #ifndef NCACHE
#define NCACHE -10 #define NCACHE -10
#endif #endif
int ncache = NCACHE;
int ncache0 = 0;
int ncache_copyrect = 0;
int macosx_ncache_macmenu = 0;
int ncache_beta_tester = 0;
#ifdef MACOSX #ifdef MACOSX
int ncache = 0;
int ncache_pad = 24; int ncache_pad = 24;
#else #else
int ncache = NCACHE;
int ncache_pad = 0; int ncache_pad = 0;
#endif #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 */ /* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
char *scroll_copyrect_str = NULL; char *scroll_copyrect_str = NULL;
......
...@@ -159,10 +159,19 @@ extern int wireframe_in_progress; ...@@ -159,10 +159,19 @@ extern int wireframe_in_progress;
extern int ncache; extern int ncache;
extern int ncache0; extern int ncache0;
extern int ncache_copyrect; extern int ncache_copyrect;
extern int ncache_wf_raises;
extern int ncache_dt_change;
extern int ncache_pad; extern int ncache_pad;
extern int macosx_ncache_macmenu; extern int macosx_ncache_macmenu;
extern int ncache_beta_tester; 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_str;
extern char *scroll_copyrect; extern char *scroll_copyrect;
extern char *scroll_copyrect_default; extern char *scroll_copyrect_default;
......
...@@ -2748,6 +2748,36 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -2748,6 +2748,36 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ncache_copyrect = 0; ncache_copyrect = 0;
rfbLog("remote_cmd: disabled -ncache_cr %d\n", ncache_copyrect); 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")) { } else if (!strcmp(p, "ncache")) {
if (query) { if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !!ncache); snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);
......
...@@ -2897,7 +2897,7 @@ if (ncache > 0) { ...@@ -2897,7 +2897,7 @@ if (ncache > 0) {
nomsg = 0; nomsg = 0;
} }
} else { } 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; X_UNLOCK;
check_ncache(0, 1); check_ncache(0, 1);
......
...@@ -829,7 +829,7 @@ char find_display[] = ...@@ -829,7 +829,7 @@ char find_display[] =
char create_display[] = char create_display[] =
"#!/bin/sh\n" "#!/bin/sh\n"
"\n" "\n"
"CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\n" "#CREATE_DISPLAY_OUTPUT=/tmp/cdo.txt\n"
"if [ \"X$CREATE_DISPLAY_EXEC\" = \"X\" ]; then\n" "if [ \"X$CREATE_DISPLAY_EXEC\" = \"X\" ]; then\n"
" CREATE_DISPLAY_EXEC=1\n" " CREATE_DISPLAY_EXEC=1\n"
" export CREATE_DISPLAY_EXEC\n" " export CREATE_DISPLAY_EXEC\n"
......
...@@ -360,6 +360,13 @@ Tuning ...@@ -360,6 +360,13 @@ Tuning
xd_area: xd_area:
xd_mem: xd_mem:
=GAL LOFF =GAL LOFF
=GAL Ncache::
ncache
ncache_size:
ncache_cr
ncache_no_moveraise
ncache_no_dtchange
=GAL LOFF
-- --
=GAL SharedMemory:: =GAL SharedMemory::
noshm noshm
...@@ -381,10 +388,6 @@ Tuning ...@@ -381,10 +388,6 @@ Tuning
rfbwait: rfbwait:
nodpms nodpms
nofbpm nofbpm
--
ncache
ncache_size:
ncache_cr
=GAL LOFF =GAL LOFF
" "
} }
...@@ -1054,6 +1057,17 @@ changed regions. Nevertheless, x11vnc uses the DAMAGE information very ...@@ -1054,6 +1057,17 @@ changed regions. Nevertheless, x11vnc uses the DAMAGE information very
effectively as hints to improve its performance. effectively as hints to improve its performance.
The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm. 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:) " set helptext(SharedMemory:) "
......
...@@ -371,6 +371,13 @@ char gui_code[] = ""; ...@@ -371,6 +371,13 @@ char gui_code[] = "";
" xd_area:\n" " xd_area:\n"
" xd_mem:\n" " xd_mem:\n"
" =GAL LOFF\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" " --\n"
" =GAL SharedMemory::\n" " =GAL SharedMemory::\n"
" noshm\n" " noshm\n"
...@@ -392,10 +399,6 @@ char gui_code[] = ""; ...@@ -392,10 +399,6 @@ char gui_code[] = "";
" rfbwait:\n" " rfbwait:\n"
" nodpms\n" " nodpms\n"
" nofbpm\n" " nofbpm\n"
" --\n"
" ncache\n"
" ncache_size:\n"
" ncache_cr\n"
" =GAL LOFF\n" " =GAL LOFF\n"
"\"\n" "\"\n"
"}\n" "}\n"
...@@ -1067,6 +1070,17 @@ char gui_code[] = ""; ...@@ -1067,6 +1070,17 @@ char gui_code[] = "";
"The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.\n" "The items in the sub-menu allow tweaking x11vnc's DAMAGE algorithm.\n"
"\"\n" "\"\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" " set helptext(SharedMemory:) \"\n"
"This sub-menu provides some options regarding SYSV shared memory usage\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" "(shm) by x11vnc. Usually you want shm turned on because the x11vnc\n"
......
...@@ -1235,6 +1235,7 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1235,6 +1235,7 @@ int wait_for_client(int *argc, char** argv, int http) {
char *create_cmd = NULL; char *create_cmd = NULL;
char *users_list_save = NULL; char *users_list_save = NULL;
int created_disp = 0; int created_disp = 0;
int ncache_save;
if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) { if (! use_dpy || strstr(use_dpy, "WAIT:") != use_dpy) {
return 0; return 0;
...@@ -1341,6 +1342,9 @@ int wait_for_client(int *argc, char** argv, int http) { ...@@ -1341,6 +1342,9 @@ int wait_for_client(int *argc, char** argv, int http) {
*argc = (*argc) + 1; *argc = (*argc) + 1;
} }
ncache_save = ncache;
ncache = 0;
initialize_allowed_input(); initialize_allowed_input();
if (! multiple_cursors_mode) { if (! multiple_cursors_mode) {
...@@ -1745,6 +1749,8 @@ if (db) fprintf(stderr, "xauth_raw_len: %d\n", n); ...@@ -1745,6 +1749,8 @@ if (db) fprintf(stderr, "xauth_raw_len: %d\n", n);
free(create_cmd); free(create_cmd);
} }
ncache = ncache_save;
return 1; return 1;
} }
...@@ -80,8 +80,8 @@ static void set_bdpush(int type, double *last_bdpush, int *pushit); ...@@ -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 repeat_check(double last_key_scroll);
static int check_xrecord_keys(void); static int check_xrecord_keys(void);
static int check_xrecord_mouse(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, static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch); int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch);
static int wireframe_mod_state(); static int wireframe_mod_state();
static void check_user_input2(double dt); static void check_user_input2(double dt);
static void check_user_input3(double dt, double dtr, int tile_diffs); static void check_user_input3(double dt, double dtr, int tile_diffs);
...@@ -1369,7 +1369,7 @@ if (n) { \ ...@@ -1369,7 +1369,7 @@ if (n) { \
int batch_dxs[], batch_dys[]; int batch_dxs[], batch_dys[];
sraRegionPtr batch_reg[]; 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, static int push_scr_ev(double *age, int type, int bdpush, int bdx, int bdy,
int bdskinny, int first_push) { int bdskinny, int first_push) {
...@@ -1568,7 +1568,7 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d" ...@@ -1568,7 +1568,7 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
if (fast_push) { if (fast_push) {
int k, nbatch = 0; int k, nbatch = 0;
double delay, d1 = 0.1, d2 = 0.02; 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); tmpregion, waittime, &nbatch);
if (first_push) { if (first_push) {
...@@ -1577,13 +1577,10 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d" ...@@ -1577,13 +1577,10 @@ if (db > 1) fprintf(stderr, "------------ got: %d x: %4d y: %3d"
delay = d2; delay = d2;
} }
batch_copyregion(batch_reg, batch_dxs, batch_dys, nbatch, delay); batch_push(nbatch, delay);
for (k=0; k < nbatch; k++) {
sraRgnDestroy(batch_reg[k]);
}
fb_push(); fb_push();
} else { } 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); tmpregion, waittime, NULL);
if (rc) { if (rc) {
last_scroll_type = type; 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) ...@@ -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) { void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double delay) {
rfbClientIteratorPtr i; rfbClientIteratorPtr i;
rfbClientPtr cl; rfbClientPtr cl;
int k, direct, mode, nrects = 0; int k, direct, mode, nrects = 0, bad = 0;
/* XXX Y */ /* 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) { if (delay < 0.0) {
delay = 0.1; delay = 0.1;
} }
fb_push_wait(delay, FB_COPY|FB_MOD); fb_push_wait(delay, FB_COPY|FB_MOD);
for (k=0; k < ncr; k++) {
nrects += sraRgnCountRects(region[k]);
}
i = rfbGetClientIterator(screen); i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) { while( (cl = rfbClientIteratorNext(i)) ) {
rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf; rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
...@@ -2022,6 +2043,14 @@ fprintf(stderr, "batch_copyregion: nrects: %d nregions: %d\n", nrects, ncr); ...@@ -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) { void fb_push0(void) {
char *httpdir = screen->httpDir; char *httpdir = screen->httpDir;
int defer = screen->deferUpdateTime; int defer = screen->deferUpdateTime;
...@@ -3041,8 +3070,8 @@ if (0) fprintf(stderr, "check_xrecord: button_mask: %d mouse_wants_back_in: %d\ ...@@ -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]; int batch_dxs[NBATCHMAX], batch_dys[NBATCHMAX];
sraRegionPtr batch_reg[NBATCHMAX]; sraRegionPtr batch_reg[NBATCHMAX];
static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy, static int try_copyrect(Window orig_frame, Window frame, int x, int y, int w, int h,
int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch) { int dx, int dy, int *obscured, sraRegionPtr extra_clip, double max_wait, int *nbatch) {
static int dt_bad = 0; static int dt_bad = 0;
static time_t dt_bad_check = 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 ...@@ -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) { if (time(NULL) > dt_bad_check + 5) {
char *dt = guess_desktop(); char *dt = guess_desktop();
if (!strcmp(dt, "kde")) { if (!strcmp(dt, "kde_maybe_is_ok_now...")) {
dt_bad = 1; dt_bad = 1;
} else if (!strcmp(dt, "xfce")) { } else if (!strcmp(dt, "xfce")) {
dt_bad = 1; 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 ...@@ -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; x -= off_x;
y -= off_y; 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) { if (dt_bad && wireframe_in_progress) {
sraRegionPtr rect; sraRegionPtr rect;
...@@ -3171,16 +3203,13 @@ if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n", ...@@ -3171,16 +3203,13 @@ if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n",
swin = stack_list[k].win; swin = stack_list[k].win;
if (db2) fprintf(stderr, "sw: %d/%lx\n", k, swin); if (db2) fprintf(stderr, "sw: %d/%lx\n", k, swin);
if (swin == frame) { if (swin == frame || swin == orig_frame) {
if (db2) { if (db2) {
saw_me = 1; fprintf(stderr, " ----------\n"); saw_me = 1; fprintf(stderr, " ----------\n");
} else { } else {
break; break;
} }
} }
#if 0
fprintf(stderr, "bo: %d/%lx\n", k, swin);
#endif
/* skip some unwanted cases: */ /* skip some unwanted cases: */
#ifndef MACOSX #ifndef MACOSX
...@@ -3224,6 +3253,7 @@ fprintf(stderr, "bo: %d/%lx\n", k, swin); ...@@ -3224,6 +3253,7 @@ fprintf(stderr, "bo: %d/%lx\n", k, swin);
if (attr.map_state != IsViewable) { if (attr.map_state != IsViewable) {
continue; 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) { if (clipshift) {
attr.x -= coff_x; attr.x -= coff_x;
...@@ -3544,29 +3574,32 @@ static sraRegionPtr NPP_roffscreen = NULL; ...@@ -3544,29 +3574,32 @@ static sraRegionPtr NPP_roffscreen = NULL;
static sraRegionPtr NPP_r_bs_tmp = NULL; static sraRegionPtr NPP_r_bs_tmp = NULL;
static Window NPP_nwin = None; static Window NPP_nwin = None;
void clear_win_events(void) { void clear_win_events(Window win, int vis) {
#if !NO_X11 #if !NO_X11
if (dpy && NPP_nwin != None) { if (dpy && win != None && ncache) {
XEvent ev; XEvent ev;
XErrorHandler old_handler; XErrorHandler old_handler;
old_handler = XSetErrorHandler(trap_xerror); old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0; trapped_xerror = 0;
while (XCheckTypedWindowEvent(dpy, NPP_nwin, ConfigureNotify, &ev)) { while (XCheckTypedWindowEvent(dpy, win, ConfigureNotify, &ev)) {
fprintf(stderr, "."); fprintf(stderr, ".");
if (trapped_xerror) { if (trapped_xerror) {
break; break;
} }
trapped_xerror = 0; trapped_xerror = 0;
} }
while (XCheckTypedWindowEvent(dpy, NPP_nwin, VisibilityNotify, &ev)) { /* XXX Y */
fprintf(stderr, "+"); if (vis) {
if (trapped_xerror) { while (XCheckTypedWindowEvent(dpy, win, VisibilityNotify, &ev)) {
break; fprintf(stderr, "+");
if (trapped_xerror) {
break;
}
trapped_xerror = 0;
} }
trapped_xerror = 0;
} }
XSetErrorHandler(old_handler); XSetErrorHandler(old_handler);
fprintf(stderr, " 0x%x\n", (unsigned int) NPP_nwin); fprintf(stderr, " 0x%x\n", (unsigned int) win);
} }
#endif #endif
} }
...@@ -3962,11 +3995,7 @@ void ncache_post_portions(int nidx, int use_batch, int orig_x, int orig_y, int o ...@@ -3962,11 +3995,7 @@ void ncache_post_portions(int nidx, int use_batch, int orig_x, int orig_y, int o
sraRgnDestroy(r1); sraRgnDestroy(r1);
if (use_batch) { if (use_batch) {
int k; batch_push(NPP_nreg, batch_delay);
batch_copyregion(batch_reg, batch_dxs, batch_dys, NPP_nreg, batch_delay);
for (k=0; k < NPP_nreg; k++) {
sraRgnDestroy(batch_reg[k]);
}
fprintf(stderr, "FB_COPY: %.4f XX did batch 0x%x %3d su: %dx%d+%d+%d bs: %dx%d+%d+%d\n", dnow() - ntim, 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); (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+ ...@@ -3978,11 +4007,7 @@ fprintf(stderr, "FB_COPY: %.4f XX did batch 0x%x %3d su: %dx%d+%d+%d bs: %dx%d+
} }
} else { } else {
if (use_batch) { if (use_batch) {
int k; batch_push(NPP_nreg, batch_delay);
batch_copyregion(batch_reg, batch_dxs, batch_dys, NPP_nreg, batch_delay);
for (k=0; k < NPP_nreg; k++) {
sraRgnDestroy(batch_reg[k]);
}
} }
} }
...@@ -4126,6 +4151,58 @@ void check_macosx_click_frame(void) { ...@@ -4126,6 +4151,58 @@ void check_macosx_click_frame(void) {
#endif #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 * Applied just before any check_user_input() modes. Look for a
* ButtonPress; find window it happened in; find the wm frame window * 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); ...@@ -4244,7 +4321,11 @@ if (db) fprintf(stderr, "NO get_wm_frame_pos-1: 0x%lx\n", frame);
return 0; return 0;
} }
X_UNLOCK; 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 * apply the percentage size criterion (allow opaque moves for
...@@ -4378,7 +4459,7 @@ if (db) fprintf(stderr, "INTERIOR\n"); ...@@ -4378,7 +4459,7 @@ if (db) fprintf(stderr, "INTERIOR\n");
XFlush_wr(dpy); XFlush_wr(dpy);
X_UNLOCK; X_UNLOCK;
/* try do induce/waitfor some more user input */ /* try to induce/waitfor some more user input */
if (use_threads) { if (use_threads) {
usleep(1000); usleep(1000);
} else if (drew_box && do_copyrect_drag != 1) { } else if (drew_box && do_copyrect_drag != 1) {
...@@ -4609,17 +4690,20 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n"); ...@@ -4609,17 +4690,20 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} else if (w != box_w || h != box_h) { } else if (w != box_w || h != box_h) {
do_copyrect_drag = 0; do_copyrect_drag = 0;
} else if (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) { if (idx < 0) {
idx = lookup_win_index(frame); fr = frame;
idx = lookup_win_index(fr);
} }
if (idx >= 0) { if (idx >= 0) {
if (cache_list[idx].su_time > 0.0) { do_copyrect_drag = set_copyrect_drag(idx, fr, try_batch);
/* XXX Y */ if (do_copyrect_drag) {
min_draw *= 0.66; min_draw *= 0.66;
do_copyrect_drag = 1;
} }
nidx = idx; nidx = idx;
} else {
do_copyrect_drag = 0;
} }
now_x = orig_x; now_x = orig_x;
now_y = orig_y; now_y = orig_y;
...@@ -4631,8 +4715,18 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n"); ...@@ -4631,8 +4715,18 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} }
} }
drew_box = 1;
if (do_copyrect_drag <= 0) { 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); draw_box(x, y, w, h, 0);
fb_push(); /* XXX Y */ fb_push(); /* XXX Y */
rfbPE(1000); rfbPE(1000);
...@@ -4648,6 +4742,8 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n"); ...@@ -4648,6 +4742,8 @@ fprintf(stderr, "*** NO GPI DRAW_BOX\n");
} }
#endif #endif
} }
drew_box = 1;
last_wireframe = dnow();
last_draw = spin; last_draw = spin;
last_draw_cnt = cnt; last_draw_cnt = cnt;
...@@ -4712,11 +4808,17 @@ if (db || db2) fprintf(stderr, "NO button_mask\n"); ...@@ -4712,11 +4808,17 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
} else if (skip_cr_when_scaling("wireframe")) { } else if (skip_cr_when_scaling("wireframe")) {
; ;
} else if (w != orig_w || h != orig_h) { } 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 (dx == 0 && dy == 0) {
; ;
} else if (do_copyrect_drag > 0) { } else if (do_copyrect_drag > 0) {
clear_win_events(); clear_win_events(NPP_nwin, 0);
} else { } else {
int spin_ms = (int) (spin * 1000 * 1000); int spin_ms = (int) (spin * 1000 * 1000);
int obscured, sent_copyrect = 0; int obscured, sent_copyrect = 0;
...@@ -4758,16 +4860,16 @@ fprintf(stderr, "FB_COPY failed again! %.4f", dnow() - ntim); ...@@ -4758,16 +4860,16 @@ fprintf(stderr, "FB_COPY failed again! %.4f", dnow() - ntim);
/* 2) try to send a clipped copyrect of translation: */ /* 2) try to send a clipped copyrect of translation: */
if (! try_batch) { 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); &obscured, NULL, 0.15, NULL);
} else { } 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 */ &obscured, NULL, 0.15, &NPP_nreg); /* XXX */
sent_copyrect = 1; sent_copyrect = 1;
use_batch = 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) { if (sent_copyrect) {
/* try to push the changes to viewers: */ /* try to push the changes to viewers: */
if (use_batch) { if (use_batch) {
...@@ -4781,7 +4883,7 @@ if (db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copy ...@@ -4781,7 +4883,7 @@ if (db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copy
#ifndef NO_NCACHE #ifndef NO_NCACHE
ncache_post_portions(nidx, use_batch, ncache_post_portions(nidx, use_batch,
orig_x, orig_y, orig_w, orig_h, x, y, w, h, -1.0, ntim); 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 #endif
if (scaling && !use_batch) { if (scaling && !use_batch) {
...@@ -5415,10 +5517,8 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n", ...@@ -5415,10 +5517,8 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
if (wireframe) { if (wireframe) {
if (check_wireframe()) { if (check_wireframe()) {
fprintf(stderr, "check_wireframe: 1\n");
return 0; return 0;
} }
//fprintf(stderr, "check_wireframe: 0\n");
} }
if (pointer_mode == 1) { if (pointer_mode == 1) {
...@@ -5583,6 +5683,56 @@ void snapshot_cache_list(int free_only, double allowed_age) { ...@@ -5583,6 +5683,56 @@ void snapshot_cache_list(int free_only, double allowed_age) {
#endif /* NO_X11 */ #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 get_bs_n(int y) {
int n; int n;
for (n = 1; n < ncache; n += 2) { for (n = 1; n < ncache; n += 2) {
...@@ -5698,6 +5848,63 @@ fprintf(stderr, "lookup_freeB: %d\n", rfree); ...@@ -5698,6 +5848,63 @@ fprintf(stderr, "lookup_freeB: %d\n", rfree);
return 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) \ #define STORE(k, w, attr) \
cache_list[k].win = w; \ cache_list[k].win = w; \
cache_list[k].fetched = 1; \ cache_list[k].fetched = 1; \
...@@ -6292,7 +6499,6 @@ int find_rect(int idx, int x, int y, int w, int h) { ...@@ -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); rect_reg[n] = sraRgnCreateRect(0, n * dpy_y, dpy_x, (n+1) * dpy_y);
} }
} else if (now > last_clean + 60) { } else if (now > last_clean + 60) {
//fprintf(stderr, "free_rect: cleaning up regions:\n");
last_clean = now; last_clean = now;
for (n = 1; n < ncache; n += 2) { for (n = 1; n < ncache; n += 2) {
int i, n2 = n+1; 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 ...@@ -6384,7 +6590,7 @@ fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d\n", w, h, x, y, x_hi
fr_BIG1t++; fr_BIG1t++;
return 0; 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); fprintf(stderr, ">>**--**>> BIG1 rect: %dx%d+%d+%d -- %d %d (FULL DISPLAY)\n", w, h, x, y, x_hit, y_hit);
fr_BIG1++; fr_BIG1++;
fr_BIG1t++; fr_BIG1t++;
...@@ -6573,21 +6779,124 @@ int valid_wr(int idx, Window win, XWindowAttributes *attr) { ...@@ -6573,21 +6779,124 @@ int valid_wr(int idx, Window win, XWindowAttributes *attr) {
return valid_window(win, attr, 1); 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; Window win = cache_list[idx].win;
XWindowAttributes attr; XWindowAttributes attr;
int x1, y1, w1, h1; int x1, y1, w1, h1;
int x2, y2, w2, h2; int x2, y2, w2, h2;
int x, y, w, h; int x, y, w, h;
int dx, dy, rc = 1; int dx, dy, rc = 1;
sraRegionPtr r, r0; sraRegionPtr r, r0, r1;
x1 = cache_list[idx].x; x1 = cache_list[idx].x;
y1 = cache_list[idx].y; y1 = cache_list[idx].y;
w1 = cache_list[idx].width; w1 = cache_list[idx].width;
h1 = cache_list[idx].height; 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; X_LOCK;
if (! valid_wr(idx, win, &attr)) { if (! valid_wr(idx, win, &attr)) {
...@@ -6635,12 +6944,17 @@ fprintf(stderr, "BS_save: FAIL FOR: %d\n", idx); ...@@ -6635,12 +6944,17 @@ fprintf(stderr, "BS_save: FAIL FOR: %d\n", idx);
y2 -= coff_y; y2 -= coff_y;
} }
dx = x - x2;
dy = y - y2;
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2); r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(r, r0); sraRgnAnd(r, r0);
if (clip) {
clip_region(r, win);
}
dx = x - x2;
dy = y - y2;
sraRgnOffset(r, dx, dy); sraRgnOffset(r, dx, dy);
dtA = dnowx(); dtA = dnowx();
...@@ -6660,7 +6974,7 @@ if (verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d ...@@ -6660,7 +6974,7 @@ if (verb) fprintf(stderr, "BS_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
return 1; 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; Window win = cache_list[idx].win;
XWindowAttributes attr; XWindowAttributes attr;
int x1, y1, w1, h1; int x1, y1, w1, h1;
...@@ -6721,12 +7035,17 @@ fprintf(stderr, "SU_save: FAIL FOR: %d\n", idx); ...@@ -6721,12 +7035,17 @@ fprintf(stderr, "SU_save: FAIL FOR: %d\n", idx);
y2 -= coff_y; y2 -= coff_y;
} }
dx = x - x2;
dy = y - y2;
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2); r = sraRgnCreateRect(x2, y2, x2+w2, y2+h2);
sraRgnAnd(r, r0); sraRgnAnd(r, r0);
if (clip) {
clip_region(r, win);
}
dx = x - x2;
dy = y - y2;
sraRgnOffset(r, dx, dy); sraRgnOffset(r, dx, dy);
dtA = dnowx(); dtA = dnowx();
...@@ -6746,7 +7065,7 @@ if (verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d ...@@ -6746,7 +7065,7 @@ if (verb) fprintf(stderr, "SU_save: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
return 1; 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; Window win = cache_list[idx].win;
XWindowAttributes attr; XWindowAttributes attr;
int x1, y1, w1, h1; int x1, y1, w1, h1;
...@@ -6763,7 +7082,12 @@ if (verb) fprintf(stderr, "backingstore restore: 0x%x %3d \n", (unsigned int ...@@ -6763,7 +7082,12 @@ if (verb) fprintf(stderr, "backingstore restore: 0x%x %3d \n", (unsigned int
h1 = cache_list[idx].height; h1 = cache_list[idx].height;
X_LOCK; 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); fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
DELETE(idx); DELETE(idx);
X_UNLOCK; X_UNLOCK;
...@@ -6782,7 +7106,9 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win); ...@@ -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; h = cache_list[idx].bs_h;
if (x < 0 || cache_list[idx].bs_time == 0.0) { if (x < 0 || cache_list[idx].bs_time == 0.0) {
STORE(idx, win, attr); if (!novalidate) {
STORE(idx, win, attr);
}
return 0; return 0;
} }
...@@ -6805,9 +7131,6 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win); ...@@ -6805,9 +7131,6 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win);
y2 -= coff_y; y2 -= coff_y;
} }
dx = x2 - x;
dy = y2 - y;
if (w2 > w) { if (w2 > w) {
w2 = w; w2 = w;
} }
...@@ -6817,9 +7140,17 @@ fprintf(stderr, "BS_restore: not a valid X window: 0x%x\n", (unsigned int) win); ...@@ -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); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x, y, x+w2, y+h2); r = sraRgnCreateRect(x, y, x+w2, y+h2);
dx = x2 - x;
dy = y2 - y;
sraRgnOffset(r, dx, dy); sraRgnOffset(r, dx, dy);
sraRgnAnd(r, r0); sraRgnAnd(r, r0);
if (clip) {
clip_region(r, win);
}
dtA = dnowx(); dtA = dnowx();
if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); if (verb) fprintf(stderr, "BS_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
if (w2 > 0 && h2 > 0) { 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 ...@@ -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(r0);
sraRgnDestroy(r); sraRgnDestroy(r);
STORE(idx, win, attr); if (!novalidate) {
STORE(idx, win, attr);
}
return 1; 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; Window win = cache_list[idx].win;
XWindowAttributes attr; XWindowAttributes attr;
int x1, y1, w1, h1; 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 ...@@ -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; y2 -= coff_y;
} }
dx = x2 - x;
dy = y2 - y;
if (w2 > w) { if (w2 > w) {
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 ...@@ -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); r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r = sraRgnCreateRect(x, y, x+w2, y+h2); r = sraRgnCreateRect(x, y, x+w2, y+h2);
dx = x2 - x;
dy = y2 - y;
sraRgnOffset(r, dx, dy); sraRgnOffset(r, dx, dy);
sraRgnAnd(r, r0); sraRgnAnd(r, r0);
if (clip) {
clip_region(r, win);
}
dtA = dnowx(); dtA = dnowx();
if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy); if (verb) fprintf(stderr, "SU_rest: %.4f %d dx=%d dy=%d\n", dtA, idx, dx, dy);
if (w2 > 0 && h2 > 0) { 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 ...@@ -6929,11 +7267,10 @@ if (verb) fprintf(stderr, "SU_rest: %.4f %.2f %d done. %dx%d+%d+%d %dx%d+%d+%d
if (invalid) { if (invalid) {
DELETE(idx); DELETE(idx);
return 0;
} else { } else {
STORE(idx, win, attr); STORE(idx, win, attr);
return 1;
} }
return 1;
} }
void check_zero_rects(void) { void check_zero_rects(void) {
...@@ -7051,7 +7388,7 @@ void block_stats(void) { ...@@ -7051,7 +7388,7 @@ void block_stats(void) {
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
#define NSCHED 64 #define NSCHED 128
Window sched_bs[NSCHED]; Window sched_bs[NSCHED];
double sched_tm[NSCHED]; double sched_tm[NSCHED];
double last_sched_bs = 0.0; double last_sched_bs = 0.0;
...@@ -7142,40 +7479,419 @@ Bool xcheckmaskevent(Display *d, long mask, XEvent *ev) { ...@@ -7142,40 +7479,419 @@ Bool xcheckmaskevent(Display *d, long mask, XEvent *ev) {
#define EVMAX 2048 #define EVMAX 2048
XEvent Ev[EVMAX]; XEvent Ev[EVMAX];
int Ev_done[EVMAX]; int Ev_done[EVMAX];
int Ev_order[EVMAX];
int Ev_area[EVMAX]; int Ev_area[EVMAX];
int Ev_tmp[EVMAX];
int Ev_tmp2[EVMAX];
Window Ev_win[EVMAX]; Window Ev_win[EVMAX];
Window Ev_map[EVMAX]; Window Ev_map[EVMAX];
Window Ev_unmap[EVMAX]; Window Ev_unmap[EVMAX];
sraRect Ev_rects[EVMAX]; sraRect Ev_rects[EVMAX];
int check_ncache(int reset, int mode) { int tmp_stack[STACKMAX];
static double last_root = 0.0; sraRegionPtr tmp_reg[STACKMAX];
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;
double now, refresh = 60.0; #define CLEAN_OUT \
Window win, win2; for (i=0; i < n; i++) { \
XWindowAttributes attr; sraRgnDestroy(tmp_reg[i]); \
unsigned long all_ev = SubstructureNotifyMask|StructureNotifyMask|VisibilityChangeMask; } \
unsigned long win_ev = StructureNotifyMask|VisibilityChangeMask; sraRgnDestroy(r1); \
sraRgnDestroy(r0);
int try_batch = 1; /* XXX Y */ int try_to_fix_resize_su(Window orig_frame, int orig_x, int orig_y, int orig_w, int orig_h,
int use_batch = 0; int x, int y, int w, int h, int try_batch) {
int nreg = 0, *nbatch;
static int didtopmost = 0;
int create_cnt, create_tot;
int pixels = 0;
int nrects = 0; 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;
#ifdef MACOSX if (idx < 0) {
if (! macosx_console) { return 0;
RAWFB_RET(-1)
} }
#else 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, n_ST = 0, n_PN = 0;
int did_sched = 0;
double now, refresh = 60.0;
Window win, win2;
XWindowAttributes attr;
unsigned long all_ev = SubstructureNotifyMask|StructureNotifyMask|VisibilityChangeMask;
unsigned long win_ev = StructureNotifyMask|VisibilityChangeMask;
int try_batch = 1; /* XXX Y */
int use_batch = 0;
int nreg = 0, *nbatch;
int create_cnt, create_tot;
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)
}
#else
RAWFB_RET(-1) RAWFB_RET(-1)
#endif #endif
...@@ -7188,7 +7904,7 @@ int check_ncache(int reset, int mode) { ...@@ -7188,7 +7904,7 @@ int check_ncache(int reset, int mode) {
if (ncache0) { if (ncache0) {
if (reset) { if (reset) {
; ;
} else if (! client_count || !ncache || nofb) { } else if (!client_count || !ncache || nofb) {
static double last_purge = 0.0; static double last_purge = 0.0;
double delay = client_count ? 0.5 : 2.0; double delay = client_count ? 0.5 : 2.0;
if (now > last_purge + delay) { if (now > last_purge + delay) {
...@@ -7241,6 +7957,8 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c); ...@@ -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); 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); mark_rect_as_modified(0, dpy_y, dpy_x, (ncache+1)*dpy_y, 0);
snap_old();
return -1; return -1;
} }
...@@ -7290,16 +8008,16 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c); ...@@ -7290,16 +8008,16 @@ if (c) fprintf(stderr, "check_ncache purged %d events\n", c);
} }
snapshot_cache_list(0, 100.0); snapshot_cache_list(0, 100.0);
fprintf(stderr, "cache_list_num: %d\n", cache_list_num);
for (i=0; i < cache_list_num; i++) { for (i=0; i < cache_list_num; i++) {
CLEAR(i); CLEAR(i);
} }
for (n = 1; n <= ncache; n++) { for (n = 1; n <= ncache; n++) {
rect_reg[n] = NULL; rect_reg[n] = NULL;
} }
snap_old();
} }
if (now < last_client + 2) { if (now < last_client + 4) {
return -1; return -1;
} }
...@@ -7322,7 +8040,6 @@ if (hack_val == 2) { ...@@ -7322,7 +8040,6 @@ if (hack_val == 2) {
#endif #endif
if (now > last_root + refresh) { if (now > last_root + refresh) {
Window topmapped = None;
fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num); fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
block_stats(); block_stats();
...@@ -7337,7 +8054,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num); ...@@ -7337,7 +8054,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
; ;
} else if (valid_window(win, &attr, 1)) { } else if (valid_window(win, &attr, 1)) {
STORE(k, win, attr); 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) { if (! cache_list[k].selectinput) {
xselectinput(win, win_ev, 0); xselectinput(win, win_ev, 0);
CLEAR(k); CLEAR(k);
...@@ -7345,9 +8061,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num); ...@@ -7345,9 +8061,6 @@ fprintf(stderr, "\n**** checking cache_list[%d]\n\n", cache_list_num);
} else { } else {
; ;
} }
if (attr.map_state == IsViewable) {
topmapped = win;
}
valid = 1; valid = 1;
} else { } 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); 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 ...@@ -7365,32 +8078,44 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned
} }
} }
last_root = dnow(); 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(); check_zero_rects();
if (now > last_sched_bs + 0.2) { if (now > last_sched_bs + 0.30) {
static double last_sched_vis = 0.0; static double last_sched_vis = 0.0;
int nr = 0, *bat = NULL; int nr = 0, *bat = NULL;
if (try_batch) { if (try_batch) {
bat = &nr; 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++) { for (i=0; i < NSCHED; i++) {
if (sched_bs[i] != None) { if (sched_bs[i] != None) {
int idx; int idx;
win = sched_bs[i]; win = sched_bs[i];
if (now < sched_tm[i] + 0.65) { if (now < sched_tm[i] + 0.55) {
continue; continue;
} }
idx = lookup_win_index(win); idx = lookup_win_index(win);
...@@ -7404,39 +8129,68 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned ...@@ -7404,39 +8129,68 @@ fprintf(stderr, "Created window never mapped: freeing(%d) 0x%x\n", k, (unsigned
} else if (aw * ah < 64 * 64) { } else if (aw * ah < 64 * 64) {
; ;
} else { } else {
fprintf(stderr, "*SNAP BS_save: 0x%x %d %d %d\n", (unsigned int) win, aw, ah, cache_list[idx].map_state); //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); bs_save(idx, bat, 1, 0, 0);
} }
} }
} }
sched_bs[i] = None; sched_bs[i] = None;
} }
if (nr) { did_sched = 1;
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();
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++) { 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].vis_state == VisibilityUnobscured) {
if (cache_list[i].valid) { ok = 1;
if (cache_list[i].win != None) { } else if (!clipped(i)) {
SCHED(cache_list[i].win, 0) ok = 1;
}
}
} }
} else {
ok = 1;
}
if (ok) {
bs_save(i, bat, !top_only, 0, 0);
} }
} }
last_sched_vis = dnow(); last_sched_vis = dnow();
saw_desktop_change = 0;
}
if (nr) {
batch_push(nr, -1.0);
} }
last_sched_bs = dnow();
} }
n = 0; n = 0;
ttot = 0;
create_tot = 0; create_tot = 0;
X_LOCK; X_LOCK;
...@@ -7445,18 +8199,25 @@ fprintf(stderr, "*SNAP BS_save: 0x%x %d %d %d\n", (unsigned int) win, aw, ah, ca ...@@ -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; win = Ev[n].xany.window;
Ev_done[n] = 0; Ev_done[n] = 0;
Ev_area[n] = 0; Ev_area[n] = 0;
Ev_win[n] = None; Ev_win[n] = win;
Ev_map[n] = None; Ev_map[n] = None;
Ev_unmap[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 (win == rootwin) {
if (type == CreateNotify) { if (type == CreateNotify) {
n++;
create_tot++; create_tot++;
n++;
n_CN++; n_CN++;
} else if (type == ReparentNotify) { } else if (type == ReparentNotify) {
n++; n++;
n_RN++; n_RN++;
} else if (type == PropertyNotify) {
set_prop_atom(Ev[n].xproperty.atom);
n++;
n_PN++;
} else { } else {
/* skip rest */ /* skip rest */
#if 0 #if 0
...@@ -7489,9 +8250,11 @@ if (type != ConfigureNotify) fprintf(stderr, "root: skip %s for 0x%x\n", Etype( ...@@ -7489,9 +8250,11 @@ if (type != ConfigureNotify) fprintf(stderr, "root: skip %s for 0x%x\n", Etype(
n++; n++;
n_VN++; n_VN++;
} else if (type == MapNotify) { } else if (type == MapNotify) {
Ev_map[n] = win;
n++; n++;
n_MN++; n_MN++;
} else if (type == UnmapNotify) { } else if (type == UnmapNotify) {
Ev_unmap[n] = win;
n++; n++;
n_UN++; n_UN++;
} else { } else {
...@@ -7505,16 +8268,21 @@ fprintf(stderr, "----- skip %s\n", Etype(type)); ...@@ -7505,16 +8268,21 @@ fprintf(stderr, "----- skip %s\n", Etype(type));
} }
X_UNLOCK; 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) { if (n == 0) {
return 0; return 0;
} }
fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n); 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) { if (try_batch) {
use_batch = 1; use_batch = 1;
} }
...@@ -7533,19 +8301,163 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n); ...@@ -7533,19 +8301,163 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
nbatch = &nreg; 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; 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; X_LOCK;
for (i=0; i < n; i++) { for (i=0; i < n; i++) {
XEvent ev; XEvent ev;
int type, idx = -1; int ns, skip = 0, type, idx = -1;
int ik = Ev_order[i];
if (Ev_done[i]) continue; if (Ev_done[ik]) continue;
win = Ev_win[i]; win = Ev_win[ik];
ev = Ev[i]; ev = Ev[ik];
type = ev.type; 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 (win == rootwin) {
if (type == CreateNotify) { if (type == CreateNotify) {
...@@ -7567,14 +8479,15 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n); ...@@ -7567,14 +8479,15 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
y=attr.y; y=attr.y;
w=attr.width; w=attr.width;
h=attr.height; h=attr.height;
/* XXX Y */
if (create_tot <= 6 && create_cnt++ < 3) { if (create_tot <= 6 && create_cnt++ < 3) {
if (w*h > 64 * 64) { if (w*h > 64 * 64) {
X_UNLOCK; X_UNLOCK;
su_save(idx, nbatch, 1); su_save(idx, nbatch, 0, 1);
X_LOCK; X_LOCK;
if (cache_list[idx].valid) { if (cache_list[idx].valid) {
SCHED(win2, 1) if (! desktop_change) {
SCHED(win2, 1)
}
} }
create_cnt++; create_cnt++;
} }
...@@ -7588,25 +8501,28 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n); ...@@ -7588,25 +8501,28 @@ fprintf(stderr, "\n"); rfbLog("IN check_ncache() %d events.\n", n);
DELETE(idx); 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) { } else if (type == ReparentNotify) {
if (ev.xreparent.parent != rootwin) { if (ev.xreparent.parent != rootwin) {
win2 = ev.xreparent.window; win2 = ev.xreparent.window;
if (win2 != rootwin) { if (win2 != rootwin) {
idx = lookup_win_index(win2); 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) { if (idx >= 0) {
DELETE(idx); DELETE(idx);
} }
xselectinput(win2, 0, 1); xselectinput(win2, 0, 1);
} }
} }
} else {
fprintf(stderr, "root%02d: ** IgnoringRoot 0x%x type: %s\n", ik, (unsigned int) win, Etype(type));
} }
} else { } else {
if (type == ConfigureNotify) { if (type == ConfigureNotify) {
int x_new, y_new, w_new, h_new; int x_new, y_new, w_new, h_new;
int x_old, y_old, w_old, h_old; int x_old, y_old, w_old, h_old;
int stack_change;
Window oabove = None; Window oabove = None;
idx = lookup_win_index(win); idx = lookup_win_index(win);
...@@ -7615,7 +8531,7 @@ fprintf(stderr, "root%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2 ...@@ -7615,7 +8531,7 @@ fprintf(stderr, "root%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2
oabove = cache_list[idx].above; 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); (unsigned int) oabove, (unsigned int) ev.xconfigure.above, ev.xconfigure.width, ev.xconfigure.height, ev.xconfigure.x, ev.xconfigure.y);
if (idx < 0) { if (idx < 0) {
...@@ -7634,12 +8550,31 @@ fprintf(stderr, "----%02d: ConfigureNotify 0x%x %3d -- above: 0x%x -> 0x%x % ...@@ -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) { if (x_old != x_new || y_old != y_new) {
/* invalidate su */ /* invalidate su */
cache_list[idx].su_time = 0.0; 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) { if (w_old != w_new || h_old != h_new) {
/* invalidate bs */ /* invalidate bs */
cache_list[idx].bs_time = 0.0; 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; cache_list[idx].x = x_new;
...@@ -7652,12 +8587,14 @@ fprintf(stderr, " invalidate bs: 0x%x wh: %d/%d %d/%d \n", (unsigned i ...@@ -7652,12 +8587,14 @@ fprintf(stderr, " invalidate bs: 0x%x wh: %d/%d %d/%d \n", (unsigned i
} else if (type == VisibilityNotify) { } else if (type == VisibilityNotify) {
int state = ev.xvisibility.state; int state = ev.xvisibility.state;
idx = lookup_win_index(win); 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) { if (idx < 0) {
continue; 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 ... */ ; /* XXXX not working well yet with UnmapNotify ... */
} else if (state == VisibilityUnobscured) { } else if (state == VisibilityUnobscured) {
int i2, ok = 1; int i2, ok = 1;
...@@ -7672,11 +8609,11 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i ...@@ -7672,11 +8609,11 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
} }
if (ok) { if (ok) {
X_UNLOCK; X_UNLOCK;
bs_restore(idx, nbatch, 1, 1); bs_restore(idx, nbatch, 0, 1, 0, 1);
X_LOCK; X_LOCK;
cache_list[idx].time = dnow(); cache_list[idx].time = dnow();
cache_list[idx].vis_cnt++; cache_list[idx].vis_cnt++;
Ev_map[i] = win; Ev_map[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x; Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y; Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width; 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 ...@@ -7689,16 +8626,47 @@ fprintf(stderr, "----%02d: VisibilityNotify 0x%x %3d state: %s U/P %d/%d\n", i
} else if (type == MapNotify) { } else if (type == MapNotify) {
idx = lookup_win_index(win); 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) { if (idx < 0) {
continue; continue;
} }
if (cache_list[idx].map_state == IsUnmapped || macosx_console) { if (cache_list[idx].map_state == IsUnmapped || desktop_change || macosx_console) {
X_UNLOCK; X_UNLOCK;
su_save(idx, nbatch, 1); if (desktop_change) {
bs_restore(idx, nbatch, 0, 1); /* 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) { if (macosx_console) {
#ifdef MACOSX #ifdef MACOSX
macosxCGS_follow_animation_win(win, -1, 1); macosxCGS_follow_animation_win(win, -1, 1);
...@@ -7716,7 +8684,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win, ...@@ -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; pixels += cache_list[idx].width * cache_list[idx].height;
cache_list[idx].time = dnow(); cache_list[idx].time = dnow();
cache_list[idx].map_cnt++; cache_list[idx].map_cnt++;
Ev_map[i] = win; Ev_map[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x; Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y; Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width; Ev_rects[nrects].x2 = cache_list[idx].width;
...@@ -7727,7 +8695,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win, ...@@ -7727,7 +8695,7 @@ fprintf(stderr, "----%02d: MapNotify 0x%x %3d\n", i, (unsigned int) win,
} else if (type == UnmapNotify) { } else if (type == UnmapNotify) {
idx = lookup_win_index(win); 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) { if (idx < 0) {
continue; continue;
...@@ -7738,15 +8706,45 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win, ...@@ -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; X_UNLOCK;
bs_save(idx, nbatch, 1); if (desktop_change) {
su_restore(idx, nbatch, 0, 1); 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; X_LOCK;
pixels += cache_list[idx].width * cache_list[idx].height; pixels += cache_list[idx].width * cache_list[idx].height;
cache_list[idx].time = dnow(); cache_list[idx].time = dnow();
cache_list[idx].unmap_cnt++; cache_list[idx].unmap_cnt++;
Ev_unmap[i] = win; Ev_unmap[ik] = win;
Ev_rects[nrects].x1 = cache_list[idx].x; Ev_rects[nrects].x1 = cache_list[idx].x;
Ev_rects[nrects].y1 = cache_list[idx].y; Ev_rects[nrects].y1 = cache_list[idx].y;
Ev_rects[nrects].x2 = cache_list[idx].width; Ev_rects[nrects].x2 = cache_list[idx].width;
...@@ -7760,7 +8758,7 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win, ...@@ -7760,7 +8758,7 @@ fprintf(stderr, "----%02d: UnmapNotify 0x%x %3d\n", i, (unsigned int) win,
win2 = ev.xreparent.window; win2 = ev.xreparent.window;
if (win2 != rootwin) { if (win2 != rootwin) {
idx = lookup_win_index(win2); 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) { if (idx >= 0) {
DELETE(idx); DELETE(idx);
} }
...@@ -7771,11 +8769,13 @@ fprintf(stderr, "----%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2 ...@@ -7771,11 +8769,13 @@ fprintf(stderr, "----%02d: ReparentNotifyRM 0x%x %3d\n", i, (unsigned int) win2
} else if (type == DestroyNotify) { } else if (type == DestroyNotify) {
win2 = ev.xdestroywindow.window; win2 = ev.xdestroywindow.window;
idx = lookup_win_index(win2); 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) { if (idx >= 0) {
DELETE(idx); 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 ...@@ -7783,11 +8783,7 @@ fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", i, (unsigned int) win2
X_UNLOCK; X_UNLOCK;
if (use_batch && nreg) { if (use_batch && nreg) {
int k; batch_push(nreg, -1.0);
batch_copyregion(batch_reg, batch_dxs, batch_dys, nreg, -1.0);
for (k=0; k < nreg; k++) {
sraRgnDestroy(batch_reg[k]);
}
} }
if (nrects) { if (nrects) {
if (scaling) { if (scaling) {
...@@ -7795,6 +8791,14 @@ fprintf(stderr, "----%02d: DestroyNotify 0x%x %3d\n", i, (unsigned int) win2 ...@@ -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); rfbLog("OUT check_ncache(): %.6f events: %d pixels: %d\n", dnow() - now, n, pixels);
return pixels; return pixels;
} }
......
.\" This file was automatically generated from x11vnc -help output. .\" 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 .SH NAME
x11vnc - allow VNC connections to real X11 displays 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 .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -2418,7 +2418,7 @@ detection not as accurate as the X version. ...@@ -2418,7 +2418,7 @@ detection not as accurate as the X version.
.PP .PP
\fB-ncache_cr\fR \fB-ncache_cr\fR
.IP .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 moves/drags instead of wireframes (this can induce
painting errors). The wireframe will still be used when painting errors). The wireframe will still be used when
moving a window whose save-unders has not yet been set moving a window whose save-unders has not yet been set
...@@ -2429,9 +2429,24 @@ with this option. On Unix, realvnc viewer gives ...@@ -2429,9 +2429,24 @@ with this option. On Unix, realvnc viewer gives
smoother drags than tightvnc viewer. Response may also smoother drags than tightvnc viewer. Response may also
be choppy if the server side machine is too slow. be choppy if the server side machine is too slow.
.PP .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 \fB-ncache_pad\fR \fIn\fR
.IP .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 caching rectangles. This can be used to try to improve
the situation with dropshadows or other compositing the situation with dropshadows or other compositing
(e.g. MacOS X window manager), although it could make (e.g. MacOS X window manager), although it could make
...@@ -4001,6 +4016,10 @@ ncache_cr enable \fB-ncache_cr\fR mode. ...@@ -4001,6 +4016,10 @@ ncache_cr enable \fB-ncache_cr\fR mode.
.IP .IP
noncache_cr disable \fB-ncache_cr\fR mode. noncache_cr disable \fB-ncache_cr\fR mode.
.IP .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" wireframe enable \fB-wireframe\fR mode. same as "wf"
.IP .IP
nowireframe disable \fB-wireframe\fR mode. same as "nowf" nowireframe disable \fB-wireframe\fR mode. same as "nowf"
...@@ -4277,12 +4296,13 @@ clear_keys noclear_keys remap repeat norepeat fb nofb ...@@ -4277,12 +4296,13 @@ clear_keys noclear_keys remap repeat norepeat fb nofb
bell nobell sel nosel primary noprimary setprimary bell nobell sel nosel primary noprimary setprimary
nosetprimary clipboard noclipboard setclipboard nosetprimary clipboard noclipboard setclipboard
nosetclipboard seldir cursorshape nocursorshape nosetclipboard seldir cursorshape nocursorshape
cursorpos nocursorpos cursor_drag nocursor_drag cursor cursorpos nocursorpos cursor_drag nocursor_drag
show_cursor noshow_cursor nocursor arrow xfixes noxfixes cursor show_cursor noshow_cursor nocursor arrow
xdamage noxdamage xd_area xd_mem alphacut alphafrac xfixes noxfixes xdamage noxdamage xd_area xd_mem
alpharemove noalpharemove alphablend noalphablend alphacut alphafrac alpharemove noalpharemove alphablend
xwarppointer xwarp noxwarppointer noxwarp buttonmap noalphablend xwarppointer xwarp noxwarppointer noxwarp
dragging nodragging ncache_cr noncache_cr ncache buttonmap dragging nodragging ncache_cr noncache_cr
ncache_no_moveraise noncache_no_moveraise ncache
noncache ncache_size wireframe_mode wireframe wf noncache ncache_size wireframe_mode wireframe wf
nowireframe nowf wireframelocal wfl nowireframelocal nowireframe nowf wireframelocal wfl nowireframelocal
nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area
......
...@@ -1451,7 +1451,7 @@ char msg[] = ...@@ -1451,7 +1451,7 @@ char msg[] =
"\n" "\n"
"Hello! Exciting News!!\n" "Hello! Exciting News!!\n"
"\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" "client-side pixel caching feature!\n"
"\n" "\n"
"This scheme stores pixel data offscreen on the VNC viewer side for faster\n" "This scheme stores pixel data offscreen on the VNC viewer side for faster\n"
...@@ -1468,12 +1468,13 @@ char msg[] = ...@@ -1468,12 +1468,13 @@ char msg[] =
"would notice and use the -ncache option (e.g. the wireframe and scroll\n" "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" "detection features are on by default). A couple things to note:\n"
"\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" "\n"
" 2) You can actually see the cached pixel data if you scroll down\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" " to it in your viewer; adjust your viewer's size to hide it.\n"
"\n" "\n"
"More info: http://www.karlrunge.com/x11vnc/#faq-client-caching\n" "More info: http://www.karlrunge.com/x11vnc/#faq-client-caching\n"
"waiting for connections:\n"
; ;
if (raw_fb_str && !macosx_console) { if (raw_fb_str && !macosx_console) {
...@@ -2161,6 +2162,10 @@ int main(int argc, char* argv[]) { ...@@ -2161,6 +2162,10 @@ int main(int argc, char* argv[]) {
} }
} else if (!strcmp(arg, "-ncache_cr")) { } else if (!strcmp(arg, "-ncache_cr")) {
ncache_copyrect = 1; 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")) { } else if (!strcmp(arg, "-ncache_pad")) {
CHECK_ARGC CHECK_ARGC
ncache_pad = atoi(argv[++i]); ncache_pad = atoi(argv[++i]);
...@@ -3249,6 +3254,7 @@ int main(int argc, char* argv[]) { ...@@ -3249,6 +3254,7 @@ int main(int argc, char* argv[]) {
multiple_cursors_mode = strdup("most"); multiple_cursors_mode = strdup("most");
if (! quiet && ! raw_fb_str) { if (! quiet && ! raw_fb_str) {
rfbLog("\n");
rfbLog("XFIXES available on display, resetting cursor mode\n"); rfbLog("XFIXES available on display, resetting cursor mode\n");
rfbLog(" to: '-cursor most'.\n"); rfbLog(" to: '-cursor most'.\n");
rfbLog(" to disable this behavior use: '-cursor arrow'\n"); rfbLog(" to disable this behavior use: '-cursor arrow'\n");
...@@ -3390,13 +3396,13 @@ int main(int argc, char* argv[]) { ...@@ -3390,13 +3396,13 @@ int main(int argc, char* argv[]) {
if (! quiet && ncache && ! raw_fb_str) { if (! quiet && ncache && ! raw_fb_str) {
rfbLog("\n"); rfbLog("\n");
rfbLog("Client Side Caching: -ncache mode is in effect to provide\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(" iconifying/deiconifying windows, moving and raising\n");
rfbLog(" windows, and reposting menus. In the simple CopyRect\n"); rfbLog(" windows, and reposting menus. In the simple CopyRect\n");
rfbLog(" encoding scheme used (no compression) a huge amount\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(" 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(" client sides. This mode works with any VNC viewer.\n");
rfbLog(" however in most you can actually see the cached pixel\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(" 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(" See http://www.karlrunge.com/x11vnc/#faq-client-caching.\n");
rfbLog(" If this mode yields undesired behavior (poor response,\n"); rfbLog(" If this mode yields undesired behavior (poor response,\n");
......
...@@ -464,9 +464,13 @@ extern double last_pointer_motion_time; ...@@ -464,9 +464,13 @@ extern double last_pointer_motion_time;
extern double last_key_to_button_remap_time; extern double last_key_to_button_remap_time;
extern double last_copyrect; extern double last_copyrect;
extern double last_copyrect_fix; extern double last_copyrect_fix;
extern double last_wireframe;
extern double servertime_diff; extern double servertime_diff;
extern double x11vnc_start; extern double x11vnc_start;
extern double last_get_wm_frame_time;
extern Window last_get_wm_frame;
extern int hack_val; extern int hack_val;
/* last client to move pointer */ /* last client to move pointer */
......
...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0; ...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* 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 */ /* X display info */
...@@ -128,9 +128,13 @@ double last_pointer_motion_time = 0.0; ...@@ -128,9 +128,13 @@ double last_pointer_motion_time = 0.0;
double last_key_to_button_remap_time = 0.0; double last_key_to_button_remap_time = 0.0;
double last_copyrect = 0.0; double last_copyrect = 0.0;
double last_copyrect_fix = 0.0; double last_copyrect_fix = 0.0;
double last_wireframe = 0.0;
double servertime_diff = 0.0; double servertime_diff = 0.0;
double x11vnc_start = 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; int hack_val = 0;
/* last client to move pointer */ /* last client to move pointer */
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
int grab_buster = 0; int grab_buster = 0;
int grab_kbd = 0; int grab_kbd = 0;
int grab_ptr = 0; int grab_ptr = 0;
int sync_tod_delay = 3; int sync_tod_delay = 20;
void initialize_vnc_connect_prop(void); void initialize_vnc_connect_prop(void);
void initialize_x11vnc_remote_prop(void); void initialize_x11vnc_remote_prop(void);
...@@ -28,6 +28,7 @@ void spawn_grab_buster(void); ...@@ -28,6 +28,7 @@ void spawn_grab_buster(void);
void sync_tod_with_servertime(void); void sync_tod_with_servertime(void);
void check_keycode_state(void); void check_keycode_state(void);
void check_autorepeat(void); void check_autorepeat(void);
void set_prop_atom(Atom atom);
void check_xevents(int reset); void check_xevents(int reset);
void xcut_receive(char *text, int len, rfbClientPtr cl); void xcut_receive(char *text, int len, rfbClientPtr cl);
...@@ -600,6 +601,16 @@ void sync_tod_with_servertime(void) { ...@@ -600,6 +601,16 @@ void sync_tod_with_servertime(void) {
RAWFB_RET_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) { if (! ticker_atom) {
ticker_atom = XInternAtom(dpy, "X11VNC_TICKER", False); ticker_atom = XInternAtom(dpy, "X11VNC_TICKER", False);
} }
...@@ -609,7 +620,7 @@ void sync_tod_with_servertime(void) { ...@@ -609,7 +620,7 @@ void sync_tod_with_servertime(void) {
XSync(dpy, False); XSync(dpy, False);
while (XCheckTypedEvent(dpy, PropertyNotify, &xev)) { while (XCheckTypedEvent(dpy, PropertyNotify, &xev)) {
; set_prop_atom(xev.xproperty.atom);
} }
snprintf(diff, 128, "%d/%08d/%lu/%.6f", (int) getpid(), seq++, snprintf(diff, 128, "%d/%08d/%lu/%.6f", (int) getpid(), seq++,
...@@ -739,6 +750,13 @@ void check_autorepeat(void) { ...@@ -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 * This routine is periodically called to check for selection related
* and other X11 events and respond to them as needed. * and other X11 events and respond to them as needed.
...@@ -871,7 +889,10 @@ void check_xevents(int reset) { ...@@ -871,7 +889,10 @@ void check_xevents(int reset) {
* Go retrieve X11VNC_REMOTE string. * Go retrieve X11VNC_REMOTE string.
*/ */
read_x11vnc_remote_prop(0); read_x11vnc_remote_prop(0);
} }
set_prop_atom(xev.xproperty.atom);
} }
} }
......
...@@ -15,6 +15,7 @@ extern void spawn_grab_buster(void); ...@@ -15,6 +15,7 @@ extern void spawn_grab_buster(void);
extern void sync_tod_with_servertime(void); extern void sync_tod_with_servertime(void);
extern void check_keycode_state(void); extern void check_keycode_state(void);
extern void check_autorepeat(void); extern void check_autorepeat(void);
extern void set_prop_atom(Atom atom);
extern void check_xevents(int reset); extern void check_xevents(int reset);
extern void xcut_receive(char *text, int len, rfbClientPtr cl); extern void xcut_receive(char *text, int len, rfbClientPtr cl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment