Thread safety. Fix -clip -in -rawfb. Try to avoid Xorg stuck

key bug.
pull/1/head
runge 15 years ago
parent 804335f9d2
commit 94d058b35f

@ -941,6 +941,7 @@ if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
0, 0);
XSetErrorHandler(old_handler);
X_UNLOCK;
if (! xi_r || trapped_xerror) {
@ -1664,6 +1665,7 @@ if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
ZPixmap, xi, 0, 0);
#endif
XSetErrorHandler(old_handler);
X_UNLOCK;
if (! xi_r || trapped_xerror) {
@ -2100,7 +2102,7 @@ void mark_8bpp(int mode) {
}
if (windows_8bpp[i].map_state != IsViewable) {
XWindowAttributes attr;
int vw;
int vw = 0;
X_LOCK;
vw = valid_window(windows_8bpp[i].win, &attr, 1);

@ -1,3 +1,10 @@
2009-05-21 Karl Runge <runge@karlrunge.com>
* x11vnc: Thread safety improvements. Add 'OpenOffice' to special
case list for scroll detection. Fix -clip mode under -rawfb.
Workaround Xorg bug that yields infinitely repeating keys
when 'xset r off' action is done with keys pressed. Env. var
X11VNC_IDLE_TIMEOUT.
2009-03-12 Karl Runge <runge@karlrunge.com>
* x11vnc: Fix off-screen bug for -ncache_cr copyrect.

File diff suppressed because it is too large Load Diff

@ -80,6 +80,7 @@ void set_x11vnc_remote_prop(char *str);
void read_x11vnc_remote_prop(int);
void check_connect_inputs(void);
void check_gui_inputs(void);
rfbClientPtr create_new_client(int sock, int start_thread);
enum rfbNewClientAction new_client(rfbClientPtr client);
enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client);
rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len);
@ -704,6 +705,8 @@ static int accepted_client = 0;
void client_gone(rfbClientPtr client) {
ClientData *cd = NULL;
CLIENT_LOCK;
client_count--;
if (client_count < 0) client_count = 0;
@ -800,6 +803,7 @@ void client_gone(rfbClientPtr client) {
}
clean_up_exit(0);
}
if (connect_once) {
/*
* This non-exit is done for a bad passwd to be consistent
@ -814,11 +818,13 @@ void client_gone(rfbClientPtr client) {
"disconnect.\n");
rfbLog("connect_once: waiting for next connection.\n");
accepted_client = 0;
CLIENT_UNLOCK;
return;
}
if (shared && client_count > 0) {
rfbLog("connect_once: other shared clients still "
"connected, not exiting.\n");
CLIENT_UNLOCK;
return;
}
@ -827,6 +833,7 @@ void client_gone(rfbClientPtr client) {
rfbLog("killing gui_pid %d\n", gui_pid);
kill(gui_pid, SIGTERM);
}
CLIENT_UNLOCK;
clean_up_exit(0);
}
#ifdef MACOSX
@ -834,6 +841,7 @@ void client_gone(rfbClientPtr client) {
macosxCG_refresh_callback_off();
}
#endif
CLIENT_UNLOCK;
}
/*
@ -2417,7 +2425,7 @@ static int do_reverse_connect(char *str_in) {
write(sock, prestring, prestring_len);
free(prestring);
}
cl = rfbNewClient(screen, sock);
cl = create_new_client(sock, 1);
} else {
return 0;
}
@ -2426,12 +2434,16 @@ static int do_reverse_connect(char *str_in) {
if (sock >= 0) {
write(sock, prestring, prestring_len);
free(prestring);
cl = rfbNewClient(screen, sock);
cl = create_new_client(sock, 1);
} else {
return 0;
}
} else {
cl = rfbReverseConnection(screen, host, rport);
if (cl != NULL && use_threads) {
cl->onHold = FALSE;
rfbStartOnHoldClient(cl);
}
}
free(host);
@ -2846,6 +2858,27 @@ void check_gui_inputs(void) {
}
}
rfbClientPtr create_new_client(int sock, int start_thread) {
rfbClientPtr cl;
if (!screen) {
return NULL;
}
cl = rfbNewClient(screen, sock);
if (cl == NULL) {
return NULL;
}
if (use_threads) {
cl->onHold = FALSE;
if (start_thread) {
rfbStartOnHoldClient(cl);
}
}
return cl;
}
static int turn_off_truecolor = 0;
static void turn_off_truecolor_ad(rfbClientPtr client) {
@ -2925,6 +2958,8 @@ void client_set_net(rfbClientPtr client) {
enum rfbNewClientAction new_client(rfbClientPtr client) {
ClientData *cd;
CLIENT_LOCK;
last_event = last_input = time(NULL);
latest_client = client;
@ -2942,16 +2977,19 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
clients_served++;
if (use_openssl || use_stunnel) {
if (! ssl_initialized) {
rfbLog("denying additional client: %s ssl not setup"
" yet.\n", client->host);
CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
}
if (unixpw_in_progress) {
rfbLog("denying additional client: %s during -unixpw login.\n",
client->host);
CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
if (connect_once) {
@ -2959,13 +2997,16 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
if (! shared && accepted_client) {
rfbLog("denying additional client: %s\n",
client->host);
CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
}
}
if (! check_access(client->host)) {
rfbLog("denying client: %s does not match %s\n", client->host,
allow_list ? allow_list : "(null)" );
CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
@ -2995,6 +3036,7 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
free_client_data(client);
CLIENT_UNLOCK;
return(RFB_CLIENT_REFUSE);
}
@ -3075,6 +3117,8 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
bm--;
}
if (use_threads) LOCK(client->updateMutex);
client->format.trueColour = TRUE;
client->format.redShift = rs;
client->format.greenShift = gs;
@ -3083,6 +3127,8 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
client->format.greenMax = gm;
client->format.blueMax = bm;
if (use_threads) UNLOCK(client->updateMutex);
rfbSetTranslateFunction(client);
screen->serverFormat.trueColour = TRUE;
@ -3124,10 +3170,17 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
rfbLog("new client: %s in non-unixpw_in_rfbPE.\n",
client->host);
}
/* always put client on hold even if unixpw_in_rfbPE is true */
return(RFB_CLIENT_ON_HOLD);
CLIENT_UNLOCK;
if (!use_threads) {
/* always put client on hold even if unixpw_in_rfbPE is true */
return(RFB_CLIENT_ON_HOLD);
} else {
/* unixpw threads is still in testing mode, disabled by default. See UNIXPW_THREADS */
return(RFB_CLIENT_ACCEPT);
}
}
CLIENT_UNLOCK;
return(RFB_CLIENT_ACCEPT);
}

@ -59,6 +59,7 @@ extern void set_x11vnc_remote_prop(char *str);
extern void read_x11vnc_remote_prop(int);
extern void check_connect_inputs(void);
extern void check_gui_inputs(void);
extern rfbClientPtr create_new_client(int sock, int start_thread);
extern enum rfbNewClientAction new_client(rfbClientPtr client);
extern enum rfbNewClientAction new_client_chat_helper(rfbClientPtr client);
extern rfbBool password_check_chat_helper(rfbClientPtr cl, const char* response, int len);

@ -897,8 +897,6 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
RAWFB_RET_VOID
X_LOCK;
if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
nm_info = 0;
}
@ -978,8 +976,6 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
XSetErrorHandler(old_handler);
trapped_xerror = 0;
X_UNLOCK;
*depth = descend;
*w = wins[descend];
#endif /* NO_X11 */
@ -1522,7 +1518,7 @@ int get_which_cursor(void) {
int db = 0;
if (show_multiple_cursors) {
int depth = 0;
int depth = 0, rint;
static win_str_info_t winfo;
static int first = 1, depth_cutoff = -1;
Window win = None;
@ -1550,12 +1546,14 @@ int get_which_cursor(void) {
}
if (rawfb_vnc_reflect && mode > -1) {
return get_exact_cursor(0);
rint = get_exact_cursor(0);
return rint;
}
if (mode == 3) {
if ((xfixes_present && use_xfixes) || macosx_console) {
if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
return get_exact_cursor(0);
rint = get_exact_cursor(0);
return rint;
}
}
@ -1575,7 +1573,9 @@ int get_which_cursor(void) {
}
first = 0;
X_LOCK;
tree_descend_cursor(&depth, &win, &winfo);
X_UNLOCK;
if (depth <= depth_cutoff && !subwin) {
which = CURS_ROOT;
@ -1939,7 +1939,7 @@ int check_x11_pointer(void) {
Window root_w, child_w;
rfbBool ret = 0;
int root_x, root_y, win_x, win_y;
int x, y;
int x, y, rint;
unsigned int mask;
if (unixpw_in_progress) return 0;
@ -2006,6 +2006,7 @@ if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
cursor_position(x, y);
/* change the cursor shape if necessary */
return set_cursor(x, y, get_which_cursor());
rint = set_cursor(x, y, get_which_cursor());
return rint;
}

@ -903,6 +903,9 @@ void print_help(int mode) {
" if [list] starts with the \"%%\" character. See the\n"
" quick_pw() function in the source for details.\n"
"\n"
" Use -nounixpw to disable unixpw mode if it was enabled\n"
" earlier in the cmd line (e.g. -svc mode)\n"
"\n"
"-unixpw_nis [list] As -unixpw above, however do not use su(1) but rather\n"
" use the traditional getpwnam(3) + crypt(3) method to\n"
" verify passwords. All of the above -unixpw options and\n"
@ -2745,10 +2748,13 @@ void print_help(int mode) {
"-repeat VNC clients are connected and VNC keyboard input is\n"
" not idle for more than 5 minutes. This works around a\n"
" repeating keystrokes bug (triggered by long processing\n"
" delays between key down and key up client events: either\n"
" from large screen changes or high latency).\n"
" delays between key down and key up client events:\n"
" either from large screen changes or high latency).\n"
" Default: %s\n"
"\n"
" You can set the env. var. X11VNC_IDLE_TIMEOUT to the\n"
" number of idle seconds you want (5min = 300secs).\n"
"\n"
" Note: your VNC viewer side will likely do autorepeating,\n"
" so this is no loss unless someone is simultaneously at\n"
" the real X display.\n"
@ -3647,12 +3653,25 @@ void print_help(int mode) {
" -sig ignore:INT,TERM,exit:USR1\n"
"\n"
"-threads Whether or not to use the threaded libvncserver\n"
"-nothreads algorithm [rfbRunEventLoop] if libpthread is available\n"
" Default: %s. NOTE: The -threads mode is now\n"
" disabled due to its unstable behavior. Not recommended,\n"
" but you can recompile with -DX11VNC_THREADED in\n"
" CPPFLAGS if you need to use it. You can also set the\n"
" env. variable X11VNC_THREADED=1\n"
"-nothreads algorithm [rfbRunEventLoop] if libpthread is available.\n"
" In this mode new threads (one for input and one\n"
" for output) are created to handle each new client.\n"
" Default: %s.\n"
"\n"
" NOTE: The -threads mode may be disabled due to its\n"
" unstable behavior. If it is disabled, a warning is\n"
" printed out. Stability has been improved in version\n"
" 0.9.8 and so the feature has been re-enabled.\n"
"\n"
" Multiple clients in threaded mode should be stable\n"
" for the ZRLE encoding on all platforms. The Tight and\n"
" Zlib encodings are currently only stable on Linux for\n"
" multiple clients. Compile with -DTLS=__thread if your\n"
" OS and compiler and linker support it.\n"
"\n"
" Multiple clients in threaded mode could yield better\n"
" performance for 'class-room' broadcasting usage.\n"
" See also the -reflect option.\n"
"\n"
"-fs f If the fraction of changed tiles in a poll is greater\n"
" than f, the whole screen is updated. Default: %.2f\n"

@ -397,13 +397,12 @@ void autorepeat(int restore, int bequiet) {
return; /* nothing to restore */
}
global_auto_repeat = get_autorepeat_state();
X_LOCK;
/* read state and skip restore if equal (e.g. no clients) */
if (global_auto_repeat == save_auto_repeat) {
X_UNLOCK;
return;
}
X_LOCK;
kctrl.auto_repeat_mode = save_auto_repeat;
XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
XFlush_wr(dpy);
@ -2641,6 +2640,7 @@ static void tweak_mod(signed char mod, rfbBool down) {
XTestFakeKeyEvent_wr(dpy, altgr, dn, CurrentTime);
}
X_UNLOCK;
if (debug_keyboard) {
rfbLog("tweak_mod: Finish: down=%d index=%d mod_state=0x%x"
" is_shift=%d\n", down, (int) mod, (int) mod_state,
@ -2758,6 +2758,7 @@ void initialize_keyboard_and_pointer(void) {
initialize_remap(remap_file);
initialize_pointer_map(pointer_remap);
X_LOCK;
clear_modifiers(1);
if (clear_mods == 1) {
clear_modifiers(0);
@ -2765,6 +2766,7 @@ void initialize_keyboard_and_pointer(void) {
if (clear_mods == 3) {
clear_locks();
}
X_UNLOCK;
}
void get_allowed_input(rfbClientPtr client, allowed_input_t *input) {

@ -19,6 +19,13 @@ while (<>) {
#define xrealloc realloc
#define rfbTightNoZlib 0x0A
#define tightSubsampLevel correMaxWidth
#if LIBVNCSERVER_HAVE_LIBPTHREAD && LIBVNCSERVER_HAVE_TLS
#define TLS __thread
#else
#define TLS
#endif
END
next;
}
@ -38,6 +45,10 @@ END
# $_ =~ s/cl->tightQualityLevel;/cl->tightQualityLevel * 10;/;
if (/^static\s+(Bool|int|CARD32|PALETTE|char|unsigned|tjhandle)\s+[^()]*;\s*$/) {
$_ =~ s/^static/static TLS /;
}
$_ =~ s/rfbScreen.pfbMemory/cl->scaledScreen->frameBuffer/g;
$_ =~ s/rfbScreen.paddedWidthInBytes/cl->scaledScreen->paddedWidthInBytes/g;
$_ =~ s/rfbScreen.bitsPerPixel/cl->scaledScreen->bitsPerPixel/g;

@ -344,7 +344,7 @@ char **scroll_skip_all = NULL;
char **scroll_skip_key = NULL;
char **scroll_skip_mouse = NULL;
char *scroll_skip_str = NULL;
char *scroll_skip_str0 = "##Soffice.bin,##StarOffice";
char *scroll_skip_str0 = "##Soffice.bin,##StarOffice,##OpenOffice";
/* "##Konsole," * no problems, known heuristics do not work */
char **scroll_term = NULL;
@ -463,11 +463,8 @@ int quiet = 0;
int verbose = 0;
/* threaded vs. non-threaded (default) */
#if LIBVNCSERVER_HAVE_LIBPTHREAD && defined(X11VNC_THREADED)
int use_threads = 0; /* not 1. now X11VNC_THREADED means enable it at all. */
#else
int use_threads = 0;
#endif
int started_rfbRunEventLoop = 0;
/* info about command line opts */
int got_noxwarppointer = 0;

@ -359,6 +359,7 @@ extern int quiet;
extern int verbose;
extern int use_threads;
extern int started_rfbRunEventLoop;
extern int got_noxwarppointer;
extern int got_rfbport;

@ -455,12 +455,17 @@ if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
if (OUCH && ouch_db) fprintf(stderr, "***OUCH-A\n");
if (OUCH) continue;
if (use_threads) LOCK(cl->updateMutex);
if (sraRgnCountRects(cl->modifiedRegion)) {
rfbPE(1000);
if (OUCH && ouch_db) fprintf(stderr, "***OUCH-B\n");
if (use_threads) UNLOCK(cl->updateMutex);
if (OUCH) continue;
}
if (use_threads) UNLOCK(cl->updateMutex);
defer = screen->deferUpdateTime;
httpdir = screen->httpDir;
screen->deferUpdateTime = 0;
@ -486,8 +491,13 @@ if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C1\n");
if (OUCH) break;
if (use_threads) LOCK(cl->updateMutex);
req0 = sraRgnCountRects(cl->requestedRegion);
mod0 = sraRgnCountRects(cl->modifiedRegion);
if (use_threads) UNLOCK(cl->updateMutex);
if (use_threads) {
usleep(1000);
} else {
@ -506,9 +516,13 @@ if (db) fprintf(stderr, "%d client num rects req: %d mod: %d cbs: %d "
if (OUCH && ouch_db) fprintf(stderr, "***OUCH-C2\n");
if (OUCH) break;
if (use_threads) LOCK(cl->updateMutex);
req1 = sraRgnCountRects(cl->requestedRegion);
mod1 = sraRgnCountRects(cl->modifiedRegion);
if (use_threads) UNLOCK(cl->updateMutex);
if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
"fbu-sent: %d dt: %.4f dt2: %.4f tm: %.4f\n",
req0, req1, mod0, mod1,
@ -558,10 +572,12 @@ if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
while (1) {
int req0, req1, mod0, mod1;
req0 = sraRgnCountRects(
cl->requestedRegion);
mod0 = sraRgnCountRects(
cl->modifiedRegion);
if (use_threads) LOCK(cl->updateMutex);
req0 = sraRgnCountRects(cl->requestedRegion);
mod0 = sraRgnCountRects(cl->modifiedRegion);
if (use_threads) UNLOCK(cl->updateMutex);
if (i == 0) {
rfbPE(0);
@ -582,11 +598,13 @@ if (db) fprintf(stderr, "dt2 calc: num rects req: %d/%d mod: %d/%d "
if (dt3 > spin_lat_max) {
break;
}
req1 = sraRgnCountRects(
cl->requestedRegion);
mod1 = sraRgnCountRects(
cl->modifiedRegion);
if (use_threads) LOCK(cl->updateMutex);
req1 = sraRgnCountRects(cl->requestedRegion);
mod1 = sraRgnCountRects(cl->modifiedRegion);
if (use_threads) UNLOCK(cl->updateMutex);
if (db) fprintf(stderr, "dt3 calc: num rects req: %d/%d mod: %d/%d "
"fbu-sent: %d dt: %.4f dt3: %.4f tm: %.4f\n",

@ -929,12 +929,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ok = 1;
}
if (ok) {
X_LOCK;
if (twin && ! valid_window(twin, NULL, 0)) {
rfbLog("skipping invalid sub-window: 0x%lx\n",
twin);
rfbLog("skipping invalid sub-window: 0x%lx\n", twin);
X_UNLOCK;
} else {
subwin = twin;
rootshift = 0;
X_UNLOCK;
check_black_fb();
do_new_fb(1);
}
@ -968,12 +970,14 @@ char *process_remote_cmd(char *cmd, int stringonly) {
ok = 1;
}
if (ok) {
X_LOCK;
if (twin && ! valid_window(twin, NULL, 0)) {
rfbLog("skipping invalid sub-window: 0x%lx\n",
twin);
rfbLog("skipping invalid sub-window: 0x%lx\n", twin);
X_UNLOCK;
} else {
subwin = twin;
rootshift = 1;
X_UNLOCK;
check_black_fb();
do_new_fb(1);
}
@ -2394,7 +2398,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
rfbLog("remote_cmd: enabling -clear_mods mode.\n");
clear_mods = 1;
if (use_threads) {X_LOCK;}
clear_modifiers(0);
if (use_threads) {X_UNLOCK;}
goto done;
}
if (!strcmp(p, "noclear_mods")) {
@ -2415,7 +2421,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
rfbLog("remote_cmd: enabling -clear_keys mode.\n");
clear_mods = 2;
if (use_threads) {X_LOCK;}
clear_keys();
if (use_threads) {X_UNLOCK;}
goto done;
}
if (!strcmp(p, "noclear_keys")) {
@ -2436,14 +2444,18 @@ char *process_remote_cmd(char *cmd, int stringonly) {
}
rfbLog("remote_cmd: doing clear_all action.\n");
clear_mods = 3;
if (use_threads) {X_LOCK;}
clear_keys();
clear_locks();
if (use_threads) {X_UNLOCK;}
goto done;
}
if (!strcmp(p, "clear_locks")) {
NOTAPP
rfbLog("remote_cmd: doing clear_locks action.\n");
if (use_threads) {X_LOCK;}
clear_locks();
if (use_threads) {X_UNLOCK;}
goto done;
}
if (!strcmp(p, "keystate")) {
@ -2452,7 +2464,9 @@ char *process_remote_cmd(char *cmd, int stringonly) {
for (i=0; i<256; i++) {
state[i] = 0;
}
if (use_threads) {X_LOCK;}
get_keystate(state);
if (use_threads) {X_UNLOCK;}
for (i=0; i<256; i++) {
fprintf(stderr, "keystate[%03d] %d\n", i, state[i]);
}

@ -1776,6 +1776,7 @@ static int copy_tiles(int tx, int ty, int nt) {
copy_image(tile_row[nt], x, y, size_x, size_y);
XRANDR_CHK_TRAP_RET(-1, "copy_tile-chk");
X_UNLOCK;
if (blackouts && tile_blackout[n].cover == 1) {
@ -2806,6 +2807,7 @@ if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - st
}
X_UNLOCK;
dt = dtime(&dt);
if (first) {
rfbLog("copy_snap: time for -snapfb snapshot: %.3f sec\n", dt);
@ -3474,7 +3476,7 @@ int scan_for_updates(int count_only) {
last_xd_check = time(NULL);
if (xd_samples > 200) {
static int bad = 0;
if (xd_misses > (5 * xd_samples) / 100) {
if (xd_misses > (20 * xd_samples) / 100) {
rfbLog("XDAMAGE is not working well... misses: %d/%d\n", xd_misses, xd_samples);
rfbLog("Maybe an OpenGL app like Beryl or Compiz is the problem?\n");
rfbLog("Use x11vnc -noxdamage or disable the Beryl/Compiz app.\n");

@ -858,6 +858,60 @@ static void remove_fake_fb(void) {
fake_fb = NULL;
}
static void lock_client_sends(int lock) {
static rfbClientPtr *cls = NULL;
static int cls_len = 0;
static int blocked = 0;
rfbClientIteratorPtr iter;
rfbClientPtr cl;
if (!use_threads) {
return;
}
if (!screen) {
return;
}
if (lock) {
if (cls_len < client_count + 128) {
if (cls != NULL) {
free(cls);
}
cls_len = client_count + 128;
cls = (rfbClientPtr *) calloc(cls_len * sizeof(rfbClientPtr), 1);
}
iter = rfbGetClientIterator(screen);
blocked = 0;
while ((cl = rfbClientIteratorNext(iter)) != NULL) {
SEND_LOCK(cl);
rfbLog("locked client: %p\n", cl);
cls[blocked++] = cl;
}
rfbReleaseClientIterator(iter);
} else {
int i;
for (i=0; i < blocked; i++) {
cl = cls[i];
if (cl != NULL) {
SEND_UNLOCK(cl)
rfbLog("unlocked client: %p\n", cl);
}
cls[i] = NULL;
}
blocked = 0;
}
}
static void rfb_new_framebuffer(rfbScreenInfoPtr rfbScreen, char *framebuffer,
int width,int height, int bitsPerSample,int samplesPerPixel,
int bytesPerPixel) {
rfbNewFramebuffer(rfbScreen, framebuffer, width, height, bitsPerSample,
samplesPerPixel, bytesPerPixel);
}
static void install_fake_fb(int w, int h, int bpp) {
int bpc;
if (! screen) {
@ -876,7 +930,9 @@ static void install_fake_fb(int w, int h, int bpp) {
rfbLog("rfbNewFramebuffer(0x%x, 0x%x, %d, %d, %d, %d, %d)\n",
screen, fake_fb, w, h, bpc, 1, bpp/8);
rfbNewFramebuffer(screen, fake_fb, w, h, bpc, 1, bpp/8);
lock_client_sends(1);
rfb_new_framebuffer(screen, fake_fb, w, h, bpc, 1, bpp/8);
lock_client_sends(0);
}
void check_padded_fb(void) {
@ -1204,6 +1260,11 @@ rfbBool vnc_reflect_send_pointer(int x, int y, int mask) {
last_pointer_time = time(NULL);
}
if (clipshift) {
x += coff_x;
y += coff_y;
}
if (cursor_x != x || cursor_y != y) {
last_pointer_motion_time = dnow();
}
@ -2021,7 +2082,7 @@ static void initialize_clipshift(void) {
bad = 1;
}
if (bad) {
rfbLog("skipping invalid -clip WxH+X+Y: %s\n",
rfbLog("*** ignoring invalid -clip WxH+X+Y: %s\n",
clip_str);
} else {
/* OK, change geom behind everyone's back... */
@ -2356,6 +2417,7 @@ if (0) fprintf(stderr, "DefaultDepth: %d visial_id: %d\n", depth, (int) visual_
if (use_snapfb) {
initialize_snap_fb();
}
X_UNLOCK;
if (fb->bits_per_pixel == 24 && ! quiet) {
@ -2743,6 +2805,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
*/
bits_per_color = guess_bits_per_color(fb_bpp);
lock_client_sends(1);
/* n.b. samplesPerPixel (set = 1 here) seems to be unused. */
if (create_screen) {
if (use_openssl) {
@ -2764,7 +2828,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
screen->bitsPerPixel = fb_bpp;
screen->depth = fb_depth;
rfbNewFramebuffer(screen, NULL, width, height,
rfb_new_framebuffer(screen, NULL, width, height,
bits_per_color, 1, (int) fb_bpp/8);
}
if (! screen) {
@ -3175,6 +3239,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
do_copy_screen = 1;
/* done for framebuffer change case */
lock_client_sends(0);
return;
}
@ -3249,6 +3314,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) {
}
install_passwds();
lock_client_sends(0);
}
#define DO_AVAHI \
@ -3811,7 +3878,8 @@ void watch_loop(void) {
double tm, dtr, dt = 0.0;
time_t start = time(NULL);
if (use_threads) {
if (use_threads && !started_rfbRunEventLoop) {
started_rfbRunEventLoop = 1;
rfbRunEventLoop(screen, -1, TRUE);
}
@ -3887,8 +3955,7 @@ void watch_loop(void) {
disable_cursor_shape_updates(screen);
}
if (screen && screen->clientHead) {
int ret = check_user_input(dt, dtr,
tile_diffs, &cnt);
int ret = check_user_input(dt, dtr, tile_diffs, &cnt);
/* true: loop back for more input */
if (ret == 2) {
skip_pe = 1;
@ -3905,6 +3972,16 @@ void watch_loop(void) {
}
} else {
/* -threads here. */
if (unixpw_in_progress) {
rfbClientPtr cl = unixpw_client;
if (cl && cl->onHold) {
rfbLog(msg, cl->host);
unixpw_client->onHold = FALSE;
}
}
if (use_xrecord) {
check_xrecord();
}
if (wireframe && button_mask) {
check_wireframe();
}

@ -2565,7 +2565,7 @@ void accept_openssl(int mode, int presock) {
return;
}
client = rfbNewClient(screen, vsock);
client = create_new_client(vsock, 0);
openssl_last_helper_pid = 0;
if (client) {
@ -2585,12 +2585,16 @@ void accept_openssl(int mode, int presock) {
client->protocolMinorVersion = 8;
if (!finish_vencrypt_auth(client, vencrypt_sel)) {
rfbCloseClient(client);
client = NULL;
}
} else if (anontls_sel != 0) {
client->protocolMajorVersion = 3;
client->protocolMinorVersion = 8;
rfbAuthNewClient(client);
}
if (use_threads && client != NULL) {
rfbStartOnHoldClient(client);
}
/* try to get RFB proto done now. */
progress_client();
} else {

@ -1157,6 +1157,7 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
static void set_db(void) {
if (getenv("DEBUG_UNIXPW")) {
db = atoi(getenv("DEBUG_UNIXPW"));
rfbLog("DEBUG_UNIXPW: %d\n", db);
}
}

@ -1533,6 +1533,7 @@ static void setup_client_connect(int *did_client_connect) {
static void loop_for_connect(int did_client_connect) {
int loop = 0;
time_t start = time(NULL);
if (first_conn_timeout < 0) {
first_conn_timeout = -first_conn_timeout;
}
@ -1564,7 +1565,11 @@ static void loop_for_connect(int did_client_connect) {
* This is to handle an initial verify cert from viewer,
* they disconnect right after fetching the cert.
*/
if (! use_threads) rfbPE(-1);
if (use_threads) {
usleep(10 * 1000);
} else {
rfbPE(-1);
}
if (screen && screen->clientHead) {
int i;
if (unixpw) {
@ -1607,7 +1612,9 @@ static void loop_for_connect(int did_client_connect) {
check_openssl();
}
if (! use_threads) {
if (use_threads) {
usleep(10 * 1000);
} else {
rfbPE(-1);
}
@ -2823,6 +2830,12 @@ int wait_for_client(int *argc, char** argv, int http) {
if (vnc_redirect) {
vnc_redirect_loop(vnc_redirect_test, &vnc_redirect_cnt);
} else {
if (use_threads && !started_rfbRunEventLoop) {
started_rfbRunEventLoop = 1;
rfbRunEventLoop(screen, -1, TRUE);
}
if (inetd && use_openssl) {
accept_openssl(OPENSSL_INETD, -1);
}
@ -2842,7 +2855,6 @@ int wait_for_client(int *argc, char** argv, int http) {
} else if (cmd && !use_threads) {
/* try to get RFB proto done now. */
progress_client();
}
}

@ -1842,10 +1842,12 @@ static void get_client_regions(int *req, int *mod, int *cpy, int *num) {
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (use_threads) LOCK(cl->updateMutex);
*req += sraRgnCountRects(cl->requestedRegion);
*mod += sraRgnCountRects(cl->modifiedRegion);
*cpy += sraRgnCountRects(cl->copyRegion);
*num += 1;
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
}
@ -2024,7 +2026,9 @@ if (0) fprintf(stderr, "sb.. %d %d %d %d %d %d\n", sx1, sy1, sx2, sy2, sdx, sdy)
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (use_threads) LOCK(cl->updateMutex);
rfbSendCopyRegion(cl, r, sdx, sdy);
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
sraRgnDestroy(r);
@ -2073,34 +2077,47 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
if (delay < 0.0) {
delay = 0.1;
}
fb_push_wait(delay, FB_COPY|FB_MOD);
if (!fb_push_wait(delay, FB_COPY|FB_MOD)) {
if (use_threads) usleep(100 * 1000);
fb_push_wait(0.75, FB_COPY|FB_MOD);
}
t1 = dnow();
#if 0
bad = 0;
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (use_threads) LOCK(cl->updateMutex);
if (cl->ublen != 0) {
fprintf(stderr, "batch_copyregion: *** BAD ublen != 0: %d\n", cl->ublen);
bad++;
}
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
if (bad) {
return;
}
#endif
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
rfbFramebufferUpdateMsg *fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
rfbFramebufferUpdateMsg *fu;
if (use_threads) LOCK(cl->updateMutex);
fu = (rfbFramebufferUpdateMsg *)cl->updateBuf;
fu->nRects = Swap16IfLE((uint16_t)(nrects));
fu->type = rfbFramebufferUpdate;
if (cl->ublen != 0) fprintf(stderr, "batch_copyregion: *** BAD ublen != 0: %d\n", cl->ublen);
if (cl->ublen != 0) fprintf(stderr, "batch_copyregion: *** BAD-2 ublen != 0: %d\n", cl->ublen);
cl->ublen = sz_rfbFramebufferUpdateMsg;
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
@ -2119,12 +2136,17 @@ void batch_copyregion(sraRegionPtr* region, int *dx, int *dy, int ncr, double de
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (use_threads) LOCK(cl->updateMutex);
if (!direct) {
for (k=0; k < ncr; k++) {
rfbSendCopyRegion(cl, region[k], dx[k], dy[k]);
}
}
rfbSendUpdateBuf(cl);
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
@ -2145,49 +2167,32 @@ void batch_push(int nreg, double delay) {
}
}
void fb_push0(void) {
char *httpdir = screen->httpDir;
int defer = screen->deferUpdateTime;
int req0, mod0, cpy0, req1, mod1, cpy1, ncli;
int db = (debug_scroll || debug_wireframe);
screen->httpDir = NULL;
screen->deferUpdateTime = 0;
if (db) get_client_regions(&req0, &mod0, &cpy0, &ncli);
rfbPE(0);
screen->httpDir = httpdir;
screen->deferUpdateTime = defer;
if (db) {
get_client_regions(&req1, &mod1, &cpy1, &ncli);
fprintf(stderr, "\nFB_push: req: %d/%d mod: %d/%d cpy: %d/%d %.4f\n",
req0, req1, mod0, mod1, cpy0, cpy1, dnowx());
}
}
void fb_push(void) {
int req0, mod0, cpy0, req1, mod1, cpy1, ncli;
int db = (debug_scroll || debug_wireframe);
rfbClientIteratorPtr i;
rfbClientPtr cl;
if (use_threads) {
return;
}
if (db) get_client_regions(&req0, &mod0, &cpy0, &ncli);
i = rfbGetClientIterator(screen);
while( (cl = rfbClientIteratorNext(i)) ) {
if (use_threads) LOCK(cl->updateMutex);
if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
!sraRgnEmpty(cl->requestedRegion)) {
if (!rfbSendFramebufferUpdate(cl, cl->modifiedRegion)) {
fprintf(stderr, "*** rfbSendFramebufferUpdate *FAILED* #1\n");
if (cl->ublen) fprintf(stderr, "*** fb_push ublen not zero: %d\n", cl->ublen);
if (use_threads) UNLOCK(cl->updateMutex);
break;
}
if (cl->ublen) fprintf(stderr, "*** fb_push ublen NOT ZERO: %d\n", cl->ublen);
}
if (use_threads) UNLOCK(cl->updateMutex);
}
rfbReleaseClientIterator(i);
@ -2199,37 +2204,6 @@ if (db) {
}
int fb_push_wait0(double max_wait, int flags) {
double tm, dt = 0.0;
int req, mod, cpy, ncli;
int ok = 0;
dtime0(&tm);
while (dt < max_wait) {
int done = 1;
rfbCFD(0);
get_client_regions(&req, &mod, &cpy, &ncli);
if (flags & FB_COPY && cpy) {
done = 0;
}
if (flags & FB_MOD && mod) {
done = 0;
}
if (flags & FB_REQ && req) {
done = 0;
}
if (done) {
ok = 1;
break;
}
usleep(1000);
fb_push();
dt += dtime(&tm);
}
return ok;
}
int fb_push_wait(double max_wait, int flags) {
double tm, dt = 0.0;
int req, mod, cpy, ncli;
@ -3403,6 +3377,7 @@ if (db2 && saw_me) continue;
sraRgnSubtract(moved_win, tmp_win);
sraRgnDestroy(tmp_win);
}
X_UNLOCK;
if (extra_clip && ! sraRgnEmpty(extra_clip)) {
@ -4597,6 +4572,9 @@ if (db) fprintf(stderr, "INTERIOR\n");
if (rotating) {
try_batch = 0;
}
if (use_threads && ncache > 0 && ncache_copyrect) {
try_batch = 0;
}
g = got_pointer_input;
gd = got_local_pointer_input;
@ -4882,8 +4860,9 @@ if (0) fprintf(stderr, "*** NO GPI DRAW_BOX\n");
rfbPE(1000);
} else {
#ifndef NO_NCACHE
int tb = use_threads ? 0 : try_batch;
do_copyrect_drag_move(orig_frame, frame, &nidx,
try_batch, now_x, now_y, orig_w, orig_h, x, y, w, h,
tb, now_x, now_y, orig_w, orig_h, x, y, w, h,
copyrect_drag_delay);
now_x = x;
now_y = y;
@ -4940,8 +4919,9 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
draw_box(0, 0, 0, 0, 1);
fb_push(); /* XXX Y */
} else {
int tb = use_threads ? 0 : try_batch;
do_copyrect_drag_move(orig_frame, frame, &nidx,
try_batch, now_x, now_y, orig_w, orig_h, x, y, w, h, -1.0);
tb, now_x, now_y, orig_w, orig_h, x, y, w, h, -1.0);
fb_push_wait(0.15, FB_COPY|FB_MOD);
}
@ -4960,15 +4940,19 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
} 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);
X_LOCK;
clear_win_events(orig_frame, 1);
if (frame != orig_frame) {
clear_win_events(frame, 1);
}
X_UNLOCK;
}
} else if (dx == 0 && dy == 0) {
;
} else if (do_copyrect_drag > 0) {
X_LOCK;
clear_win_events(NPP_nwin, 0);
X_UNLOCK;
} else {
int spin_ms = (int) (spin * 1000 * 1000);
int obscured, sent_copyrect = 0;
@ -5030,7 +5014,9 @@ if ((ncache || db) && ncdb) fprintf(stderr, "sent_copyrect: %d - obs: %d frame:
}
ncache_post_portions(nidx, use_batch,
orig_x, orig_y, orig_w, orig_h, x, y, w, h, -1.0, ntim);
X_LOCK;
clear_win_events(NPP_nwin, 0);
X_UNLOCK;
if (scaling && !use_batch) {
static double last_time = 0.0;
@ -7598,6 +7584,7 @@ void block_stats(void) {
int h = cache_list[k].bs_h;
int rc = 0;
Window win = cache_list[k].win;
if (win == None) {
continue;
}
@ -8790,7 +8777,11 @@ if (ncdb) fprintf(stderr, "*SCHED LOOKUP FAIL: i=%d 0x%lx\n", i, win);
}
/* XXX Y resp */
if (saw_desktop_change || freq % 5 == 0) {
if (!valid_window(win, &attr, 1)) {
int vret = 0;
X_LOCK;
vret = valid_window(win, &attr, 1);
X_UNLOCK;
if (!vret) {
continue;
}
STORE(i, win, attr);
@ -8948,6 +8939,9 @@ int check_ncache(int reset, int mode) {
if (reset && (first || cache_list_len == 0)) {
return -1;
}
if (use_threads) {
try_batch = 0;
}
if (ncache0) {
if (reset) {
@ -9244,6 +9238,7 @@ if (ncdb) fprintf(stderr, "PRELOOP: RepartNotify: 0x%lx %d idx=%d\n", win2, n1,
break;
}
}
X_UNLOCK;
if (got_NET_CURRENT_DESKTOP > 0.0) {
@ -9703,7 +9698,9 @@ if (ncdb) fprintf(stderr, "skip%02d: ** SpecialSkip 0x%lx/0x%lx type: %s\n", i
valid = 1;
su_save(idx, nbatch, &attr, 0, &valid, 1);
STORE(idx, win2, attr);
X_LOCK;
if (! desktop_change) {
SCHED(win2, 1)
}

@ -451,6 +451,9 @@ double rfac(void) {
void check_allinput_rate(void) {
static double last_all_input_check = 0.0;
static int set = 0;
if (use_threads) {
return;
}
if (! set) {
set = 1;
last_all_input_check = dnow();
@ -482,6 +485,9 @@ static void do_allinput(long usec) {
if (!screen || !screen->clientHead) {
return;
}
if (use_threads) {
return;
}
if (usec < 0) {
usec = 0;
}
@ -592,9 +598,6 @@ void rfbCFD(long usec) {
(int) usec, tm - x11vnc_start);
}
#if 0
fprintf(stderr, "handleEventsEagerly: %d\n", screen->handleEventsEagerly);
#endif
if (! use_threads) {
if (all_input) {
@ -678,6 +681,7 @@ char *choose_title(char *display) {
}
}
strncat(title, display, MAXN - strlen(title));
X_LOCK;
if (subwin && dpy && valid_window(subwin, NULL, 0)) {
#if !NO_X11
char *name = NULL;
@ -690,5 +694,6 @@ char *choose_title(char *display) {
}
#endif /* NO_X11 */
}
X_UNLOCK;
return title;
}

@ -118,4 +118,23 @@ extern MUTEX(scrollMutex);
#define SCR_UNLOCK if (use_threads) {UNLOCK(scrollMutex);}
#define SCR_INIT INIT_MUTEX(scrollMutex)
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
MUTEX(clientMutex);
#endif
#define CLIENT_LOCK if (use_threads) {LOCK(clientMutex);}
#define CLIENT_UNLOCK if (use_threads) {UNLOCK(clientMutex);}
#define CLIENT_INIT INIT_MUTEX(clientMutex)
/*
* The sendMutex member was added to libvncserver 0.9.8
* rfb/rfb.h sets LIBVNCSERVER_SEND_MUTEX if present.
*/
#if LIBVNCSERVER_HAVE_LIBPTHREAD && defined(LIBVNCSERVER_SEND_MUTEX)
#define SEND_LOCK(cl) if (use_threads) LOCK((cl)->sendMutex);
#define SEND_UNLOCK(cl) if (use_threads) UNLOCK((cl)->sendMutex);
#else
#define SEND_LOCK(cl)
#define SEND_UNLOCK(cl)
#endif
#endif /* _X11VNC_UTIL_H */

@ -1,8 +1,8 @@
.\" This file was automatically generated from x11vnc -help output.
.TH X11VNC "1" "March 2009" "x11vnc " "User Commands"
.TH X11VNC "1" "May 2009" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.9.8, lastmod: 2009-03-30
version: 0.9.8, lastmod: 2009-05-18
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -1003,6 +1003,9 @@ associated with it does apply as normal.
There are also some utilities for testing password
if [list] starts with the "%" character. See the
quick_pw() function in the source for details.
.IP
Use \fB-nounixpw\fR to disable unixpw mode if it was enabled
earlier in the cmd line (e.g. \fB-svc\fR mode)
.PP
\fB-unixpw_nis\fR \fI[list]\fR
.IP
@ -3114,10 +3117,13 @@ Option \fB-norepeat\fR disables X server key auto repeat when
VNC clients are connected and VNC keyboard input is
not idle for more than 5 minutes. This works around a
repeating keystrokes bug (triggered by long processing
delays between key down and key up client events: either
from large screen changes or high latency).
delays between key down and key up client events:
either from large screen changes or high latency).
Default: \fB-norepeat\fR
.IP
You can set the env. var. X11VNC_IDLE_TIMEOUT to the
number of idle seconds you want (5min = 300secs).
.IP
Note: your VNC viewer side will likely do autorepeating,
so this is no loss unless someone is simultaneously at
the real X display.
@ -3667,7 +3673,7 @@ If a pattern is prefixed with "KEY:" it only applies
to Keystroke generated scrolls (e.g. Up arrow). If it
is prefixed with "MOUSE:" it only applies to Mouse
induced scrolls (e.g. dragging on a scrollbar).
Default: ##Soffice.bin,##StarOffice
Default: ##Soffice.bin,##StarOffice,##OpenOffice
.PP
\fB-scr_inc\fR \fIlist\fR
.IP
@ -4211,12 +4217,25 @@ for this option if you don't like the 'pipe'. Example:
\fB-threads,\fR \fB-nothreads\fR
.IP
Whether or not to use the threaded libvncserver
algorithm [rfbRunEventLoop] if libpthread is available
Default: \fB-nothreads.\fR NOTE: The \fB-threads\fR mode is now
disabled due to its unstable behavior. Not recommended,
but you can recompile with \fB-DX11VNC_THREADED\fR in
CPPFLAGS if you need to use it. You can also set the
env. variable X11VNC_THREADED=1
algorithm [rfbRunEventLoop] if libpthread is available.
In this mode new threads (one for input and one
for output) are created to handle each new client.
Default: \fB-nothreads.\fR
.IP
NOTE: The \fB-threads\fR mode may be disabled due to its
unstable behavior. If it is disabled, a warning is
printed out. Stability has been improved in version
0.9.8 and so the feature has been re-enabled.
.IP
Multiple clients in threaded mode should be stable
for the ZRLE encoding on all platforms. The Tight and
Zlib encodings are currently only stable on Linux for
multiple clients. Compile with \fB-DTLS=__thread\fR if your
OS and compiler and linker support it.
.IP
Multiple clients in threaded mode could yield better
performance for 'class-room' broadcasting usage.
See also the \fB-reflect\fR option.
.PP
\fB-fs\fR \fIf\fR
.IP

@ -2476,6 +2476,14 @@ int main(int argc, char* argv[]) {
}
continue;
}
if (strstr(arg, "-nounixpw") == arg) {
unixpw = 0;
unixpw_nis = 0;
if (unixpw_list) {
unixpw_list = NULL;
}
continue;
}
if (!strcmp(arg, "-vencrypt")) {
char *s;
CHECK_ARGC
@ -3513,6 +3521,9 @@ int main(int argc, char* argv[]) {
#else
if (getenv("X11VNC_THREADED")) {
use_threads = 1;
} else if (1) {
/* we re-enable it due to threaded mode bugfixes. */
use_threads = 1;
} else {
rfbLog("\n");
rfbLog("The -threads mode is unstable and not tested or maintained.\n");
@ -4331,7 +4342,7 @@ int main(int argc, char* argv[]) {
}
}
}
if (use_threads) {
if (use_threads && !getenv("UNIXPW_THREADS")) {
if (! quiet) {
rfbLog("disabling -threads under -unixpw\n");
}
@ -4514,6 +4525,7 @@ int main(int argc, char* argv[]) {
X_INIT;
SCR_INIT;
CLIENT_INIT;
/* open the X display: */
if (auth_file) {

@ -47,7 +47,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.9.8 lastmod: 2009-03-30";
char lastmod[] = "0.9.8 lastmod: 2009-05-18";
/* X display info */

@ -723,7 +723,9 @@ void check_keycode_state(void) {
* in sync with the Xserver at every instant of time.
*/
if (now > last_check + delay && now > last_keyboard_input + noinput) {
X_LOCK;
init_track_keycode_state();
X_UNLOCK;
last_check = now;
}
}
@ -820,9 +822,9 @@ void check_local_grab(void) {
void check_autorepeat(void) {
static time_t last_check = 0;
static int idle_timeout = -300, idle_reset = 0;
time_t now = time(NULL);
int autorepeat_is_on, autorepeat_initially_on, idle_timeout = 300;
static int idle_reset = 0;
int autorepeat_is_on, autorepeat_initially_on;
if (! no_autorepeat || ! client_count) {
return;
@ -833,6 +835,15 @@ void check_autorepeat(void) {
if (unixpw_in_progress) return;
if (idle_timeout < 0) {
if (getenv("X11VNC_IDLE_TIMEOUT")) {
idle_timeout = atoi(getenv("X11VNC_IDLE_TIMEOUT"));
}
if (idle_timeout < 0) {
idle_timeout = -idle_timeout;
}
}
last_check = now;
autorepeat_is_on = get_autorepeat_state();
@ -850,7 +861,7 @@ void check_autorepeat(void) {
if (! autorepeat_is_on && autorepeat_initially_on) {
static time_t last_msg = 0;
static int cnt = 0;
if (now > last_msg + idle_timeout && cnt++ < 5) {
if (now > last_msg + idle_timeout && cnt++ < 10) {
rfbLog("idle keyboard: turning X autorepeat"
" back on.\n");
last_msg = now;
@ -859,10 +870,27 @@ void check_autorepeat(void) {
idle_reset = 1;
}
} else {
if (idle_reset) {
int i, state[256];
for (i=0; i<256; i++) {
state[i] = 0;
}
if (use_threads) {X_LOCK;}
get_keystate(state);
if (use_threads) {X_UNLOCK;}
for (i=0; i<256; i++) {
if (state[i] != 0) {
/* better wait until all keys are up */
rfbLog("active keyboard: waiting until"
" all keys are up. key_down=%d\n", i);
return;
}
}
}
if (idle_reset) {
static time_t last_msg = 0;
static int cnt = 0;
if (now > last_msg + idle_timeout && cnt++ < 5) {
if (now > last_msg + idle_timeout && cnt++ < 10) {
rfbLog("active keyboard: turning X autorepeat"
" off.\n");
last_msg = now;
@ -1435,8 +1463,16 @@ void kbd_release_all_keys(rfbClientPtr cl) {
#if NO_X11
return;
#else
if (use_threads) {
X_LOCK;
}
clear_keys();
clear_modifiers(0);
if (use_threads) {
X_UNLOCK;
}
#endif
}
@ -1616,7 +1652,7 @@ static void try_local_chat_window(void) {
new_save = screen->newClientHook;
screen->newClientHook = new_client_chat_helper;
chat_window_client = rfbNewClient(screen, sock);
chat_window_client = create_new_client(sock, 1);
screen->newClientHook = new_save;
@ -1678,6 +1714,9 @@ void set_text_chat(rfbClientPtr cl, int len, char *txt) {
if (cl2->state != RFB_NORMAL) {
continue;
}
SEND_LOCK(cl2);
if (ulen == rfbTextChatOpen) {
rfbSendTextChatMessage(cl2, rfbTextChatOpen, "");
} else if (ulen == rfbTextChatClose) {
@ -1689,12 +1728,16 @@ void set_text_chat(rfbClientPtr cl, int len, char *txt) {
} else if (len <= rfbTextMaxSize) {
rfbSendTextChatMessage(cl2, len, txt);
}
SEND_UNLOCK(cl2);
}
rfbReleaseClientIterator(iter);
if (ulen == rfbTextChatClose && cl != NULL) {
/* not clear what is going on WRT close and finished... */
SEND_LOCK(cl);
rfbSendTextChatMessage(cl, rfbTextChatFinished, "");
SEND_UNLOCK(cl);
}
#endif
}

@ -1577,10 +1577,20 @@ if (0) db = 1;
return;
}
if (use_threads) {
/* XXX not working */
use_xrecord = 0;
xrecording = 0;
return;
/* XXX not working. Still? Painting errors. */
static int first = 1;
if (first) {
if (use_xrecord && !getenv("XRECORD_THREADS")) {
rfbLog("xrecord_watch: disabling scroll detection in -threads mode.\n");
rfbLog("xrecord_watch: Set -env XRECORD_THREADS=1 to enable it.\n");
use_xrecord = 0;
xrecording = 0;
}
first = 0;
}
if (!use_xrecord && !xrecording) {
return;
}
}
dtime0(&now);

@ -601,6 +601,9 @@ static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w,
} else if (! raw_fb_seek) {
/* mmap */
bpl = raw_fb_bytes_per_line;
if (clipshift && wdpy_x != cdpy_x) {
bpl = wdpy_x * 3;
}
src = raw_fb_addr + raw_fb_offset + bpl*y + 3*x;
dst = dest->data;
@ -626,6 +629,9 @@ static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w,
/* lseek */
off_t off;
bpl = raw_fb_bytes_per_line;
if (clipshift && wdpy_x != cdpy_x) {
bpl = wdpy_x * 3;
}
off = (off_t) (raw_fb_offset + bpl*y + 3*x);
lseek(raw_fb_fd, off, SEEK_SET);
@ -671,7 +677,7 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
char *src, *dst;
unsigned int line;
int pixelsize = bpp/8;
int bpl = wdpy_x * pixelsize;
static int db = -1;
if (xform24to32) {
copy_raw_fb_24_to_32(dest, x, y, w, h);
@ -681,17 +687,27 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
copy_raw_fb_low_bpp(dest, x, y, w, h);
return;
}
if (db < 0) {
if (getenv("DEBUG_COPY_RAW_FB")) {
db = atoi(getenv("DEBUG_COPY_RAW_FB"));
} else {
db = 0;
}
}
if (clipshift && ! use_snapfb) {
x += coff_x;
y += coff_y;
}
if (use_snapfb && dest != snap) {
/* snapfb src */
src = snap->data + snap->bytes_per_line*y + pixelsize*x;
dst = dest->data;
if (db) fprintf(stderr, "snap->bytes_per_line: %d, dest->bytes_per_line: %d, w: %d h: %d dpy_x: %d wdpy_x: %d cdpy_x: %d\n", snap->bytes_per_line, dest->bytes_per_line, w, h, dpy_x, wdpy_x, cdpy_x);
for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize);
src += snap->bytes_per_line;
@ -700,10 +716,17 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
} else if (! raw_fb_seek) {
/* mmap */
bpl = raw_fb_bytes_per_line;
int bpl = raw_fb_bytes_per_line;
if (clipshift && wdpy_x != cdpy_x) {
bpl = wdpy_x * pixelsize;
}
src = raw_fb_addr + raw_fb_offset + bpl*y + pixelsize*x;
dst = dest->data;
if (db) fprintf(stderr, "bpl: %d, dest->bytes_per_line: %d, w: %d h: %d dpy_x: %d wdpy_x: %d cdpy_x: %d\n", bpl, dest->bytes_per_line, w, h, dpy_x, wdpy_x, cdpy_x);
for (line = 0; line < h; line++) {
memcpy(dst, src, w * pixelsize);
src += bpl;
@ -714,20 +737,25 @@ void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
/* lseek */
int n, len, del, sz = w * pixelsize;
off_t off;
bpl = raw_fb_bytes_per_line;
int bpl = raw_fb_bytes_per_line;
if (clipshift && wdpy_x != cdpy_x) {
bpl = wdpy_x * pixelsize;
}
off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x);
lseek(raw_fb_fd, off, SEEK_SET);
dst = dest->data;
if (0) fprintf(stderr, "lseek 0 ps: %d sz: %d off: %d bpl: %d\n", pixelsize, sz, (int) off, bpl);
if (db) fprintf(stderr, "lseek 0 ps: %d sz: %d off: %d bpl: %d\n", pixelsize, sz, (int) off, bpl);
for (line = 0; line < h; line++) {
len = sz;
del = 0;
while (len > 0) {
n = read(raw_fb_fd, dst + del, len);
if (0) fprintf(stderr, "len: %d n: %d\n", len, n);
//if (db > 2) fprintf(stderr, "len: %d n: %d\n", len, n);
if (n > 0) {
del += n;
@ -739,7 +767,7 @@ if (0) fprintf(stderr, "len: %d n: %d\n", len, n);
}
}
if (bpl > sz) {
if (0) fprintf(stderr, "bpl>sz %d %d\n", bpl, sz);
//if (db > 1) fprintf(stderr, "bpl>sz %d %d\n", bpl, sz);
off = (off_t) (bpl - sz);
lseek(raw_fb_fd, off, SEEK_CUR);
}

Loading…
Cancel
Save