x11vnc: more work on -ncache.

pull/1/head
runge 18 years ago
parent 8aa6fb9523
commit 56eb45a5f8

@ -1,3 +1,7 @@
2006-12-28 Karl Runge <runge@karlrunge.com>
* x11vnc: more work on -ncache, add macosx support, fix X errors
and improve cache expiration algorithm.
2006-12-17 Karl Runge <runge@karlrunge.com>
* x11vnc: first pass at client-side caching, -ncache option.
have -http guess ../classes/.. to run out of build area.

File diff suppressed because it is too large Load Diff

@ -359,6 +359,7 @@ crash_prompt:
static void interrupted (int sig) {
exit_sig = sig;
if (exit_flag) {
fprintf(stderr, "extra[%d] signal: %d\n", exit_flag, sig);
exit_flag++;
if (use_threads) {
usleep2(250 * 1000);
@ -370,6 +371,7 @@ static void interrupted (int sig) {
exit_flag++;
if (sig == 0) {
fprintf(stderr, "caught X11 error:\n");
if (crash_debug) { crash_shell(); }
} else if (sig == -1) {
fprintf(stderr, "caught XIO error:\n");
} else {
@ -380,6 +382,10 @@ static void interrupted (int sig) {
return;
}
if (crash_debug) {
crash_shell();
}
X_UNLOCK;
if (icon_mode) {

@ -1033,7 +1033,7 @@ static unsigned char t2x2_bits[] = {
XSetStandardProperties(dpy, awin, sprop, "x11vnc query", ico, NULL,
0, &hints);
XSelectInput(dpy, awin, evmask);
XSelectInput_wr(dpy, awin, evmask);
if (! font_info && (font_info = XLoadQueryFont(dpy, "fixed")) == NULL) {
rfbLogEnable(1);
@ -1209,7 +1209,7 @@ static unsigned char t2x2_bits[] = {
}
if (out != -1) {
ret = out;
XSelectInput(dpy, awin, 0);
XSelectInput_wr(dpy, awin, 0);
XUnmapWindow(dpy, awin);
XFree_wr(gc);
XDestroyWindow(dpy, awin);
@ -1554,7 +1554,7 @@ static void check_connect_file(char *file) {
rfbLog("read connect file: %s\n", str);
}
if (!strcmp(str, "cmd=stop") &&
dnow() - x11vnc_start < 3.0) {
dnowx() < 3.0) {
rfbLog("ignoring stale cmd=stop\n");
} else {
client_connect = str;
@ -2131,6 +2131,10 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
accepted_client = 1;
last_client = time(NULL);
if (ncache) {
check_ncache(1, 0);
}
if (unixpw) {
unixpw_in_progress = 1;
unixpw_client = client;

@ -1705,6 +1705,24 @@ int cursor_shape_updates_clients(rfbScreenInfoPtr s) {
return count;
}
int cursor_noshape_updates_clients(rfbScreenInfoPtr s) {
rfbClientIteratorPtr iter;
rfbClientPtr cl;
int count = 0;
if (! s) {
return 0;
}
iter = rfbGetClientIterator(s);
while( (cl = rfbClientIteratorNext(iter)) ) {
if (!cl->enableCursorShapeUpdates) {
count++;
}
}
rfbReleaseClientIterator(iter);
return count;
}
int cursor_pos_updates_clients(rfbScreenInfoPtr s) {
rfbClientIteratorPtr iter;
rfbClientPtr cl;

@ -24,6 +24,7 @@ extern int get_which_cursor(void);
extern void restore_cursor_shape_updates(rfbScreenInfoPtr s);
extern void disable_cursor_shape_updates(rfbScreenInfoPtr s);
extern int cursor_shape_updates_clients(rfbScreenInfoPtr s);
extern int cursor_noshape_updates_clients(rfbScreenInfoPtr s);
extern int cursor_pos_updates_clients(rfbScreenInfoPtr s);
extern void cursor_position(int x, int y);
extern void set_no_cursor(void);

@ -2028,17 +2028,49 @@ void print_help(int mode) {
" If this method is successful, the changes required for\n"
" clients to do this less awkwardly will be investigated.\n"
"\n"
" Note that this mode consumes a lot of memory, both\n"
" on the x11vnc server side and on the VNC Viewer side.\n"
" If n=2 then the amount of RAM used is roughly tripled\n"
" for both x11vnc and the VNC Viewer. As a rule of\n"
" thumb, note that 1280x1024 at depth 24 is about 5MB of\n"
" pixel data.\n"
" Note that this mode consumes a huge amount of memory,\n"
" both on the x11vnc server side and on the VNC Viewer\n"
" side. If n=2 then the amount of RAM used is roughly\n"
" tripled for both x11vnc and the VNC Viewer. As a rule\n"
" of thumb, note that 1280x1024 at depth 24 is about 5MB\n"
" of pixel data.\n"
"\n"
" For reasonable response when cycling through 4 to 6\n"
" large (e.g. web browser) windows a value n of 6 to 12\n"
" is recommended. (that's right: ~10X more memory...)\n"
"\n"
" Because of the way window backingstore and saveunders\n"
" are implemented, n must be even. It will be incremented\n"
" by 1 if it is not.\n"
"\n"
" This mode also works for native MacOS X, but may not\n"
" be as effective as the X version. This is due to a\n"
" number of things, one is the drop-shadow compositing\n"
" that leaves extra areas that need to be repaired (see\n"
" -ncache_pad). Another is the window iconification\n"
" animations need to be avoided (see -macicontime).\n"
" It appears the that the 'Scale' animation mode gives\n"
" better results than the 'Genie' one. Also, window event\n"
" detection not as accurate as the X version.\n"
"\n"
"-ncache_cr In -nache mode, try do to copyrect opaque window\n"
" moves/drags instead of wireframes (this can induce\n"
" painting errors). The wireframe will still be used when\n"
" moving a window whose save-unders has not yet been set\n"
" or has been invalidated.\n"
"\n"
" Some VNC Viewers provide better response than others\n"
" with this option. On Unix, realvnc viewer gives\n"
" smoother drags than tightvnc viewer. Response may also\n"
" be choppy if the server side machine is too slow.\n"
"\n"
"-ncache_pad n In -nache mode, pad each window with n pixels for the\n"
" caching rectangles. This can be used to try to improve\n"
" the situation with dropshadows or other compositing\n"
" (e.g. MacOS X window manager), although it could make\n"
" things worse. The default is 0 on Unix and 24 on\n"
" MacOS X.\n"
"\n"
#endif
"-wireframe [str] Try to detect window moves or resizes when a mouse\n"
"-nowireframe button is held down and show a wireframe instead of\n"
@ -2975,6 +3007,13 @@ void print_help(int mode) {
"-macnoresize For the native Mac OS X server, do not resize or reset\n"
" the framebuffer even if it is detected that the screen\n"
" resolution or depth has changed.\n"
"-maciconanim n For the native Mac OS X server, set n to the number\n"
" of milliseconds that the window iconify/deiconify\n"
" animation takes. In -ncache mode this value will be\n"
" used to skip the animation if possible. (default 400)\n"
"-macmenu For the native Mac OS X server, in -ncache client-side\n"
" caching mode, try to cache pull down menus (not perfect\n"
" because they have animated fades, etc.)\n"
"\n"
"-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote\n"
" control options -remote/-query described below.\n"
@ -3285,6 +3324,11 @@ void print_help(int mode) {
" buttonmap:str set -buttonmap \"str\", empty to disable\n"
" dragging disable -nodragging mode.\n"
" nodragging enable -nodragging mode.\n"
" ncache reenable -ncache mode.\n"
" noncache disable -ncache mode.\n"
" ncache_size:n set -ncache size to n.\n"
" ncache_cr enable -ncache_cr mode.\n"
" noncache_cr disable -ncache_cr mode.\n"
" wireframe enable -wireframe mode. same as \"wf\"\n"
" nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n"
@ -3350,6 +3394,16 @@ void print_help(int mode) {
" rfbport:n set -rfbport to n.\n"
" macnosaver enable -macnosaver mode.\n"
" macsaver disable -macnosaver mode.\n"
" macnowait enable -macnowait mode.\n"
" macwait disable -macnowait mode.\n"
" macwheel:n set -macwheel to n.\n"
" macnoswap enable -macnoswap mouse button mode.\n"
" macswap disable -macnoswap mouse button mode.\n"
" macnoresize enable -macnoresize mode.\n"
" macresize disable -macnoresize mode.\n"
" maciconanim:n set -maciconanim to n.\n"
" macmenu enable -macmenu mode.\n"
" macnomenu disable -macnmenu mode.\n"
/* access */
" httpport:n set -httpport to n.\n"
" httpdir:dir set -httpdir to dir (and enable http).\n"
@ -3439,7 +3493,8 @@ void print_help(int mode) {
" xdamage noxdamage xd_area xd_mem alphacut alphafrac\n"
" alpharemove noalpharemove alphablend noalphablend\n"
" xwarppointer xwarp noxwarppointer noxwarp buttonmap\n"
" dragging nodragging wireframe_mode wireframe wf\n"
" dragging nodragging ncache_cr noncache_cr ncache\n"
" noncache ncache_size wireframe_mode wireframe wf\n"
" nowireframe nowf wireframelocal wfl nowireframelocal\n"
" nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
@ -3462,7 +3517,10 @@ void print_help(int mode) {
" debug_wireframe debug_scroll nodebug_scroll debug_scroll\n"
" debug_tiles dbt nodebug_tiles nodbt debug_tiles\n"
" debug_grabs nodebug_grabs debug_sel nodebug_sel dbg\n"
" nodbg macnosaver macsaver noremote\n"
" nodbg macnosaver macsaver nomacnosaver macnowait macwait\n"
" nomacnowait macwheel macnoswap macswap nomacnoswap\n"
" macnoresize macresize nomacnoresize maciconanim macmenu\n"
" macnomenu nomacmenu noremote\n"
"\n"
" aro= noop display vncdisplay desktopname guess_desktop\n"
" http_url auth xauth users rootshift clipshift\n"
@ -3479,6 +3537,8 @@ void print_help(int mode) {
" mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y\n"
" wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y\n"
" rfbauth passwd viewpasswd\n"
"\n"
"\n"
"-QD variable Just like -query variable, but returns the default\n"
" value for that parameter (no running x11vnc server\n"
" is consulted)\n"

@ -997,15 +997,13 @@ void switch_to_xkb_if_better(void) {
XFree_wr(keymap);
if (missing_noxkb == 0 && syms_gt_4 >= 8) {
if (! raw_fb_str) {
rfbLog("XKEYBOARD: number of keysyms per keycode %d "
"is greater\n", syms_per_keycode);
rfbLog(" than 4 and %d keysyms are mapped above 4.\n",
syms_gt_4);
rfbLog("\n");
rfbLog("XKEYBOARD: number of keysyms per keycode %d is greater\n", syms_per_keycode);
rfbLog(" than 4 and %d keysyms are mapped above 4.\n", syms_gt_4);
rfbLog(" Automatically switching to -xkb mode.\n");
rfbLog(" If this makes the key mapping worse you can\n");
rfbLog(" disable it with the \"-noxkb\" option.\n");
rfbLog(" Also, remember \"-remap DEAD\" for accenting"
" characters.\n");
rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n");
}
use_xkb_modtweak = 1;
@ -1013,13 +1011,11 @@ void switch_to_xkb_if_better(void) {
} else if (missing_noxkb == 0) {
if (! raw_fb_str) {
rfbLog("XKEYBOARD: all %d \"must have\" keysyms accounted"
" for.\n", n);
rfbLog("\n");
rfbLog("XKEYBOARD: all %d \"must have\" keysyms accounted for.\n", n);
rfbLog(" Not automatically switching to -xkb mode.\n");
rfbLog(" If some keys still cannot be typed, try using"
" -xkb.\n");
rfbLog(" Also, remember \"-remap DEAD\" for accenting"
" characters.\n");
rfbLog(" If some keys still cannot be typed, try using -xkb.\n");
rfbLog(" Also, remember \"-remap DEAD\" for accenting characters.\n");
}
return;
}

@ -36,6 +36,12 @@ int macosx_valid_window(Window, XWindowAttributes*);
Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return);
void macosx_add_mapnotify(Window win, int level, int map);
void macosx_add_create(Window win, int level);
void macosx_add_destroy(Window win, int level);
void macosx_add_visnotify(Window win, int level, int obscured);
int macosx_checkevent(XEvent *ev);
#if (! DOMAC)
void macosx_event_loop(void) {
@ -72,6 +78,22 @@ Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return) {
return (Status) 0;
}
void macosx_add_mapnotify(Window win, int level, int map) {
return;
}
void macosx_add_create(Window win, int level) {
return;
}
void macosx_add_destroy(Window win, int level) {
return;
}
void macosx_add_visnotify(Window win, int level, int obscured) {
return;
}
int macosx_checkevent(XEvent *ev) {
return 0;
}
int dragum(void) {return 1;}
@ -169,6 +191,8 @@ char *macosx_console_guess(char *str, int *fd) {
return q;
}
Window macosx_click_frame = None;
void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
allowed_input_t input;
static int last_mask = 0;
@ -197,6 +221,16 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
last_pointer_client = client;
last_pointer_time = time(NULL);
}
if (last_mask != mask) {
fprintf(stderr, "about to inject mask change %d -> %d: %.4f\n", last_mask, mask, dnowx());
if (mask) {
int px, py, x, y, w, h;
macosx_click_frame = None;
if (!macosx_get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &macosx_click_frame, NULL)) {
macosx_click_frame = None;
}
}
}
macosxCG_pointer_inject(mask, x, y);
@ -209,6 +243,19 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (last_mask != mask) {
last_pointer_click_time = dnow();
if (ncache > 0) {
/* XXX Y */
int i;
fprintf(stderr, "about to get all windows: %.4f\n", dnowx());
for (i=0; i < 2; i++) {
macosxCGS_get_all_windows();
fprintf(stderr, "!");
if (macosx_checkevent(NULL)) {
break;
}
}
fprintf(stderr, "\ndone: %.4f\n", dnowx());
}
}
last_mask = mask;
@ -299,11 +346,130 @@ int macosx_get_cursor(void) {
return macosxCG_get_cursor();
}
typedef struct evdat {
int win;
int map;
int level;
int vis;
int type;
} evdat_t;
#define MAX_EVENTS 1024
evdat_t mac_events[MAX_EVENTS];
int mac_events_ptr = 0;
int mac_events_last = 0;
void macosx_add_mapnotify(Window win, int level, int map) {
int i = mac_events_last++;
mac_events[i].win = win;
mac_events[i].level = level;
if (map) {
mac_events[i].type = MapNotify;
} else {
mac_events[i].type = UnmapNotify;
}
mac_events[i].map = map;
mac_events[i].vis = -1;
mac_events_last = mac_events_last % MAX_EVENTS;
return;
}
void macosx_add_create(Window win, int level) {
int i = mac_events_last++;
mac_events[i].win = win;
mac_events[i].level = level;
mac_events[i].type = CreateNotify;
mac_events[i].map = -1;
mac_events[i].vis = -1;
mac_events_last = mac_events_last % MAX_EVENTS;
return;
}
void macosx_add_destroy(Window win, int level) {
int i = mac_events_last++;
mac_events[i].win = win;
mac_events[i].level = level;
mac_events[i].type = DestroyNotify;
mac_events[i].map = -1;
mac_events[i].vis = -1;
mac_events_last = mac_events_last % MAX_EVENTS;
return;
}
void macosx_add_visnotify(Window win, int level, int obscured) {
int i = mac_events_last++;
mac_events[i].win = win;
mac_events[i].level = level;
mac_events[i].type = VisibilityNotify;
mac_events[i].map = -1;
mac_events[i].vis = 1;
if (obscured == 0) {
mac_events[i].vis = VisibilityUnobscured;
} else if (obscured == 1) {
mac_events[i].vis = VisibilityPartiallyObscured;
} else if (obscured == 2) {
mac_events[i].vis = VisibilityFullyObscured; /* NI */
}
mac_events_last = mac_events_last % MAX_EVENTS;
return;
}
int macosx_checkevent(XEvent *ev) {
int i = mac_events_ptr;
if (mac_events_ptr == mac_events_last) {
return 0;
}
if (ev == NULL) {
return mac_events[i].type;
}
ev->xany.window = mac_events[i].win;
if (mac_events[i].type == CreateNotify) {
ev->type = CreateNotify;
ev->xany.window = rootwin;
ev->xcreatewindow.window = mac_events[i].win;
} else if (mac_events[i].type == DestroyNotify) {
ev->type = DestroyNotify;
ev->xdestroywindow.window = mac_events[i].win;
} else if (mac_events[i].type == VisibilityNotify) {
ev->type = VisibilityNotify;
ev->xvisibility.state = mac_events[i].vis;
} else if (mac_events[i].type == MapNotify) {
ev->type = MapNotify;
} else if (mac_events[i].type == UnmapNotify) {
ev->type = UnmapNotify;
} else {
fprintf(stderr, "unknown macosx_checkevent: %d\n", mac_events[i].type);
}
mac_events_ptr++;
mac_events_ptr = mac_events_ptr % MAX_EVENTS;
return mac_events[i].type;
}
typedef struct windat {
int win;
int x, y;
int width, height;
int level;
int mapped;
int clipped;
int ncache_only;
} windat_t;
extern int macwinmax;
@ -313,19 +479,13 @@ int macosx_get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
Window *frame, Window *win) {
static int last_idx = -1;
int x1, x2, y1, y2;
int idx = -1, i, k;
int idx = -1, k;
macosxCGS_get_all_windows();
macosxCG_get_cursor_pos(px, py);
for (i = -1; i<macwinmax; i++) {
k = i;
if (i == -1) {
if (last_idx >= 0 && last_idx < macwinmax) {
k = last_idx;
} else {
last_idx = -1;
continue;
}
for (k = 0; k<macwinmax; k++) {
if (! macwins[k].mapped) {
continue;
}
x1 = macwins[k].x;
x2 = macwins[k].x + macwins[k].width;
@ -362,19 +522,38 @@ int macosx_valid_window(Window w, XWindowAttributes* a) {
int win = (int) w;
int i, k, idx = -1;
for (i = -1; i<macwinmax; i++) {
k = i;
if (i == -1) {
if (last_idx >= 0 && last_idx < macwinmax) {
k = last_idx;
} else {
last_idx = -1;
continue;
if (last_idx >= 0 && last_idx < macwinmax) {
if (macwins[last_idx].win == win) {
idx = last_idx;
}
}
if (idx < 0) {
idx = macosxCGS_get_qlook(w);
if (idx >= 0 && idx < macwinmax) {
if (macwins[idx].win != win) {
idx = -1;
}
} else {
idx = -1;
}
if (macwins[k].win == win) {
idx = k;
break;
}
if (idx < 0) {
for (i = 0; i<macwinmax; i++) {
k = i;
if (i == -1) {
if (last_idx >= 0 && last_idx < macwinmax) {
k = last_idx;
} else {
last_idx = -1;
continue;
}
}
if (macwins[k].win == win) {
idx = k;
break;
}
}
}
if (idx < 0) {
@ -388,7 +567,11 @@ int macosx_valid_window(Window w, XWindowAttributes* a) {
a->depth = depth;
a->border_width = 0;
a->backing_store = 0;
a->map_state = IsViewable;
if (macwins[idx].mapped) {
a->map_state = IsViewable;
} else {
a->map_state = IsUnmapped;
}
last_idx = idx;
@ -415,6 +598,7 @@ Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
n = 0;
for (k = CGS_levelmax - 1; k >= 0; k--) {
for (i = macwinmax - 1; i >= 0; i--) {
if (n >= QTMAX) break;
if (macwins[i].level == CGS_levels[k]) {
if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n);
cret[n++] = (Window) macwins[i].win;
@ -427,5 +611,81 @@ if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n);
return (Status) 1;
}
int macosx_check_offscreen(int win) {
sraRegionPtr r0, r1;
int x1, y1, x2, y2;
int ret;
int i = macosxCGS_find_index(win);
if (i < 0) {
return 0;
}
x1 = macwins[i].x;
y1 = macwins[i].y;
x2 = macwins[i].x + macwins[i].width;
y2 = macwins[i].y + macwins[i].height;
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r1 = sraRgnCreateRect(x1, y1, x2, y2);
if (sraRgnAnd(r1, r0)) {
ret = 0;
} else {
ret = 1;
}
sraRgnDestroy(r0);
sraRgnDestroy(r1);
return ret;
}
int macosx_check_clipped(int win, int *list, int n) {
sraRegionPtr r0, r1, r2;
int x1, y1, x2, y2;
int ret = 0;
int k, j, i = macosxCGS_find_index(win);
if (i < 0) {
return 0;
}
x1 = macwins[i].x;
y1 = macwins[i].y;
x2 = macwins[i].x + macwins[i].width;
y2 = macwins[i].y + macwins[i].height;
r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
r1 = sraRgnCreateRect(x1, y1, x2, y2);
sraRgnAnd(r1, r0);
for (k = 0; k < n; k++) {
j = macosxCGS_find_index(list[k]); /* XXX slow? */
if (j < 0) {
continue;
}
x1 = macwins[j].x;
y1 = macwins[j].y;
x2 = macwins[j].x + macwins[j].width;
y2 = macwins[j].y + macwins[j].height;
r2 = sraRgnCreateRect(x1, y1, x2, y2);
if (sraRgnAnd(r2, r1)) {
ret = 1;
sraRgnDestroy(r2);
//fprintf(stderr, "macosx_check_clipped: %4d %4d -- CLIP\n", win, list[k]);
break;
}
//fprintf(stderr, "macosx_check_clipped: %4d %4d -- -no-\n", win, list[k]);
sraRgnDestroy(r2);
}
sraRgnDestroy(r0);
sraRgnDestroy(r1);
//fprintf(stderr, "macosx_check_clipped: %4d -- CLIP: %s\n", win, ret ? "yes" : "no");
return ret;
}
#endif /* LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY */

@ -16,6 +16,13 @@ extern Status macosx_xquerytree(Window w, Window *root_return, Window *parent_re
extern void macosx_send_sel(char *, int);
extern void macosx_set_sel(char *, int);
extern void macosx_add_mapnotify(Window win, int level, int map);
extern void macosx_add_create(Window win, int level);
extern void macosx_add_destroy(Window win, int level);
extern void macosx_add_visnotify(Window win, int level, int obscured);
extern int macosx_checkevent(XEvent *ev);
extern Window macosx_click_frame;
#endif /* _X11VNC_MACOSX_H */

@ -15,6 +15,7 @@
extern CGDirectDisplayID displayID;
void macosxCGS_get_all_windows(void);
int macosxCGS_get_qlook(int);
void macosxGCS_set_pasteboard(char *str, int len);
typedef CGError CGSError;
@ -31,6 +32,10 @@ extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
CGSConnectionID owner, CGSWindowCount listCapacity,
CGSWindowIDList list, CGSWindowCount *listCount);
extern CGSError CGSGetWindowList (CGSConnectionID cid,
CGSConnectionID owner, CGSWindowCount listCapacity,
CGSWindowIDList list, CGSWindowCount *listCount);
extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
CGSWindowID wid, CGSRect *rect);
@ -54,40 +59,181 @@ typedef struct windat {
int x, y;
int width, height;
int level;
int mapped;
int clipped;
int ncache_only;
} windat_t;
#define MAXWINDAT 2048
extern int ncache;
#define MAXWINDAT 4096
windat_t macwins[MAXWINDAT];
static CGSWindowID _wins[MAXWINDAT];
static CGSWindowID _wins_all[MAXWINDAT];
static CGSWindowID _wins_mapped[MAXWINDAT];
static CGSWindowCount _wins_all_cnt, _wins_mapped_cnt;
static int _wins_int[MAXWINDAT];
#define WINHISTNUM 32768
#define WINHISTMAX 4
char whist[WINHISTMAX][WINHISTNUM];
int whist_idx = -1;
int qlook[WINHISTNUM];
char is_exist = 0x1;
char is_mapped = 0x2;
char is_clipped = 0x4;
char is_offscreen = 0x8;
extern double dnow(void);
extern double dnowx(void);
extern int dpy_x, dpy_y;
extern int macosx_icon_anim_time;
extern void macosx_add_mapnotify(int, int, int);
extern void macosx_add_create(int, int);
extern void macosx_add_destroy(int, int);
extern void macosx_add_visnotify(int, int, int);
int CGS_levelmax;
int CGS_levels[16];
int macosxCGS_get_qlook(int w) {
if (w >= WINHISTNUM) {
return -1;
}
return qlook[w];
}
int macosxCGS_find_index(int w) {
static int last_index = -1;
int idx;
if (last_index >= 0) {
if (macwins[last_index].win == w) {
return last_index;
}
}
idx = macosxCGS_get_qlook(w);
if (idx >= 0) {
if (macwins[idx].win == w) {
last_index = idx;
return idx;
}
}
for (idx=0; idx < macwinmax; idx++) {
if (macwins[idx].win == w) {
last_index = idx;
return idx;
}
}
return -1;
}
int macosxCGS_follow_animation_win(int win, int idx, int grow) {
double t = dnow();
int diffs = 0;
int x, y, w, h;
int xp, yp, wp, hp;
CGSRect rect;
CGSError err;
int reps = 0;
if (cid == NULL) {
cid = _CGSDefaultConnection();
if (cid == NULL) {
return 0;
}
}
if (idx < 0) {
idx = macosxCGS_find_index(win);
}
if (idx < 0) {
return 0;
}
while (dnow() < t + 0.001 * macosx_icon_anim_time) {
err = CGSGetScreenRectForWindow(cid, win, &rect);
if (err != 0) {
break;
}
x = (int) rect.origin.x;
y = (int) rect.origin.y;
w = (int) rect.size.width;
h = (int) rect.size.height;
if (grow) {
macwins[idx].x = x;
macwins[idx].y = y;
macwins[idx].width = w;
macwins[idx].height = h;
}
fprintf(stderr, " chase: %03dx%03d+%03d+%03d %d\n", w, h, x, y, win);
if (x == xp && y == yp && w == wp && h == hp) {
reps++;
if (reps >= 2) {
break;
}
} else {
diffs++;
reps = 0;
}
xp = x;
yp = y;
wp = w;
hp = h;
usleep(50 * 1000);
}
if (diffs >= 2) {
return 1;
} else {
return 0;
}
}
extern int macosx_check_clipped(int win, int *list, int n);
extern int macosx_check_offscreen(int win);
static int check_clipped(int win) {
int i, n = 0, win2;
for (i = 0; i < (int) _wins_mapped_cnt; i++) {
win2 = (int) _wins_mapped[i];
if (win2 == win) {
break;
}
_wins_int[n++] = win2;
}
return macosx_check_clipped(win, _wins_int, n);
}
static int check_offscreen(int win) {
return macosx_check_offscreen(win);
}
extern int macosx_ncache_macmenu;
void macosxCGS_get_all_windows(void) {
static double last = 0.0;
static int first = 1;
static int totcnt = 0;
double dt = 0.0, now = dnow();
int i, db = 0;
int i, db = 0, whist_prv, maxwin = 0, whist_skip = 0;
CGSWindowCount cap = (CGSWindowCount) MAXWINDAT;
CGSWindowCount cnt = 0;
CGSError err;
if (first) {
first = 0;
CGS_levelmax = 0;
CGS_levels[CGS_levelmax++] = (int) kCGDraggingWindowLevel; /* 500 ? */
if (0) CGS_levels[CGS_levelmax++] = (int) kCGHelpWindowLevel; /* 102 ? */
if (0) CGS_levels[CGS_levelmax++] = (int) kCGPopUpMenuWindowLevel; /* 101 pulldown menu */
CGS_levels[CGS_levelmax++] = (int) kCGMainMenuWindowLevelKey; /* 24 ? */
CGS_levels[CGS_levelmax++] = (int) kCGModalPanelWindowLevel; /* 8 open dialog box */
CGS_levels[CGS_levelmax++] = (int) kCGFloatingWindowLevel; /* 3 ? */
CGS_levels[CGS_levelmax++] = (int) kCGNormalWindowLevel; /* 0 regular window */
}
CGS_levelmax = 0;
CGS_levels[CGS_levelmax++] = (int) kCGDraggingWindowLevel; /* 500 ? */
if (0) CGS_levels[CGS_levelmax++] = (int) kCGHelpWindowLevel; /* 102 ? */
if (macosx_ncache_macmenu) CGS_levels[CGS_levelmax++] = (int) kCGPopUpMenuWindowLevel; /* 101 pulldown menu */
CGS_levels[CGS_levelmax++] = (int) kCGMainMenuWindowLevelKey; /* 24 ? */
CGS_levels[CGS_levelmax++] = (int) kCGModalPanelWindowLevel; /* 8 open dialog box */
CGS_levels[CGS_levelmax++] = (int) kCGFloatingWindowLevel; /* 3 ? */
CGS_levels[CGS_levelmax++] = (int) kCGNormalWindowLevel; /* 0 regular window */
if (cid == NULL) {
cid = _CGSDefaultConnection();
@ -100,23 +246,38 @@ void macosxCGS_get_all_windows(void) {
return;
}
err = CGSGetOnScreenWindowList(cid, NULL, cap, _wins, &cnt);
last = now;
macwinmax = 0;
if (db) fprintf(stderr, "cnt: %d err: %d\n", cnt, err);
totcnt++;
if (ncache > 0) {
whist_prv = whist_idx++;
if (whist_prv < 0) {
whist_skip = 1;
whist_prv = 0;
}
whist_idx = whist_idx % WINHISTMAX;
for (i=0; i < WINHISTNUM; i++) {
whist[whist_idx][i] = 0;
qlook[i] = -1;
}
}
err = CGSGetWindowList(cid, NULL, cap, _wins_all, &_wins_all_cnt);
if (db) fprintf(stderr, "cnt: %d err: %d\n", _wins_all_cnt, err);
if (err != 0) {
return;
}
last = now;
macwinmax = 0;
for (i=0; i < (int) cnt; i++) {
for (i=0; i < (int) _wins_all_cnt; i++) {
CGSRect rect;
CGSWindowLevel level;
int j, keepit = 0;
err = CGSGetScreenRectForWindow(cid, _wins[i], &rect);
err = CGSGetScreenRectForWindow(cid, _wins_all[i], &rect);
if (err != 0) {
continue;
}
@ -127,7 +288,7 @@ if (db) fprintf(stderr, "cnt: %d err: %d\n", cnt, err);
}
}
}
err = CGSGetWindowLevel(cid, _wins[i], &level);
err = CGSGetWindowLevel(cid, _wins_all[i], &level);
if (err != 0) {
continue;
}
@ -142,16 +303,180 @@ if (db) fprintf(stderr, "cnt: %d err: %d\n", cnt, err);
}
macwins[macwinmax].level = (int) level;
macwins[macwinmax].win = (int) _wins[i];
macwins[macwinmax].win = (int) _wins_all[i];
macwins[macwinmax].x = (int) rect.origin.x;
macwins[macwinmax].y = (int) rect.origin.y;
macwins[macwinmax].width = (int) rect.size.width;
macwins[macwinmax].height = (int) rect.size.height;
if (db) fprintf(stderr, "i=%03d ID: %06d x: %03d y: %03d w: %03d h: %03d level: %d\n", i, _wins[i],
macwins[macwinmax].mapped = 0;
macwins[macwinmax].clipped = 0;
macwins[macwinmax].ncache_only = 0;
if (level == kCGPopUpMenuWindowLevel) {
macwins[macwinmax].ncache_only = 1;
}
if (0 || db) fprintf(stderr, "i=%03d ID: %06d x: %03d y: %03d w: %03d h: %03d level: %d\n", i, _wins_all[i],
(int) rect.origin.x, (int) rect.origin.y,(int) rect.size.width, (int) rect.size.height, (int) level);
if (macwins[macwinmax].win < WINHISTNUM) {
qlook[macwins[macwinmax].win] = macwinmax;
if (macwins[macwinmax].win > maxwin) {
maxwin = macwins[macwinmax].win;
}
}
macwinmax++;
}
err = CGSGetOnScreenWindowList(cid, NULL, cap, _wins_mapped, &_wins_mapped_cnt);
if (db) fprintf(stderr, "cnt: %d err: %d\n", _wins_mapped_cnt, err);
if (err != 0) {
return;
}
for (i=0; i < (int) _wins_mapped_cnt; i++) {
int j, idx = -1;
int win = (int) _wins_mapped[i];
if (0 <= win && win < WINHISTNUM) {
j = qlook[win];
if (j >= 0 && macwins[j].win == win) {
idx = j;
}
}
if (idx < 0) {
for (j=0; j < macwinmax; j++) {
if (macwins[j].win == win) {
idx = j;
break;
}
}
}
if (idx >= 0) {
macwins[idx].mapped = 1;
}
}
if (ncache > 0) {
int nv= 0, NBMAX = 64;
int nv_win[64];
int nv_lvl[64];
int nv_vis[64];
for (i=0; i < macwinmax; i++) {
int win = macwins[i].win;
char prev, curr;
if (win >= WINHISTNUM) {
continue;
}
whist[whist_idx][win] |= is_exist;
if (macwins[i].mapped) {
whist[whist_idx][win] |= is_mapped;
if (check_clipped(win)) {
whist[whist_idx][win] |= is_clipped;
macwins[i].clipped = 1;
}
if (check_offscreen(win)) {
whist[whist_idx][win] |= is_offscreen;
}
} else {
whist[whist_idx][win] |= is_offscreen;
}
curr = whist[whist_idx][win];
prev = whist[whist_prv][win];
if (whist_skip) {
;
} else if ( !(prev & is_mapped) && (curr & is_mapped)) {
/* MapNotify */
fprintf(stderr, "MapNotify: %d/%d %d %.4f %d tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 1);
//macosxCGS_follow_animation_win(win, i, 1);
} else if ( !(curr & is_mapped) && (prev & is_mapped)) {
/* UnmapNotify */
fprintf(stderr, "UnmapNotify: %d/%d %d %.4f A tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 0);
} else if ( !(prev & is_exist) && (curr & is_exist)) {
/* CreateNotify */
fprintf(stderr, "CreateNotify:%d/%d %d %.4f whist: %d/%d 0x%x tot=%d\n", prev, curr, win, dnowx(), whist_prv, whist_idx, win, totcnt);
macosx_add_create(win, macwins[i].level);
if (curr & is_mapped) {
fprintf(stderr, "MapNotify: %d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, macwins[i].level, 1);
}
}
if (whist_skip) {
;
} else if (nv >= NBMAX) {
;
} else if (!(curr & is_mapped)) {
;
} else if (!(prev & is_mapped)) {
if (1) {
;
} else if (curr & is_clipped) {
fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 1;
} else {
fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 0;
}
} else {
if ( !(prev & is_clipped) && (curr & is_clipped) ) {
fprintf(stderr, "VisibNotify: %d/%d %d OBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 1;
} else if ( (prev & is_clipped) && !(curr & is_clipped) ) {
fprintf(stderr, "VisibNotify: %d/%d %d UNOBS tot=%d\n", prev, curr, win, totcnt);
nv_win[nv] = win;
nv_lvl[nv] = macwins[i].level;
nv_vis[nv++] = 0;
}
}
}
for (i=0; i < maxwin; i++) {
char prev, curr;
int win = i;
int q = qlook[i];
int lvl = 0;
if (whist_skip) {
break;
}
if (q >= 0) {
lvl = macwins[q].level;
}
curr = whist[whist_idx][win];
prev = whist[whist_prv][win];
if (!(curr & is_exist) && (prev & is_exist)) {
if (prev & is_mapped) {
fprintf(stderr, "UnmapNotify: %d/%d %d %.4f B tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_mapnotify(win, lvl, 0);
}
/* DestroyNotify */
fprintf(stderr, "DestroNotify:%d/%d %d %.4f tot=%d\n", prev, curr, win, dnowx(), totcnt);
macosx_add_destroy(win, lvl);
}
}
if (nv) {
int k;
for (k = 0; k < nv; k++) {
macosx_add_visnotify(nv_win[k], nv_lvl[k], nv_vis[k]);
}
}
}
}
#if 1

@ -4,7 +4,9 @@
/* -- macosxCGS.h -- */
extern void macosxCGS_get_all_windows(void);
extern int macosxCGS_get_qlook(int);
extern void macosxGCS_set_pasteboard(char *str, int len);
extern int macosxCGS_follow_animation_win(int win, int idx, int grow);
#endif /* _X11VNC_MACOSXCGS_H */

@ -137,6 +137,7 @@ int macosx_mouse_wheel_speed = 5;
int macosx_console = 0;
int macosx_swap23 = 1;
int macosx_resize = 1;
int macosx_icon_anim_time = 450;
unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0;
@ -195,6 +196,13 @@ int wireframe_local = 1;
int ncache = 0;
int ncache0 = 0;
int ncache_copyrect = 0;
int macosx_ncache_macmenu = 0;
#ifdef MACOSX
int ncache_pad = 24;
#else
int ncache_pad = 0;
#endif
/* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
char *scroll_copyrect_str = NULL;

@ -112,6 +112,7 @@ extern int macosx_mouse_wheel_speed;
extern int macosx_console;
extern int macosx_swap23;
extern int macosx_resize;
extern int macosx_icon_anim_time;
extern unsigned long subwin;
extern int subwin_wait_mapped;
@ -157,6 +158,9 @@ extern int wireframe_in_progress;
extern int ncache;
extern int ncache0;
extern int ncache_copyrect;
extern int ncache_pad;
extern int macosx_ncache_macmenu;
extern char *scroll_copyrect_str;
extern char *scroll_copyrect;

@ -816,7 +816,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
}
if (debug_pointer) {
rfbLog("pointer(): sending event %d %.4f\n",
i+1, dnow() - x11vnc_start);
i+1, dnowx());
}
if (ev[i][1] >= 0) {
update_x11_pointer_position(ev[i][1], ev[i][2]);
@ -836,7 +836,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
if (mask < 0) {
if (debug_pointer) {
rfbLog("pointer(): calling XFlush "
"%.4f\n", dnow() - x11vnc_start);
"%.4f\n", dnowx());
}
X_LOCK;
XFlush_wr(dpy);
@ -853,7 +853,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
if (mask < 0) { /* -1 just means flush the event queue */
if (debug_pointer) {
rfbLog("pointer(): flush only. %.4f\n",
dnow() - x11vnc_start);
dnowx());
}
return;
}
@ -885,7 +885,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
} else if (buffer_it) {
if (debug_pointer) {
rfbLog("pointer(): calling XFlush+"
"%.4f\n", dnow() - x11vnc_start);
"%.4f\n", dnowx());
}
X_LOCK;
XFlush_wr(dpy);

@ -765,26 +765,13 @@ char *process_remote_cmd(char *cmd, int stringonly) {
sraRegionPtr r;
rfbLog("rfbDoCopyRect(screen, %d, %d, %d, %d, %d, %d)\n", x, y, x+w, y+h, dx, dy);
r = sraRgnCreateRect(x, y, x+w, y+h);
do_copyregion(r, dx, dy);
do_copyregion(r, dx, dy, 0);
fb_push();
sraRgnDestroy(r);
rfbLog("did\n");
} else {
rfbLog("remote_cmd: bad CR string: %s\n", p);
}
} else if (strstr(p, "ncache") == p) { /* skip-cmd-list */
COLON_CHECK("ncache:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, ncache);
goto qry;
}
p += strlen("ncache:");
ncache = atoi(p);
if (ncache % 2 != 0) {
ncache++;
}
rfbLog("remote_cmd: set -ncache %d\n", ncache);
} else if (!strcmp(p, "stop") || !strcmp(p, "quit") ||
!strcmp(p, "exit") || !strcmp(p, "shutdown")) {
NOTAPP
@ -2746,6 +2733,54 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: enabling mouse nodragging mode.\n");
show_dragging = 0;
} else if (!strcmp(p, "ncache_cr")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, ncache_copyrect);
goto qry;
}
ncache_copyrect = 1;
rfbLog("remote_cmd: set -ncache_cr %d\n", ncache_copyrect);
} else if (!strcmp(p, "noncache_cr")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !ncache_copyrect);
goto qry;
}
ncache_copyrect = 0;
rfbLog("remote_cmd: disabled -ncache_cr %d\n", ncache_copyrect);
} else if (!strcmp(p, "ncache")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !!ncache);
goto qry;
}
ncache = ncache0;
rfbLog("remote_cmd: set ncache %d\n", ncache);
} else if (!strcmp(p, "noncache")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !ncache);
goto qry;
}
ncache = 0;
rfbLog("remote_cmd: disabled ncache %d\n", ncache);
} else if (strstr(p, "ncache_size") == p) {
int orig = ncache, n;
COLON_CHECK("ncache_size:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, ncache);
goto qry;
}
p += strlen("ncache_size:");
n = atoi(p);
if (n >= 0 && n != ncache) {
rfbLog("remote_cmd: setting ncache %d to: %d\n", orig, ncache);
ncache = n;
do_new_fb(1);
if (client_count) {
check_ncache(1,0);
}
}
} else if (strstr(p, "wireframe_mode") == p) {
COLON_CHECK("wireframe_mode:")
if (query) {
@ -3960,13 +3995,84 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
rfbLog("remote_cmd: turn on macnosaver.\n");
macosx_noscreensaver = 1;
} else if (!strcmp(p, "macsaver")) {
} else if (!strcmp(p, "macsaver") || !strcmp(p, "nomacnosaver")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_noscreensaver); goto qry;
}
rfbLog("remote_cmd: turn off macnosaver.\n");
macosx_noscreensaver = 0;
} else if (!strcmp(p, "macnowait")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_wait_for_switch); goto qry;
}
rfbLog("remote_cmd: disable macosx_wait_for_switch.\n");
macosx_wait_for_switch = 0;
} else if (!strcmp(p, "macwait") || !strcmp(p, "nomacnowait")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, macosx_wait_for_switch); goto qry;
}
rfbLog("remote_cmd: enable macosx_wait_for_switch.\n");
macosx_wait_for_switch = 1;
} else if (strstr(p, "macwheel") == p) {
COLON_CHECK("macwheel:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, macosx_mouse_wheel_speed);
goto qry;
}
p += strlen("macwheel:");
macosx_mouse_wheel_speed = atoi(p);
rfbLog("set macosx_mouse_wheel_speed to: %d\n", macosx_mouse_wheel_speed);
} else if (!strcmp(p, "macnoswap")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_swap23); goto qry;
}
rfbLog("remote_cmd: disable macosx_swap23.\n");
macosx_swap23 = 0;
} else if (!strcmp(p, "macswap") || !strcmp(p, "nomacnoswap")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, macosx_swap23); goto qry;
}
rfbLog("remote_cmd: enable macosx_swap23.\n");
macosx_swap23 = 1;
} else if (!strcmp(p, "macnoresize")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_resize); goto qry;
}
rfbLog("remote_cmd: disable macosx_resize.\n");
macosx_resize = 0;
} else if (!strcmp(p, "macresize") || !strcmp(p, "nomacnoresize")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, macosx_resize); goto qry;
}
rfbLog("remote_cmd: enable macosx_resize.\n");
macosx_resize = 1;
} else if (strstr(p, "maciconanim") == p) {
COLON_CHECK("maciconanim:")
if (query) {
snprintf(buf, bufn, "ans=%s%s%d", p, co, macosx_icon_anim_time);
goto qry;
}
p += strlen("maciconanim:");
macosx_icon_anim_time = atoi(p);
rfbLog("set macosx_icon_anim_time to: %d\n", macosx_icon_anim_time);
} else if (!strcmp(p, "macmenu")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, macosx_ncache_macmenu); goto qry;
}
rfbLog("remote_cmd: enable macosx_ncache_macmenu.\n");
macosx_ncache_macmenu = 1;
} else if (!strcmp(p, "macnomenu") || !strcmp(p, "nomacmenu")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_ncache_macmenu); goto qry;
}
rfbLog("remote_cmd: disable macosx_ncache_macmenu.\n");
macosx_ncache_macmenu = 0;
} else if (strstr(p, "hack") == p) { /* skip-cmd-list */
COLON_CHECK("hack:")

@ -26,7 +26,7 @@ void initialize_polling_images(void);
void scale_rect(double factor, int blend, int interpolate, int Bpp,
char *src_fb, int src_bytes_per_line, char *dst_fb, int dst_bytes_per_line,
int Nx, int Ny, int nx, int ny, int X1, int Y1, int X2, int Y2, int mark);
void scale_and_mark_rect(int X1, int Y1, int X2, int Y2);
void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark);
void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force);
int copy_screen(void);
int copy_snap(void);
@ -1253,7 +1253,7 @@ some aliases:
-90: +270, 270
*/
void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark) {
char *dst_fb, *src_fb = main_fb;
int dst_bpl, Bpp = bpp/8, fac = 1;
@ -1290,7 +1290,7 @@ void scale_and_mark_rect(int X1, int Y1, int X2, int Y2) {
scale_rect(scale_fac, scaling_blend, scaling_interpolate, fac * Bpp,
src_fb, fac * main_bytes_per_line, dst_fb, dst_bpl, dpy_x, dpy_y,
scaled_x, scaled_y, X1, Y1, X2, Y2, 1);
scaled_x, scaled_y, X1, Y1, X2, Y2, mark);
}
void rotate_coords(int x, int y, int *xo, int *yo, int dxi, int dyi) {
@ -1308,6 +1308,8 @@ void rotate_coords(int x, int y, int *xo, int *yo, int dxi, int dyi) {
Dy = dpy_y;
}
/* ncache?? */
if (rotating == ROTATE_NONE) {
*xo = xi;
*yo = yi;
@ -1625,7 +1627,7 @@ void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force) {
}
if (scaling) {
scale_and_mark_rect(x1, y1, x2, y2);
scale_and_mark_rect(x1, y1, x2, y2, 1);
} else {
mark_wrapper(x1, y1, x2, y2);
}
@ -2537,6 +2539,48 @@ if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - st
}
/*
* debugging: print out a picture of the tiles.
*/
static void print_tiles(void) {
/* hack for viewing tile diffs on the screen. */
static char *prev = NULL;
int n, x, y, ms = 1500;
ms = 1;
if (! prev) {
prev = (char *) malloc((size_t) ntiles);
for (n=0; n < ntiles; n++) {
prev[n] = 0;
}
}
fprintf(stderr, " ");
for (x=0; x < ntiles_x; x++) {
fprintf(stderr, "%1d", x % 10);
}
fprintf(stderr, "\n");
n = 0;
for (y=0; y < ntiles_y; y++) {
fprintf(stderr, "%2d ", y);
for (x=0; x < ntiles_x; x++) {
if (tile_has_diff[n]) {
fprintf(stderr, "X");
} else if (prev[n]) {
fprintf(stderr, "o");
} else {
fprintf(stderr, ".");
}
n++;
}
fprintf(stderr, "\n");
}
for (n=0; n < ntiles; n++) {
prev[n] = tile_has_diff[n];
}
usleep(ms * 1000);
}
/*
* Utilities for managing the "naps" to cut down on amount of polling.
*/
@ -2818,27 +2862,42 @@ static int scan_display(int ystart, int rescan) {
X_LOCK;
#ifndef NO_NCACHE
#if !NO_X11
if (ncache > 0 && dpy) {
/* XXX watch for problems. */
/* XXX Y test */
if (ncache > 0) {
XEvent ev;
int gotone = 0;
if (XCheckTypedEvent(dpy, MapNotify, &ev)) {
gotone = 1;
} else if (XCheckTypedEvent(dpy, UnmapNotify, &ev)) {
gotone = 2;
} else if (XCheckTypedEvent(dpy, CreateNotify, &ev)) {
gotone = 3;
if (macosx_console) {
if (macosx_checkevent(NULL)) {
gotone = 1;
}
} else {
#if !NO_X11
if (XCheckTypedEvent(dpy, MapNotify, &ev)) {
gotone = 1;
} else if (XCheckTypedEvent(dpy, UnmapNotify, &ev)) {
gotone = 2;
} else if (XCheckTypedEvent(dpy, CreateNotify, &ev)) {
gotone = 3;
}
if (gotone) {
XPutBackEvent(dpy, &ev);
}
#endif
}
if (gotone) {
XPutBackEvent(dpy, &ev);
static int nomsg = 1;
if (nomsg) {
if (dnowx() > 20) {
nomsg = 0;
}
} else {
fprintf(stderr, "*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d rescan=%d\n", gotone, y, rescan);
}
X_UNLOCK;
fprintf(stderr, "*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d\n", gotone, y);
check_ncache(0);
check_ncache(0, 1);
X_LOCK;
}
}
#endif
#endif
XRANDR_SET_TRAP_RET(-1, "scan_display-set");
@ -2936,6 +2995,7 @@ int scan_for_updates(int count_only) {
double frac2 = 0.35; /* or 3rd */
double frac3 = 0.02; /* do scan_display() again after copy_tiles() */
static double last_poll = 0.0;
double dtmp;
if (unixpw_in_progress) return 0;
@ -3007,6 +3067,7 @@ int scan_for_updates(int count_only) {
/* scan with the initial y to the jitter value from scanlines: */
scan_in_progress = 1;
tile_count = scan_display(scanlines[scan_count], 0);
//if (tile_count) fprintf(stderr, "XX tile_countA: %d\n", tile_count);
SCAN_FATAL(tile_count);
/*
@ -3069,12 +3130,14 @@ int scan_for_updates(int count_only) {
cp = (NSCAN - scan_count) % NSCAN;
tile_count = scan_display(scanlines[cp], 1);
//fprintf(stderr, "XX tile_countB: %d\n", tile_count);
SCAN_FATAL(tile_count);
if (tile_count >= (1 + frac2) * tile_count_old) {
/* on a roll... do a 3rd scan */
cp = (NSCAN - scan_count + 7) % NSCAN;
tile_count = scan_display(scanlines[cp], 1);
//fprintf(stderr, "XX tile_countC: %d\n", tile_count);
SCAN_FATAL(tile_count);
}
}
@ -3127,6 +3190,9 @@ int scan_for_updates(int count_only) {
}
if (unixpw_in_progress) return 0;
/* XXX Y */
if (0 && tile_count > 20) print_tiles();
//dtmp = dnow();
if (old_copy_tile) {
tile_diffs = copy_all_tiles();
@ -3134,6 +3200,7 @@ int scan_for_updates(int count_only) {
tile_diffs = copy_all_tile_runs();
}
SCAN_FATAL(tile_diffs);
//if (tile_count) fprintf(stderr, "XX copytile: %.4f tile_count: %d\n", dnow() - dtmp, tile_count);
/*
* This backward pass for upward and left tiles complements what

@ -14,7 +14,7 @@ extern void initialize_polling_images(void);
extern void scale_rect(double factor, int blend, int interpolate, int Bpp,
char *src_fb, int src_bytes_per_line, char *dst_fb, int dst_bytes_per_line,
int Nx, int Ny, int nx, int ny, int X1, int Y1, int X2, int Y2, int mark);
extern void scale_and_mark_rect(int X1, int Y1, int X2, int Y2);
extern void scale_and_mark_rect(int X1, int Y1, int X2, int Y2, int mark);
extern void mark_rect_as_modified(int x1, int y1, int x2, int y2, int force);
extern int copy_screen(void);
extern int copy_snap(void);

@ -701,6 +701,7 @@ void free_old_fb(void) {
void do_new_fb(int reset_mem) {
XImage *fb;
int i;
/* for threaded we really should lock libvncserver out. */
if (use_threads) {
@ -725,7 +726,6 @@ void do_new_fb(int reset_mem) {
initialize_blackouts_and_xinerama();
initialize_polling_images();
}
}
static void remove_fake_fb(void) {
@ -2035,18 +2035,25 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
#ifndef NO_NCACHE
if (ncache > 0) {
char *new_fb;
int sz = fb->height * fb->bytes_per_line;
new_fb = (char *) calloc((size_t) (sz * (1+ncache)), 1);
if (fb->data) {
memcpy(new_fb, fb->data, sz);
free(fb->data);
}
fb->data = new_fb;
fb->height *= (1+ncache);
height *= (1+ncache);
ncache0 = ncache;
#ifdef MACOSX
if (! raw_fb_str || macosx_console) {
#else
if (! raw_fb_str) {
#endif
char *new_fb;
int sz = fb->height * fb->bytes_per_line;
new_fb = (char *) calloc((size_t) (sz * (1+ncache)), 1);
if (fb->data) {
memcpy(new_fb, fb->data, sz);
free(fb->data);
}
fb->data = new_fb;
fb->height *= (1+ncache);
height *= (1+ncache);
ncache0 = ncache;
}
}
#endif

@ -240,6 +240,15 @@ Misc
xrecord
=RQA reset_record
=GAL LOFF
=GAL MacOSX::
macnosaver
macnowait
macwheel:
macnoswap
macnoresize
maciconanim:
macmenu
=GAL LOFF
--
nofb
=D nobell
@ -370,7 +379,12 @@ Tuning
threads
wmdt:
rfbwait:
nodpms
nofbpm
--
ncache
ncache_size:
ncache_cr
=GAL LOFF
"
}

@ -251,6 +251,15 @@ char gui_code[] = "";
" xrecord\n"
" =RQA reset_record\n"
" =GAL LOFF\n"
" =GAL MacOSX::\n"
" macnosaver\n"
" macnowait\n"
" macwheel:\n"
" macnoswap\n"
" macnoresize\n"
" maciconanim:\n"
" macmenu\n"
" =GAL LOFF\n"
" --\n"
" nofb\n"
" =D nobell\n"
@ -381,7 +390,12 @@ char gui_code[] = "";
" threads\n"
" wmdt:\n"
" rfbwait:\n"
" nodpms\n"
" nofbpm\n"
" --\n"
" ncache\n"
" ncache_size:\n"
" ncache_cr\n"
" =GAL LOFF\n"
"\"\n"
"}\n"

File diff suppressed because it is too large Load Diff

@ -21,7 +21,7 @@ extern void initialize_max_keyrepeat(void);
extern int direct_fb_copy(int x1, int y1, int x2, int y2, int mark);
extern void fb_push(void);
extern void fb_push_wait(double max_wait, int flags);
extern int fb_push_wait(double max_wait, int flags);
extern void eat_viewonly_input(int max_eat, int keep);
extern void mark_for_xdamage(int x, int y, int w, int h);
@ -35,6 +35,6 @@ extern int check_xrecord(void);
extern int check_wireframe(void);
extern int fb_update_sent(int *count);
extern int check_user_input(double dt, double dtr, int tile_diffs, int *cnt);
extern void do_copyregion(sraRegionPtr region, int dx, int dy);
extern void do_copyregion(sraRegionPtr region, int dx, int dy, int mode);
#endif /* _X11VNC_USERINPUT_H */

@ -19,7 +19,13 @@ typedef struct winattr {
double su_time;
int bs_x, bs_y, bs_w, bs_h;
int su_x, su_y, su_w, su_h;
int selectinput;
Window above;
short vis_state;
short selectinput;
short map_cnt;
short unmap_cnt;
short vis_cnt;
short create_cnt;
} winattr_t;
#endif /* _X11VNC_WINATTR_T_H */

@ -2,7 +2,7 @@
.TH X11VNC "1" "December 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.4, lastmod: 2006-12-17
version: 0.8.4, lastmod: 2006-12-28
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -2391,16 +2391,52 @@ will have to set things up so you can't see that region.
If this method is successful, the changes required for
clients to do this less awkwardly will be investigated.
.IP
Note that this mode consumes a lot of memory, both
on the x11vnc server side and on the VNC Viewer side.
If n=2 then the amount of RAM used is roughly tripled
for both x11vnc and the VNC Viewer. As a rule of
thumb, note that 1280x1024 at depth 24 is about 5MB of
pixel data.
Note that this mode consumes a huge amount of memory,
both on the x11vnc server side and on the VNC Viewer
side. If n=2 then the amount of RAM used is roughly
tripled for both x11vnc and the VNC Viewer. As a rule
of thumb, note that 1280x1024 at depth 24 is about 5MB
of pixel data.
.IP
For reasonable response when cycling through 4 to 6
large (e.g. web browser) windows a value n of 6 to 12
is recommended. (that's right: ~10X more memory...)
.IP
Because of the way window backingstore and saveunders
are implemented, n must be even. It will be incremented
by 1 if it is not.
.IP
This mode also works for native MacOS X, but may not
be as effective as the X version. This is due to a
number of things, one is the drop-shadow compositing
that leaves extra areas that need to be repaired (see
\fB-ncache_pad).\fR Another is the window iconification
animations need to be avoided (see \fB-macicontime).\fR
It appears the that the 'Scale' animation mode gives
better results than the 'Genie' one. Also, window event
detection not as accurate as the X version.
.PP
\fB-ncache_cr\fR
.IP
In \fB-nache\fR mode, try do to copyrect opaque window
moves/drags instead of wireframes (this can induce
painting errors). The wireframe will still be used when
moving a window whose save-unders has not yet been set
or has been invalidated.
.IP
Some VNC Viewers provide better response than others
with this option. On Unix, realvnc viewer gives
smoother drags than tightvnc viewer. Response may also
be choppy if the server side machine is too slow.
.PP
\fB-ncache_pad\fR \fIn\fR
.IP
In \fB-nache\fR mode, pad each window with n pixels for the
caching rectangles. This can be used to try to improve
the situation with dropshadows or other compositing
(e.g. MacOS X window manager), although it could make
things worse. The default is 0 on Unix and 24 on
MacOS X.
.PP
\fB-wireframe\fR \fI[str],\fR \fB-nowireframe\fR
.IP
@ -3498,6 +3534,19 @@ For the native Mac OS X server, do not resize or reset
the framebuffer even if it is detected that the screen
resolution or depth has changed.
.PP
\fB-maciconanim\fR \fIn\fR
.IP
For the native Mac OS X server, set n to the number
of milliseconds that the window iconify/deiconify
animation takes. In \fB-ncache\fR mode this value will be
used to skip the animation if possible. (default 400)
.PP
\fB-macmenu\fR
.IP
For the native Mac OS X server, in \fB-ncache\fR client-side
caching mode, try to cache pull down menus (not perfect
because they have animated fades, etc.)
.PP
\fB-gui\fR \fI[gui-opts]\fR
.IP
Start up a simple tcl/tk gui based on the the remote
@ -3942,6 +3991,16 @@ dragging disable \fB-nodragging\fR mode.
.IP
nodragging enable \fB-nodragging\fR mode.
.IP
ncache reenable \fB-ncache\fR mode.
.IP
noncache disable \fB-ncache\fR mode.
.IP
ncache_size:n set \fB-ncache\fR size to n.
.IP
ncache_cr enable \fB-ncache_cr\fR mode.
.IP
noncache_cr disable \fB-ncache_cr\fR mode.
.IP
wireframe enable \fB-wireframe\fR mode. same as "wf"
.IP
nowireframe disable \fB-wireframe\fR mode. same as "nowf"
@ -4071,6 +4130,26 @@ macnosaver enable \fB-macnosaver\fR mode.
.IP
macsaver disable \fB-macnosaver\fR mode.
.IP
macnowait enable \fB-macnowait\fR mode.
.IP
macwait disable \fB-macnowait\fR mode.
.IP
macwheel:n set \fB-macwheel\fR to n.
.IP
macnoswap enable \fB-macnoswap\fR mouse button mode.
.IP
macswap disable \fB-macnoswap\fR mouse button mode.
.IP
macnoresize enable \fB-macnoresize\fR mode.
.IP
macresize disable \fB-macnoresize\fR mode.
.IP
maciconanim:n set \fB-maciconanim\fR to n.
.IP
macmenu enable \fB-macmenu\fR mode.
.IP
macnomenu disable \fB-macnmenu\fR mode.
.IP
httpport:n set \fB-httpport\fR to n.
.IP
httpdir:dir set \fB-httpdir\fR to dir (and enable http).
@ -4203,7 +4282,8 @@ show_cursor noshow_cursor nocursor arrow xfixes noxfixes
xdamage noxdamage xd_area xd_mem alphacut alphafrac
alpharemove noalpharemove alphablend noalphablend
xwarppointer xwarp noxwarppointer noxwarp buttonmap
dragging nodragging wireframe_mode wireframe wf
dragging nodragging ncache_cr noncache_cr ncache
noncache ncache_size wireframe_mode wireframe wf
nowireframe nowf wireframelocal wfl nowireframelocal
nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area
scr_skip scr_inc scr_keys scr_term scr_keyrepeat
@ -4226,7 +4306,10 @@ debug_xdamage debug_wireframe nodebug_wireframe
debug_wireframe debug_scroll nodebug_scroll debug_scroll
debug_tiles dbt nodebug_tiles nodbt debug_tiles
debug_grabs nodebug_grabs debug_sel nodebug_sel dbg
nodbg macnosaver macsaver noremote
nodbg macnosaver macsaver nomacnosaver macnowait macwait
nomacnowait macwheel macnoswap macswap nomacnoswap
macnoresize macresize nomacnoresize maciconanim macmenu
macnomenu nomacmenu noremote
.IP
aro= noop display vncdisplay desktopname guess_desktop
http_url auth xauth users rootshift clipshift

@ -329,7 +329,7 @@ static int choose_delay(double dt) {
}
dts[ndt-1] = dt;
if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnow() - x11vnc_start);
if (0 && dt > 0.0) fprintf(stderr, "dt: %.5f %.4f\n", dt, dnowx());
if (bogdown) {
if (use_xdamage) {
/* DAMAGE can queue ~1000 rectangles for a scroll */
@ -554,7 +554,7 @@ static void watch_loop(void) {
}
check_new_clients();
check_ncache();
check_ncache(0, 0);
check_xevents(0);
check_autorepeat();
check_pm();
@ -2115,6 +2115,11 @@ int main(int argc, char* argv[]) {
if (ncache % 2 != 0) {
ncache++;
}
} else if (!strcmp(arg, "-ncache_cr")) {
ncache_copyrect = 1;
} else if (!strcmp(arg, "-ncache_pad")) {
CHECK_ARGC
ncache_pad = atoi(argv[++i]);
#endif
} else if (!strcmp(arg, "-wireframe")
|| !strcmp(arg, "-wf")) {
@ -2335,6 +2340,11 @@ int main(int argc, char* argv[]) {
macosx_swap23 = 0;
} else if (!strcmp(arg, "-macnoresize")) {
macosx_resize = 0;
} else if (!strcmp(arg, "-maciconanim")) {
CHECK_ARGC
macosx_icon_anim_time = atoi(argv[++i]);
} else if (!strcmp(arg, "-macmenu")) {
macosx_ncache_macmenu = 1;
} else if (!strcmp(arg, "-gui")) {
launch_gui = 1;
if (i < argc-1) {
@ -3094,8 +3104,7 @@ int main(int argc, char* argv[]) {
if (priv_remote) {
if (! remote_control_access_ok()) {
rfbLog("** Disabling remote commands in -privremote "
"mode.\n");
rfbLog("** Disabling remote commands in -privremote mode.\n");
accept_remote_cmds = 0;
}
}
@ -3108,8 +3117,7 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
if (! XFixesQueryExtension(dpy, &xfixes_base_event_type, &er)) {
if (! quiet && ! raw_fb_str) {
rfbLog("Disabling XFIXES mode: display does not "
"support it.\n");
rfbLog("Disabling XFIXES mode: display does not support it.\n");
}
xfixes_base_event_type = 0;
xfixes_present = 0;
@ -3124,8 +3132,7 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if (! XDamageQueryExtension(dpy, &xdamage_base_event_type, &er)) {
if (! quiet && ! raw_fb_str) {
rfbLog("Disabling X DAMAGE mode: display does not "
"support it.\n");
rfbLog("Disabling X DAMAGE mode: display does not support it.\n");
}
xdamage_base_event_type = 0;
xdamage_present = 0;
@ -3137,31 +3144,24 @@ int main(int argc, char* argv[]) {
use_xdamage = 0;
}
if (! quiet && xdamage_present && use_xdamage && ! raw_fb_str) {
rfbLog("X DAMAGE available on display, using it for"
" polling hints.\n");
rfbLog(" To disable this behavior use: "
"'-noxdamage'\n");
rfbLog("X DAMAGE available on display, using it for polling hints.\n");
rfbLog(" To disable this behavior use: '-noxdamage'\n");
}
if (! quiet && wireframe && ! raw_fb_str) {
rfbLog("Wireframing: -wireframe mode is in effect for window "
"moves.\n");
rfbLog(" If this yields undesired behavior (poor response, "
"painting\n");
rfbLog("\n");
rfbLog("Wireframing: -wireframe mode is in effect for window moves.\n");
rfbLog(" If this yields undesired behavior (poor response, painting\n");
rfbLog(" errors, etc) it may be disabled:\n");
rfbLog(" - use '-nowf' to disable wireframing completely.\n");
rfbLog(" - use '-nowcr' to disable the Copy Rectangle after "
"the\n");
rfbLog(" - use '-nowcr' to disable the Copy Rectangle after the\n");
rfbLog(" moved window is released in the new position.\n");
rfbLog(" Also see the -help entry for tuning parameters.\n");
rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row"
" to \n");
rfbLog(" repaint the screen, also see the -fixscreen option"
" for\n");
rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
rfbLog(" repaint the screen, also see the -fixscreen option for\n");
rfbLog(" periodic repaints.\n");
if (scale_str && !strstr(scale_str, "nocr")) {
rfbLog(" Note: '-scale' is on and this can cause "
"more problems.\n");
rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
}
}
@ -3169,8 +3169,7 @@ int main(int argc, char* argv[]) {
#if defined(SOLARIS_OVERLAY) && !NO_X11
if (! XQueryExtension(dpy, "SUN_OVL", &maj, &ev, &er)) {
if (! quiet && overlay && ! raw_fb_str) {
rfbLog("Disabling -overlay: SUN_OVL "
"extension not available.\n");
rfbLog("Disabling -overlay: SUN_OVL extension not available.\n");
}
} else {
overlay_present = 1;
@ -3179,8 +3178,7 @@ int main(int argc, char* argv[]) {
#if defined(IRIX_OVERLAY) && !NO_X11
if (! XReadDisplayQueryExtension(dpy, &ev, &er)) {
if (! quiet && overlay && ! raw_fb_str) {
rfbLog("Disabling -overlay: IRIX ReadDisplay "
"extension not available.\n");
rfbLog("Disabling -overlay: IRIX ReadDisplay extension not available.\n");
}
} else {
overlay_present = 1;
@ -3202,11 +3200,9 @@ int main(int argc, char* argv[]) {
multiple_cursors_mode = strdup("most");
if (! quiet && ! raw_fb_str) {
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 disable this behavior use: "
"'-cursor arrow'\n");
rfbLog(" to disable this behavior use: '-cursor arrow'\n");
rfbLog(" or '-noxfixes'.\n");
}
}
@ -3214,8 +3210,7 @@ int main(int argc, char* argv[]) {
if (xfixes_present && use_xfixes &&
overlay_cursor == 1) {
if (! quiet && ! raw_fb_str) {
rfbLog("using XFIXES for cursor "
"drawing.\n");
rfbLog("using XFIXES for cursor drawing.\n");
}
overlay_cursor = 0;
}
@ -3225,8 +3220,7 @@ int main(int argc, char* argv[]) {
if (overlay) {
using_shm = 0;
if (flash_cmap && ! quiet && ! raw_fb_str) {
rfbLog("warning: -flashcmap may be "
"incompatible with -overlay\n");
rfbLog("warning: -flashcmap may be incompatible with -overlay\n");
}
if (show_cursor && overlay_cursor) {
char *s = multiple_cursors_mode;
@ -3252,19 +3246,14 @@ int main(int argc, char* argv[]) {
/* check for XTEST */
if (! XTestQueryExtension_wr(dpy, &ev, &er, &maj, &min)) {
if (! quiet && ! raw_fb_str) {
rfbLog("WARNING: XTEST extension not available "
"(either missing from\n");
rfbLog(" display or client library libXtst "
"missing at build time).\n");
rfbLog(" MOST user input (pointer and keyboard) "
"will be DISCARDED.\n");
rfbLog(" If display does have XTEST, be sure to "
"build x11vnc with\n");
rfbLog(" a working libXtst build environment "
"(e.g. libxtst-dev,\n");
rfbLog("\n");
rfbLog("WARNING: XTEST extension not available (either missing from\n");
rfbLog(" display or client library libXtst missing at build time).\n");
rfbLog(" MOST user input (pointer and keyboard) will be DISCARDED.\n");
rfbLog(" If display does have XTEST, be sure to build x11vnc with\n");
rfbLog(" a working libXtst build environment (e.g. libxtst-dev,\n");
rfbLog(" or other packages).\n");
rfbLog("No XTEST extension, switching to "
"-xwarppointer mode for\n");
rfbLog("No XTEST extension, switching to -xwarppointer mode for\n");
rfbLog(" pointer motion input.\n");
}
xtest_present = 0;
@ -3297,6 +3286,7 @@ int main(int argc, char* argv[]) {
if (! XRecordQueryVersion_wr(dpy, &maj, &min)) {
xrecord_present = 0;
if (! quiet) {
rfbLog("\n");
rfbLog("The RECORD X extension was not found on the display.\n");
rfbLog("If your system has disabled it by default, you can\n");
rfbLog("enable it to get a nice x11vnc performance speedup\n");
@ -3333,23 +3323,39 @@ int main(int argc, char* argv[]) {
tmpi = 0;
#endif
if (! quiet && tmpi && ! raw_fb_str) {
rfbLog("Scroll Detection: -scrollcopyrect mode is in effect "
"to\n");
rfbLog(" use RECORD extension to try to detect scrolling "
"windows\n");
rfbLog("\n");
rfbLog("Scroll Detection: -scrollcopyrect mode is in effect to\n");
rfbLog(" use RECORD extension to try to detect scrolling windows\n");
rfbLog(" (induced by either user keystroke or mouse input).\n");
rfbLog(" If this yields undesired behavior (poor response, "
"painting\n");
rfbLog(" If this yields undesired behavior (poor response, painting\n");
rfbLog(" errors, etc) it may be disabled via: '-noscr'\n");
rfbLog(" Also see the -help entry for tuning parameters.\n");
rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row"
" to \n");
rfbLog(" repaint the screen, also see the -fixscreen option"
" for\n");
rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
rfbLog(" repaint the screen, also see the -fixscreen option for\n");
rfbLog(" periodic repaints.\n");
if (scale_str && !strstr(scale_str, "nocr")) {
rfbLog(" Note: '-scale' is on and this can cause "
"more problems.\n");
rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
}
}
if (! quiet && ncache && ! raw_fb_str) {
rfbLog("\n");
rfbLog("Client Side Caching: -ncache mode is in effect to provide\n");
rfbLog(" some client-side pixel data caching. This speeds up\n");
rfbLog(" iconifying/deiconifying windows, moving and raising\n");
rfbLog(" windows, and reposting menus. In the simple CopyRect\n");
rfbLog(" encoding scheme used (no compression) a huge amount\n");
rfbLog(" of extra memory (20-80MB) is used on both the server and\n");
rfbLog(" client sides. This mode works with any VNC viewer,\n");
rfbLog(" however in most you can actually see the cached pixel\n");
rfbLog(" data by scrolling down, so you need to re-adjust its size.\n");
rfbLog(" If this mode yields undesired behavior (poor response,\n");
rfbLog(" painting errors, etc) it may be disabled via: '-ncache 0'\n");
rfbLog(" You can press 3 Alt_L's (Left \"Alt\" key) in a row to \n");
rfbLog(" repaint the screen, also see the -fixscreen option for\n");
rfbLog(" periodic repaints.\n");
if (scale_str) {
rfbLog(" Note: '-scale' is on and this can cause more problems.\n");
}
}
@ -3367,16 +3373,14 @@ int main(int argc, char* argv[]) {
xshm_present = 0;
if (! using_shm) {
if (! quiet && ! raw_fb_str) {
rfbLog("info: display does not support"
" XShm.\n");
rfbLog("info: display does not support XShm.\n");
}
} else {
if (! quiet && ! raw_fb_str) {
rfbLog("\n");
rfbLog("warning: XShm extension is not available.\n");
rfbLog("For best performance the X Display should be"
" local. (i.e.\n");
rfbLog("the x11vnc and X server processes should be"
" running on\n");
rfbLog("For best performance the X Display should be local. (i.e.\n");
rfbLog("the x11vnc and X server processes should be running on\n");
rfbLog("the same machine.)\n");
#if LIBVNCSERVER_HAVE_XSHM
rfbLog("Restart with -noshm to override this.\n");
@ -3396,8 +3400,7 @@ int main(int argc, char* argv[]) {
initialize_watch_bell();
if (!xkb_present && use_xkb_modtweak) {
if (! quiet && ! raw_fb_str) {
rfbLog("warning: disabling xkb modtweak."
" XKEYBOARD ext. not present.\n");
rfbLog("warning: disabling xkb modtweak. XKEYBOARD ext. not present.\n");
}
use_xkb_modtweak = 0;
}
@ -3412,8 +3415,7 @@ int main(int argc, char* argv[]) {
#if LIBVNCSERVER_HAVE_LIBXRANDR
if (! XRRQueryExtension(dpy, &xrandr_base_event_type, &er)) {
if (xrandr && ! quiet && ! raw_fb_str) {
rfbLog("Disabling -xrandr mode: display does not"
" support X RANDR.\n");
rfbLog("Disabling -xrandr mode: display does not support X RANDR.\n");
}
xrandr_base_event_type = 0;
xrandr = 0;

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.4 lastmod: 2006-12-17";
char lastmod[] = "0.8.4 lastmod: 2006-12-28";
/* X display info */

@ -108,7 +108,7 @@ static void initialize_xevents(int reset) {
*/
X_LOCK;
xselectinput_rootwin |= PropertyChangeMask;
XSelectInput(dpy, rootwin, xselectinput_rootwin);
XSelectInput_wr(dpy, rootwin, xselectinput_rootwin);
X_UNLOCK;
did_xselect_input = 1;
}

@ -647,7 +647,7 @@ if (db > 1) fprintf(stderr, "record_CA-%d\n", k++);
dt = (dnow() - servertime_diff) - st;
fprintf(stderr, "record_CA-%d *FOUND_SCROLL: src: 0x%lx dx: %d dy: %d "
"x: %d y: %d w: %d h: %d st: %.4f %.4f %.4f\n", k++, src, dx, dy,
src_x, src_y, w, h, st, dt, dnow() - x11vnc_start);
src_x, src_y, w, h, st, dt, dnowx());
}
i = scr_ev_cnt;
@ -1144,7 +1144,7 @@ if (db > 1) fprintf(stderr, "record_CW-%d\n", k++);
dt = (dnow() - servertime_diff) - st;
fprintf(stderr, "record_CW-%d *FOUND_SCROLL: win: 0x%lx dx: %d dy: %d "
"x: %d y: %d w: %d h: %d st: %.4f dt: %.4f %.4f\n", k++, win,
dx, dy, src_x, src_y, w, h, st, dt, dnow() - x11vnc_start);
dx, dy, src_x, src_y, w, h, st, dt, dnowx());
}
i = scr_ev_cnt;
@ -1271,7 +1271,7 @@ static void record_grab(XPointer ptr, XRecordInterceptData *rec_data) {
req = (xReq *) rec_data->data;
if (req->reqType == X_GrabServer) {
double now = dnow() - x11vnc_start;
double now = dnowx();
xserver_grabbed++;
if (db) rfbLog("X server Grabbed: %d %.5f\n", xserver_grabbed, now);
if (xserver_grabbed > 1) {
@ -1282,7 +1282,7 @@ static void record_grab(XPointer ptr, XRecordInterceptData *rec_data) {
xserver_grabbed = 1;
}
} else if (req->reqType == X_UngrabServer) {
double now = dnow() - x11vnc_start;
double now = dnowx();
xserver_grabbed--;
if (xserver_grabbed < 0) {
xserver_grabbed = 0;

@ -80,6 +80,7 @@ Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return);
int XFree_wr(void *data);
int XSelectInput_wr(Display *display, Window w, long event_mask);
void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
static void upup_downdown_warning(KeyCode key, Bool down);
@ -671,7 +672,7 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
}
if (debug_keyboard) {
rfbLog("calling XTestFakeKeyEvent(%d, %d) %.4f\n",
key, down, dnow() - x11vnc_start);
key, down, dnowx());
}
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeKeyEvent(dpy, key, down, delay);
@ -740,7 +741,7 @@ void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
}
if (debug_pointer) {
rfbLog("calling XTestFakeButtonEvent(%d, %d) %.4f\n",
button, is_press, dnow() - x11vnc_start);
button, is_press, dnowx());
}
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeButtonEvent(dpy, button, is_press, delay);
@ -799,7 +800,7 @@ void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
if (debug_pointer) {
rfbLog("calling XTestFakeMotionEvent(%d, %d) %.4f\n",
x, y, dnow() - x11vnc_start);
x, y, dnowx());
}
#if LIBVNCSERVER_HAVE_XTEST
XTestFakeMotionEvent(dpy, screen, x, y, delay);
@ -1081,16 +1082,26 @@ Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
Window *child_return, int *root_x_return, int *root_y_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return) {
Bool rc;
XErrorHandler old_handler;
#if NO_X11
return False;
#else
if (! display) {
return False;
}
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryPointer(display, w, root_return, child_return,
root_x_return, root_y_return, win_x_return, win_y_return,
mask_return);
XSetErrorHandler(old_handler);
if (trapped_xerror) {
rc = 0;
}
if (rc) {
display_button_mask = (*mask_return) & Bmask;
display_mod_mask = (*mask_return) & Mmask;
@ -1146,6 +1157,26 @@ int XFree_wr(void *data) {
#endif
}
int XSelectInput_wr(Display *display, Window w, long event_mask) {
#if NO_X11
return 0;
#else
int rc;
XErrorHandler old_handler;
if (display == NULL || w == None) {
return 0;
}
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XSelectInput(display, w, event_mask);
XSetErrorHandler(old_handler);
if (trapped_xerror) {
rc = 0;
}
return rc;
#endif
}
void nox11_exit(int rc) {
#if NO_X11
rfbLog("This x11vnc was not built with X11 support.\n");

@ -77,6 +77,7 @@ extern Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return);
extern int XFree_wr(void *data);
extern int XSelectInput_wr(Display *display, Window w, long event_mask);
#endif /* _X11VNC_XWRAPPERS_H */

Loading…
Cancel
Save