Commit 8aa6fb95 authored by runge's avatar runge

x11vnc: first pass at client-side caching, -ncache option.

parent 399a175f
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.
2006-12-17 Karl Runge <runge@karlrunge.com> 2006-12-17 Karl Runge <runge@karlrunge.com>
* x11vnc: make -xwarppointer the default if xinerama is active. * x11vnc: make -xwarppointer the default if xinerama is active.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2014,6 +2014,32 @@ void print_help(int mode) { ...@@ -2014,6 +2014,32 @@ void print_help(int mode) {
" text selection, and some menu traversals. It overrides\n" " text selection, and some menu traversals. It overrides\n"
" any -pointer_mode setting.\n" " any -pointer_mode setting.\n"
"\n" "\n"
#ifndef NO_NCACHE
"-ncache n Client-side caching scheme. Framebuffer memory \"n\"\n"
" (an integer) times that of the full display is allocated\n"
" below the actual framebuffer to cache screen contents\n"
" for rapid retrieval. So a W x H frambuffer is expanded\n"
" to a W x (n+1)*H one. Use 0 to disable. Default: XXX.\n"
"\n"
" This is an experimental option, currently implemented\n"
" in an awkward way in that in the VNC Viewer you can\n"
" see the cache contents if you scroll down, etc. So you\n"
" will have to set things up so you can't see that region.\n"
" 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"
"\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"
#endif
"-wireframe [str] Try to detect window moves or resizes when a mouse\n" "-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" "-nowireframe button is held down and show a wireframe instead of\n"
" the full opaque window. This is based completely on\n" " the full opaque window. This is based completely on\n"
......
...@@ -193,6 +193,9 @@ char *wireframe_copyrect_default = "never"; ...@@ -193,6 +193,9 @@ char *wireframe_copyrect_default = "never";
int wireframe_in_progress = 0; int wireframe_in_progress = 0;
int wireframe_local = 1; int wireframe_local = 1;
int ncache = 0;
int ncache0 = 0;
/* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */ /* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
char *scroll_copyrect_str = NULL; char *scroll_copyrect_str = NULL;
#ifndef SCROLL_COPYRECT #ifndef SCROLL_COPYRECT
......
...@@ -155,6 +155,9 @@ extern char *wireframe_copyrect; ...@@ -155,6 +155,9 @@ extern char *wireframe_copyrect;
extern char *wireframe_copyrect_default; extern char *wireframe_copyrect_default;
extern int wireframe_in_progress; extern int wireframe_in_progress;
extern int ncache;
extern int ncache0;
extern char *scroll_copyrect_str; extern char *scroll_copyrect_str;
extern char *scroll_copyrect; extern char *scroll_copyrect;
extern char *scroll_copyrect_default; extern char *scroll_copyrect_default;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "selection.h" #include "selection.h"
#include "unixpw.h" #include "unixpw.h"
#include "uinput.h" #include "uinput.h"
#include "userinput.h"
int send_remote_cmd(char *cmd, int query, int wait); int send_remote_cmd(char *cmd, int query, int wait);
int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync, int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
...@@ -335,6 +336,13 @@ int check_httpdir(void) { ...@@ -335,6 +336,13 @@ int check_httpdir(void) {
} else { } else {
snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog); snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog);
} }
if (stat(httpdir, &sbuf) != 0) {
if (use_openssl || use_stunnel || http_ssl) {
snprintf(httpdir, len, "%s/../classes/ssl", prog);
} else {
snprintf(httpdir, len, "%s/../classes", prog);
}
}
free(prog); free(prog);
if (stat(httpdir, &sbuf) == 0) { if (stat(httpdir, &sbuf) == 0) {
...@@ -749,7 +757,35 @@ char *process_remote_cmd(char *cmd, int stringonly) { ...@@ -749,7 +757,35 @@ char *process_remote_cmd(char *cmd, int stringonly) {
/* /*
* Maybe add: passwdfile logfile bg rfbauth passwd... * Maybe add: passwdfile logfile bg rfbauth passwd...
*/ */
if (!strcmp(p, "stop") || !strcmp(p, "quit") || if (strstr(p, "CR:") == p) { /* skip-cmd-list */
/* CR:WxH+X+Y,dx,dy */
int w, h, x, y, dx, dy;
NOTAPP
if (sscanf(p+3, "%dx%d+%d+%d,%d,%d", &w, &h, &x, &y, &dx, &dy) == 6) {
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);
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")) { !strcmp(p, "exit") || !strcmp(p, "shutdown")) {
NOTAPP NOTAPP
if (client_connect_file) { if (client_connect_file) {
......
...@@ -2816,6 +2816,31 @@ static int scan_display(int ystart, int rescan) { ...@@ -2816,6 +2816,31 @@ static int scan_display(int ystart, int rescan) {
/* grab the horizontal scanline from the display: */ /* grab the horizontal scanline from the display: */
X_LOCK; X_LOCK;
#ifndef NO_NCACHE
#if !NO_X11
if (ncache > 0 && dpy) {
/* XXX watch for problems. */
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 (gotone) {
XPutBackEvent(dpy, &ev);
X_UNLOCK;
fprintf(stderr, "*** SCAN_DISPLAY CHECK_NCACHE/%d *** %d\n", gotone, y);
check_ncache(0);
X_LOCK;
}
}
#endif
#endif
XRANDR_SET_TRAP_RET(-1, "scan_display-set"); XRANDR_SET_TRAP_RET(-1, "scan_display-set");
copy_image(scanline, 0, y, 0, 0); copy_image(scanline, 0, y, 0, 0);
XRANDR_CHK_TRAP_RET(-1, "scan_display-chk"); XRANDR_CHK_TRAP_RET(-1, "scan_display-chk");
......
...@@ -2033,6 +2033,23 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { ...@@ -2033,6 +2033,23 @@ 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;
}
#endif
if (cmap8to24 && depth == 8) { if (cmap8to24 && depth == 8) {
rfb_bytes_per_line *= 4; rfb_bytes_per_line *= 4;
rot_bytes_per_line *= 4; rot_bytes_per_line *= 4;
......
...@@ -56,6 +56,7 @@ extern char *crypt(const char*, const char *); ...@@ -56,6 +56,7 @@ extern char *crypt(const char*, const char *);
#undef UNIXPW_CRYPT #undef UNIXPW_CRYPT
#endif #endif
int white_pixel(void);
void unixpw_screen(int init); void unixpw_screen(int init);
void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
void unixpw_accept(char *user); void unixpw_accept(char *user);
...@@ -65,7 +66,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size); ...@@ -65,7 +66,7 @@ int su_verify(char *user, char *pass, char *cmd, char *rbuf, int *rbuf_size);
int crypt_verify(char *user, char *pass); int crypt_verify(char *user, char *pass);
int cmd_verify(char *user, char *pass); int cmd_verify(char *user, char *pass);
static int white(void);
static int text_x(void); static int text_x(void);
static int text_y(void); static int text_y(void);
static void set_db(void); static void set_db(void);
...@@ -89,7 +90,7 @@ static int char_x = 0, char_y = 0, char_w = 8, char_h = 16; ...@@ -89,7 +90,7 @@ static int char_x = 0, char_y = 0, char_w = 8, char_h = 16;
static int db = 0; static int db = 0;
static int white(void) { int white_pixel(void) {
static unsigned long black_pix = 0, white_pix = 1, set = 0; static unsigned long black_pix = 0, white_pix = 1, set = 0;
RAWFB_RET(0xffffff) RAWFB_RET(0xffffff)
...@@ -162,7 +163,7 @@ void unixpw_screen(int init) { ...@@ -162,7 +163,7 @@ void unixpw_screen(int init) {
pscreen = screen; pscreen = screen;
} }
rfbDrawString(pscreen, &default8x16Font, x, y, log, white()); rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
char_x = x; char_x = x;
char_y = y; char_y = y;
...@@ -1075,13 +1076,13 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "*** ...@@ -1075,13 +1076,13 @@ if (db) fprintf(stderr, "unixpw_verify: '%s' '%s'\n", user, db > 1 ? pass : "***
x = text_x(); x = text_x();
y = text_y(); y = text_y();
rfbDrawString(pscreen, &default8x16Font, x, y, li, white()); rfbDrawString(pscreen, &default8x16Font, x, y, li, white_pixel());
char_row += 2; char_row += 2;
x = text_x(); x = text_x();
y = text_y(); y = text_y();
rfbDrawString(pscreen, &default8x16Font, x, y, log, white()); rfbDrawString(pscreen, &default8x16Font, x, y, log, white_pixel());
char_col = strlen(log); char_col = strlen(log);
...@@ -1245,7 +1246,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) { ...@@ -1245,7 +1246,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
x = text_x(); x = text_x();
y = text_y(); y = text_y();
rfbDrawString(pscreen, &default8x16Font, x, y, pw, rfbDrawString(pscreen, &default8x16Font, x, y, pw,
white()); white_pixel());
char_col = strlen(pw); char_col = strlen(pw);
if (scaling) { if (scaling) {
...@@ -1279,7 +1280,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) { ...@@ -1279,7 +1280,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
x = text_x(); x = text_x();
y = text_y(); y = text_y();
rfbDrawString(pscreen, &default8x16Font, x, y, rfbDrawString(pscreen, &default8x16Font, x, y,
str, white()); str, white_pixel());
mark_rect_as_modified(x, y-char_h, x+char_w, mark_rect_as_modified(x, y-char_h, x+char_w,
y, scaling); y, scaling);
char_col++; char_col++;
...@@ -1323,7 +1324,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) { ...@@ -1323,7 +1324,7 @@ void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init) {
if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x '%s'\n", u_cnt, x, y, keysym, keystr); if (db && db <= 2) fprintf(stderr, "u_cnt: %d %d/%d ks: 0x%x '%s'\n", u_cnt, x, y, keysym, keystr);
rfbDrawString(pscreen, &default8x16Font, x, y, keystr, white()); rfbDrawString(pscreen, &default8x16Font, x, y, keystr, white_pixel());
mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling); mark_rect_as_modified(x, y-char_h, x+char_w, y, scaling);
char_col++; char_col++;
...@@ -1555,7 +1556,7 @@ void unixpw_deny(void) { ...@@ -1555,7 +1556,7 @@ void unixpw_deny(void) {
x = char_x + char_col * char_w; x = char_x + char_col * char_w;
y = char_y + char_row * char_h; y = char_y + char_row * char_h;
rfbDrawString(pscreen, &default8x16Font, x, y, pd, white()); rfbDrawString(pscreen, &default8x16Font, x, y, pd, white_pixel());
if (scaling) { if (scaling) {
mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1); mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1);
} else { } else {
...@@ -1587,7 +1588,7 @@ void unixpw_msg(char *msg, int delay) { ...@@ -1587,7 +1588,7 @@ void unixpw_msg(char *msg, int delay) {
x = char_x + char_col * char_w; x = char_x + char_col * char_w;
y = char_y + char_row * char_h; y = char_y + char_row * char_h;
rfbDrawString(pscreen, &default8x16Font, x, y, msg, white()); rfbDrawString(pscreen, &default8x16Font, x, y, msg, white_pixel());
if (scaling) { if (scaling) {
mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1); mark_rect_as_modified(0, 0, scaled_x, scaled_y, 1);
} else { } else {
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
/* -- unixpw.h -- */ /* -- unixpw.h -- */
extern int white_pixel(void);
extern void unixpw_screen(int init); extern void unixpw_screen(int init);
extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init); extern void unixpw_keystroke(rfbBool down, rfbKeySym keysym, int init);
extern void unixpw_accept(char *user); extern void unixpw_accept(char *user);
......
This diff is collapsed.
...@@ -35,5 +35,6 @@ extern int check_xrecord(void); ...@@ -35,5 +35,6 @@ extern int check_xrecord(void);
extern int check_wireframe(void); extern int check_wireframe(void);
extern int fb_update_sent(int *count); extern int fb_update_sent(int *count);
extern int check_user_input(double dt, double dtr, int tile_diffs, int *cnt); extern int check_user_input(double dt, double dtr, int tile_diffs, int *cnt);
extern void do_copyregion(sraRegionPtr region, int dx, int dy);
#endif /* _X11VNC_USERINPUT_H */ #endif /* _X11VNC_USERINPUT_H */
...@@ -15,6 +15,11 @@ typedef struct winattr { ...@@ -15,6 +15,11 @@ typedef struct winattr {
int map_state; int map_state;
int rx, ry; int rx, ry;
double time; double time;
double bs_time;
double su_time;
int bs_x, bs_y, bs_w, bs_h;
int su_x, su_y, su_w, su_h;
int selectinput;
} winattr_t; } winattr_t;
#endif /* _X11VNC_WINATTR_T_H */ #endif /* _X11VNC_WINATTR_T_H */
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
.TH X11VNC "1" "December 2006" "x11vnc " "User Commands" .TH X11VNC "1" "December 2006" "x11vnc " "User Commands"
.SH NAME .SH NAME
x11vnc - allow VNC connections to real X11 displays x11vnc - allow VNC connections to real X11 displays
version: 0.8.4, lastmod: 2006-12-14 version: 0.8.4, lastmod: 2006-12-17
.SH SYNOPSIS .SH SYNOPSIS
.B x11vnc .B x11vnc
[OPTION]... [OPTION]...
...@@ -2376,6 +2376,32 @@ slow setups, but you lose all visual feedback for drags, ...@@ -2376,6 +2376,32 @@ slow setups, but you lose all visual feedback for drags,
text selection, and some menu traversals. It overrides text selection, and some menu traversals. It overrides
any \fB-pointer_mode\fR setting. any \fB-pointer_mode\fR setting.
.PP .PP
\fB-ncache\fR \fIn\fR
.IP
Client-side caching scheme. Framebuffer memory \fIn\fR
(an integer) times that of the full display is allocated
below the actual framebuffer to cache screen contents
for rapid retrieval. So a W x H frambuffer is expanded
to a W x (n+1)*H one. Use 0 to disable. Default: XXX.
.IP
This is an experimental option, currently implemented
in an awkward way in that in the VNC Viewer you can
see the cache contents if you scroll down, etc. So you
will have to set things up so you can't see that region.
If this method is successful, the changes required for
clients to do this less awkwardly will be investigated.
.IP
Note that this mode consumes a 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.
.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.
.PP
\fB-wireframe\fR \fI[str],\fR \fB-nowireframe\fR \fB-wireframe\fR \fI[str],\fR \fB-nowireframe\fR
.IP .IP
Try to detect window moves or resizes when a mouse Try to detect window moves or resizes when a mouse
......
...@@ -554,6 +554,7 @@ static void watch_loop(void) { ...@@ -554,6 +554,7 @@ static void watch_loop(void) {
} }
check_new_clients(); check_new_clients();
check_ncache();
check_xevents(0); check_xevents(0);
check_autorepeat(); check_autorepeat();
check_pm(); check_pm();
...@@ -611,8 +612,9 @@ static void watch_loop(void) { ...@@ -611,8 +612,9 @@ static void watch_loop(void) {
if (button_mask && (!show_dragging || pointer_mode == 0)) { if (button_mask && (!show_dragging || pointer_mode == 0)) {
/* /*
* if any button is pressed do not update rfb * if any button is pressed in this mode do
* screen, but do flush the X11 display. * not update rfb screen, but do flush the
* X11 display.
*/ */
X_LOCK; X_LOCK;
XFlush_wr(dpy); XFlush_wr(dpy);
...@@ -1200,6 +1202,7 @@ static void print_settings(int try_http, int bg, char *gui_str) { ...@@ -1200,6 +1202,7 @@ static void print_settings(int try_http, int bg, char *gui_str) {
fprintf(stderr, " buttonmap: %s\n", pointer_remap fprintf(stderr, " buttonmap: %s\n", pointer_remap
? pointer_remap : "null"); ? pointer_remap : "null");
fprintf(stderr, " dragging: %d\n", show_dragging); fprintf(stderr, " dragging: %d\n", show_dragging);
fprintf(stderr, " ncache: %d\n", ncache);
fprintf(stderr, " wireframe: %s\n", wireframe_str ? fprintf(stderr, " wireframe: %s\n", wireframe_str ?
wireframe_str : WIREFRAME_PARMS); wireframe_str : WIREFRAME_PARMS);
fprintf(stderr, " wirecopy: %s\n", wireframe_copyrect ? fprintf(stderr, " wirecopy: %s\n", wireframe_copyrect ?
...@@ -2105,6 +2108,14 @@ int main(int argc, char* argv[]) { ...@@ -2105,6 +2108,14 @@ int main(int argc, char* argv[]) {
pointer_remap = strdup(argv[++i]); pointer_remap = strdup(argv[++i]);
} else if (!strcmp(arg, "-nodragging")) { } else if (!strcmp(arg, "-nodragging")) {
show_dragging = 0; show_dragging = 0;
#ifndef NO_NCACHE
} else if (!strcmp(arg, "-ncache")) {
CHECK_ARGC
ncache = atoi(argv[++i]);
if (ncache % 2 != 0) {
ncache++;
}
#endif
} else if (!strcmp(arg, "-wireframe") } else if (!strcmp(arg, "-wireframe")
|| !strcmp(arg, "-wf")) { || !strcmp(arg, "-wf")) {
wireframe = 1; wireframe = 1;
......
...@@ -134,7 +134,9 @@ ...@@ -134,7 +134,9 @@
#define PASSWD_UNLESS_NOPW 0 #define PASSWD_UNLESS_NOPW 0
#endif #endif
/* these are for delaying features: */
#define xxNO_SSL_OR_UNIXPW #define xxNO_SSL_OR_UNIXPW
#define xxNO_NCACHE
/* /*
* Beginning of support for small binary footprint build for embedded * Beginning of support for small binary footprint build for embedded
...@@ -360,6 +362,8 @@ extern int button_mask; /* button state and info */ ...@@ -360,6 +362,8 @@ extern int button_mask; /* button state and info */
extern int button_mask_prev; extern int button_mask_prev;
extern int num_buttons; extern int num_buttons;
extern long xselectinput_rootwin;
extern unsigned int display_button_mask; extern unsigned int display_button_mask;
extern unsigned int display_mod_mask; extern unsigned int display_mod_mask;
......
...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0; ...@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0; int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */ /* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.4 lastmod: 2006-12-14"; char lastmod[] = "0.8.4 lastmod: 2006-12-17";
/* X display info */ /* X display info */
...@@ -36,6 +36,8 @@ int button_mask = 0; /* button state and info */ ...@@ -36,6 +36,8 @@ int button_mask = 0; /* button state and info */
int button_mask_prev = 0; int button_mask_prev = 0;
int num_buttons = -1; int num_buttons = -1;
long xselectinput_rootwin = 0;
unsigned int display_button_mask = 0; unsigned int display_button_mask = 0;
unsigned int display_mod_mask = 0; unsigned int display_mod_mask = 0;
......
...@@ -107,7 +107,8 @@ static void initialize_xevents(int reset) { ...@@ -107,7 +107,8 @@ static void initialize_xevents(int reset) {
* XXX: does this cause a flood of other stuff? * XXX: does this cause a flood of other stuff?
*/ */
X_LOCK; X_LOCK;
XSelectInput(dpy, rootwin, PropertyChangeMask); xselectinput_rootwin |= PropertyChangeMask;
XSelectInput(dpy, rootwin, xselectinput_rootwin);
X_UNLOCK; X_UNLOCK;
did_xselect_input = 1; did_xselect_input = 1;
} }
......
...@@ -382,11 +382,17 @@ void push_sleep(int n) { ...@@ -382,11 +382,17 @@ void push_sleep(int n) {
* try to forcefully push a black screen to all connected clients * try to forcefully push a black screen to all connected clients
*/ */
void push_black_screen(int n) { void push_black_screen(int n) {
int Lx = dpy_x, Ly = dpy_y;
if (!screen) { if (!screen) {
return; return;
} }
zero_fb(0, 0, dpy_x, dpy_y); #ifndef NO_NCACHE
mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); if (ncache > 0) {
Ly = dpy_y * (1+ncache);
}
#endif
zero_fb(0, 0, Lx, Ly);
mark_rect_as_modified(0, 0, Lx, Ly, 0);
push_sleep(n); push_sleep(n);
} }
...@@ -406,13 +412,19 @@ void refresh_screen(int push) { ...@@ -406,13 +412,19 @@ void refresh_screen(int push) {
*/ */
void zero_fb(int x1, int y1, int x2, int y2) { void zero_fb(int x1, int y1, int x2, int y2) {
int pixelsize = bpp/8; int pixelsize = bpp/8;
int line, fill = 0; int line, fill = 0, yfac = 1;
char *dst; char *dst;
#ifndef NO_NCACHE
if (ncache > 0) {
yfac = 1+ncache;
}
#endif
if (x1 < 0 || x2 <= x1 || x2 > dpy_x) { if (x1 < 0 || x2 <= x1 || x2 > dpy_x) {
return; return;
} }
if (y1 < 0 || y2 <= y1 || y2 > dpy_y) { if (y1 < 0 || y2 <= y1 || y2 > yfac * dpy_y) {
return; return;
} }
if (! main_fb) { if (! main_fb) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment