diff options
author | runge <runge> | 2005-04-19 20:55:46 +0000 |
---|---|---|
committer | runge <runge> | 2005-04-19 20:55:46 +0000 |
commit | 014e911f6bece702bb0d05f6e5cddb7298862549 (patch) | |
tree | bfdfce3f740737d9b2e659f5ccb895ec025fa364 /x11vnc/x11vnc.c | |
parent | c46cdf9493565a8809ba130f4d0b420bc055f157 (diff) | |
download | libtdevnc-014e911f6bece702bb0d05f6e5cddb7298862549.tar.gz libtdevnc-014e911f6bece702bb0d05f6e5cddb7298862549.zip |
x11vnc: -wireframe, -wirecopyrect, -privremote, -safer, -nocmd, -unsafe, -noviewonly
Diffstat (limited to 'x11vnc/x11vnc.c')
-rw-r--r-- | x11vnc/x11vnc.c | 2242 |
1 files changed, 1956 insertions, 286 deletions
diff --git a/x11vnc/x11vnc.c b/x11vnc/x11vnc.c index bd06c44..e09d9ca 100644 --- a/x11vnc/x11vnc.c +++ b/x11vnc/x11vnc.c @@ -436,7 +436,7 @@ int xdamage_tile_count; /* date +'lastmod: %Y-%m-%d' */ -char lastmod[] = "0.7.2 lastmod: 2005-04-11"; +char lastmod[] = "0.7.2 lastmod: 2005-04-19"; int hack_val = 0; /* X display info */ @@ -452,6 +452,7 @@ int off_x, off_y; /* offsets for -sid */ int wdpy_x, wdpy_y; /* for actual sizes in case of -clip */ int cdpy_x, cdpy_y, coff_x, coff_y; /* the -clip params */ int button_mask = 0; /* button state and info */ +int button_mask_prev = 0; int num_buttons = -1; /* image structures */ @@ -569,6 +570,7 @@ int clients_served = 0; /* more transient kludge variables: */ int cursor_x, cursor_y; /* x and y from the viewer(s) */ +int button_change_x, button_change_y; int got_user_input = 0; int got_pointer_input = 0; int got_keyboard_input = 0; @@ -683,6 +685,8 @@ void pipe_pointer(int mask, int x, int y, rfbClientPtr client); int check_pipeinput(void); void cursor_position(int, int); +void parse_wireframe(void); +void set_wirecopyrect_mode(char *); void read_vnc_connect_prop(void); void set_vnc_connect_prop(char *); char *process_remote_cmd(char *, int); @@ -725,6 +729,7 @@ int get_read_rate(void); int get_net_rate(void); int get_net_latency(void); void measure_send_rates(int); +int fb_update_sent(int *); int get_remote_port(int sock); int get_local_port(int sock); @@ -785,7 +790,10 @@ int connect_once = 0; #endif int deny_all = 0; /* global locking of new clients */ int accept_remote_cmds = 1; /* -noremote */ -int safe_remote_only = 0; /* -safer, -unsafe */ +int safe_remote_only = 1; /* -unsafe */ +int priv_remote = 0; /* -privremote */ +int more_safe = 0; /* -safer */ +int no_external_cmds = 0; /* -nocmds */ int started_as_root = 0; int host_lookup = 1; char *users_list = NULL; /* -users */ @@ -820,6 +828,7 @@ unsigned long subwin = 0x0; /* -id, -sid */ int subwin_wait_mapped = 0; int debug_xevents = 0; /* -R debug_xevents:1 */ +int debug_xdamage = 0; /* -R debug_xdamage:1 or 2 ... */ int xtrap_input = 0; /* -xtrap for user input insertion */ int xinerama = 0; /* -xinerama */ @@ -846,6 +855,20 @@ int cursor_pos_updates = 1; /* cursor position updates -cursorpos */ int cursor_shape_updates = 1; /* cursor shape updates -nocursorshape */ int use_xwarppointer = 0; /* use XWarpPointer instead of XTestFake... */ int show_dragging = 1; /* process mouse movement events */ +#ifndef WIREFRAME +#define WIREFRAME 1 +#endif +int wireframe = WIREFRAME; /* try to emulate wireframe wm moves */ +/* shade,linewidth,percent,T+B+L+R,t1+t2+t3+t4 */ +#ifndef WIREFRAME_PARMS +#define WIREFRAME_PARMS "0xff,3,0,32+8+8+8,0.15+0.35+4.0+0.1" +#endif +char *wireframe_str = NULL; +char *wireframe_copyrect = NULL; +char *wireframe_copyrect_default = "always"; +int wireframe_in_progress = 0; +Window *stack_list = NULL; +int stack_num = 0; int no_autorepeat = 1; /* turn off autorepeat with clients */ int no_repeat_countdown = 2; int watch_bell = 1; /* watch for the bell using XKEYBOARD */ @@ -923,6 +946,7 @@ int got_alwaysshared = 0; int got_nevershared = 0; int got_cursorpos = 0; int got_pointer_mode = -1; +int got_noviewonly = 0; /* threaded vs. non-threaded (default) */ #if LIBVNCSERVER_X11VNC_THREADED && ! defined(X11VNC_THREADED) @@ -1074,6 +1098,12 @@ int pick_windowid(unsigned long *num) { if (use_dpy) { set_env("DISPLAY", use_dpy); } + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", "xwininfo"); + rfbLog(" exiting.\n"); + clean_up_exit(1); + } p = popen("xwininfo", "r"); if (! p) { @@ -2707,9 +2737,7 @@ void clean_up_exit (int ret) { /* remove the shm areas: */ clean_shm(0); - if (! dpy) { - exit(ret); /* raw_rb hack */ - } + if (! dpy) exit(ret); /* raw_rb hack */ /* X keyboard cleanups */ delete_added_keycodes(); @@ -2878,14 +2906,20 @@ void interrupted (int sig) { } /* trapping utility to check for a valid window: */ -int valid_window(Window win) { +int valid_window(Window win, XWindowAttributes *attr_ret) { XErrorHandler old_handler; - XWindowAttributes attr; + XWindowAttributes attr, *pattr; int ok = 0; + if (attr_ret == NULL) { + pattr = &attr; + } else { + pattr = attr_ret; + } + trapped_xerror = 0; old_handler = XSetErrorHandler(trap_xerror); - if (XGetWindowAttributes(dpy, win, &attr)) { + if (XGetWindowAttributes(dpy, win, pattr)) { ok = 1; } if (trapped_xerror && trapped_xerror_event && ! quiet) { @@ -2904,7 +2938,7 @@ int wait_until_mapped(Window win) { XWindowAttributes attr; while (1) { - if (! valid_window(win)) { + if (! valid_window(win, NULL)) { if (time(0) > start + waittime) { return 0; } @@ -3219,7 +3253,6 @@ void set_child_info(void) { * used by, e.g., accept_client() and client_gone() */ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { - char *dpystr = DisplayString(dpy); char *old_display = NULL; char *addr = client->host; char str[100]; @@ -3285,7 +3318,12 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { if (getenv("DISPLAY")) { old_display = strdup(getenv("DISPLAY")); } - set_env("DISPLAY", dpystr); + + if (raw_fb && ! dpy) { /* raw_fb hack */ + set_env("DISPLAY", "rawfb"); + } else { + set_env("DISPLAY", DisplayString(dpy)); + } /* * work out the number of clients (have to use client_count @@ -3294,6 +3332,12 @@ static int run_user_command(char *cmd, rfbClientPtr client, char *mode) { sprintf(str, "%d", client_count); set_env("RFB_CLIENT_COUNT", str); + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", cmd); + rfbLog(" exiting.\n"); + clean_up_exit(1); + } rfbLog("running command:\n"); rfbLog(" %s\n", cmd); @@ -3576,6 +3620,8 @@ static char t2x2_bits[] = { int No_x = 75, No_y = 0, No_w = 45, No_h = 20; int Vi_x = 130, Vi_y = 0, Vi_w = 45, Vi_h = 20; + if (raw_fb && ! dpy) return 0; /* raw_fb hack */ + if (!strcmp(mode, "mouse_only")) { str1 = str1_m; str2 = str2_m; @@ -4587,6 +4633,8 @@ void autorepeat(int restore) { XKeyboardControl kctrl; static int save_auto_repeat = -1; + if (raw_fb && ! dpy) return; /* raw_fb hack */ + if (restore) { if (save_auto_repeat < 0) { return; /* nothing to restore */ @@ -4633,6 +4681,8 @@ int add_keysym(KeySym keysym) { static int first = 1; KeySym *keymap; + if (raw_fb && ! dpy) return 0; /* raw_fb hack */ + if (first) { for (n=0; n < 0x100; n++) { added_keysyms[n] = NoSymbol; @@ -4703,6 +4753,8 @@ void delete_keycode(KeyCode kc) { KeySym ksym, new[8]; char *str; + if (raw_fb && ! dpy) return; /* raw_fb hack */ + XDisplayKeycodes(dpy, &minkey, &maxkey); keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1), &syms_per_keycode); @@ -5728,6 +5780,7 @@ void initialize_allowed_input(void) { } void initialize_keyboard_and_pointer(void) { + if (raw_fb && ! dpy) return; /* raw_fb hack */ if (use_modifier_tweak) { @@ -6070,6 +6123,8 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) { got_user_input++; got_keyboard_input++; + if (raw_fb && ! dpy) return; /* raw_fb hack */ + if (keyremaps) { keyremap_t *remap = keyremaps; while (remap != NULL) { @@ -6398,10 +6453,31 @@ void initialize_pointer_map(char *pointer_remap) { } /* + * For use in the -wireframe stuff, save the stacking order of the direct + * children of the root window. Ideally done before we send ButtonPress + * to the X server. + */ +void snapshot_stack_list(void) { + Window r, w; + if (stack_list) { + XFree(stack_list); + stack_list = NULL; + stack_num = 0; + } + XSync(dpy, False); + if (! XQueryTree(dpy, rootwin, &r, &w, &stack_list, &stack_num)) { + stack_list = NULL; + stack_num = 0; + } +} + +/* * Send a pointer position event to the X server. */ static void update_x11_pointer_position(int x, int y) { + if (raw_fb && ! dpy) return; /* raw_fb hack */ + X_LOCK; if (use_xwarppointer) { /* @@ -6426,16 +6502,6 @@ static void update_x11_pointer_position(int x, int y) { set_cursor(x, y, get_which_cursor()); last_event = last_input = time(0); - - if (nofb) { - /* - * nofb is for, e.g. Win2VNC, where fastest pointer - * updates are desired. - */ - X_LOCK; - XFlush(dpy); - X_UNLOCK; - } } /* @@ -6446,7 +6512,17 @@ static void update_x11_pointer_mask(int mask) { last_event = last_input = time(0); + if (raw_fb && ! dpy) return; /* raw_fb hack */ + X_LOCK; + if (mask && !button_mask) { + /* button down, snapshot the stacking list before flushing */ + if (wireframe && !wireframe_in_progress && + strcmp(wireframe_copyrect, "never")) { + snapshot_stack_list(); + } + } + /* look for buttons that have be clicked or released: */ for (i=0; i < MAX_BUTTONS; i++) { if ( (button_mask & (1<<i)) != (mask & (1<<i)) ) { @@ -6511,12 +6587,14 @@ static void update_x11_pointer_mask(int mask) { } } + X_UNLOCK; /* * Remember the button state for next time and also for the * -nodragging case: */ + button_mask_prev = button_mask; button_mask = mask; } @@ -6589,6 +6667,7 @@ void pipe_pointer(int mask, int x, int y, rfbClientPtr client) { */ void pointer(int mask, int x, int y, rfbClientPtr client) { allowed_input_t input; + int sent = 0; if (debug_pointer && mask >= 0) { static int show_motion = -1; @@ -6623,6 +6702,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) { } if (view_only && raw_fb) { /* raw_fb hack track button state */ + button_mask_prev = button_mask; button_mask = mask; } return; @@ -6725,7 +6805,9 @@ void pointer(int mask, int x, int y, rfbClientPtr client) { } if (nevents && dt > maxwait) { X_LOCK; - XFlush(dpy); + if (dpy) { /* raw_fb hack */ + XFlush(dpy); + } X_UNLOCK; } nevents = 0; /* reset everything */ @@ -6745,9 +6827,25 @@ void pointer(int mask, int x, int y, rfbClientPtr client) { /* update the X display with the event: */ if (input.motion) { update_x11_pointer_position(x, y); + sent = 1; } if (input.button) { + if (mask != button_mask) { + button_change_x = cursor_x; + button_change_y = cursor_y; + } update_x11_pointer_mask(mask); + sent = 1; + } + + if (nofb && sent) { + /* + * nofb is for, e.g. Win2VNC, where fastest pointer + * updates are desired. + */ + X_LOCK; + XFlush(dpy); + X_UNLOCK; } } @@ -6830,6 +6928,12 @@ void initialize_pipeinput(void) { } set_child_info(); + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", p); + rfbLog(" exiting.\n"); + clean_up_exit(1); + } rfbLog("pipeinput: starting: \"%s\"...\n", p); pipeinput_fh = popen(p, "w"); @@ -7123,7 +7227,7 @@ int handle_subwin_resize(char *msg) { if (! subwin) { return 0; /* hmmm... */ } - if (! valid_window(subwin)) { + if (! valid_window(subwin, NULL)) { rfbLog("subwin 0x%lx went away!\n", subwin); X_UNLOCK; clean_up_exit(1); @@ -7625,9 +7729,8 @@ void check_xevents(void) { static time_t last_sync = 0; time_t now = time(0); - if (! dpy) { /* raw_fb hack */ - return; - } + if (raw_fb && ! dpy) return; /* raw_fb hack */ + if (now > last_init_check+1) { last_init_check = now; initialize_xevents(); @@ -7838,7 +7941,7 @@ void check_xevents(void) { } if (now > last_check + 1) { - int ev_max = 300, ev_size = 400; + int ev_type_max = 300, ev_size = 400; XEvent xevs[400]; int i, tot = XEventsQueued(dpy, QueuedAlready); @@ -7852,7 +7955,7 @@ void check_xevents(void) { fprintf(stderr, "Total events queued: %d\n", tot); } - for (i=1; i<ev_max; i++) { + for (i=1; i<ev_type_max; i++) { int k, n = 0; while (XCheckTypedEvent(dpy, i, xevs+n)) { if (++n >= ev_size) { @@ -7860,8 +7963,9 @@ void check_xevents(void) { } } if (n) { - fprintf(stderr, " %d events of type %d" - " queued\n", n, i); + fprintf(stderr, " %d%s events of type" + " %d queued\n", n, + (n >= ev_size) ? "+" : "", i); } for (k=n-1; k >= 0; k--) { XPutBackEvent(dpy, xevs+k); @@ -7897,6 +8001,8 @@ void check_xevents(void) { void xcut_receive(char *text, int len, rfbClientPtr cl) { allowed_input_t input; + if (raw_fb && ! dpy) return; /* raw_fb hack */ + if (!watch_selection) { return; } @@ -8326,6 +8432,105 @@ void reset_rfbport(int old, int new) { } /* + * Do some sanity checking of the permissions on the XAUTHORITY and the + * -connect file. This is -privremote. What should be done is check + * for an empty host access list, currently we lazily do not bring in + * libXau yet. + */ +int remote_control_access_ok(void) { + struct stat sbuf; + + if (client_connect_file) { + if (stat(client_connect_file, &sbuf) == 0) { + if (sbuf.st_mode & S_IWOTH) { + rfbLog("connect file is writable by others.\n"); + rfbLog(" %s\n", client_connect_file); + return 0; + } + if (sbuf.st_mode & S_IWGRP) { + rfbLog("connect file is writable by group.\n"); + rfbLog(" %s\n", client_connect_file); + return 0; + } + } + } + + if (dpy) { + char tmp[1000]; + char *home, *xauth; + char *dpy_str = DisplayString(dpy); + Display *dpy2; + + home = get_home_dir(); + if (getenv("XAUTHORITY") != NULL) { + xauth = getenv("XAUTHORITY"); + } else if (home) { + int len = 1000 - strlen("/.Xauthority") - 1; + strncpy(tmp, home, len); + strcat(tmp, "/.Xauthority"); + xauth = tmp; + } else { + rfbLog("cannot determine default XAUTHORITY.\n"); + return 0; + } + if (home) { + free(home); + } + if (stat(xauth, &sbuf) == 0) { + if (sbuf.st_mode & S_IWOTH) { + rfbLog("XAUTHORITY is writable by others!!\n"); + rfbLog(" %s\n", xauth); + return 0; + } + if (sbuf.st_mode & S_IWGRP) { + rfbLog("XAUTHORITY is writable by group!!\n"); + rfbLog(" %s\n", xauth); + return 0; + } + if (sbuf.st_mode & S_IROTH) { + rfbLog("XAUTHORITY is readable by others.\n"); + rfbLog(" %s\n", xauth); + return 0; + } + if (sbuf.st_mode & S_IRGRP) { + rfbLog("XAUTHORITY is readable by group.\n"); + rfbLog(" %s\n", xauth); + return 0; + } + } + + if (getenv("XAUTHORITY")) { + xauth = strdup(getenv("XAUTHORITY")); + } else { + xauth = NULL; + } + set_env("XAUTHORITY", "/impossible/xauthfile"); + + fprintf(stderr, "\nChecking if display %s requires " + "XAUTHORITY\n", dpy_str); + fprintf(stderr, " (ignore any Xlib: errors that follow)\n"); + dpy2 = XOpenDisplay(dpy_str); + + if (xauth) { + set_env("XAUTHORITY", xauth); + free(xauth); + } else { + xauth = getenv("XAUTHORITY"); + if (xauth) { + *(xauth-2) = '_'; /* yow */ + } + } + if (dpy2) { + rfbLog("XAUTHORITY is not required on display.\n"); + rfbLog(" %s\n", DisplayString(dpy)); + XCloseDisplay(dpy2); + return 0; + } + } + return 1; +} + +/* * Huge, ugly switch to handle all remote commands and queries * -remote/-R and -query/-Q. */ @@ -8337,12 +8542,23 @@ char *process_remote_cmd(char *cmd, int stringonly) { int bufn = VNC_CONNECT_MAX; int query = 0; static char *prev_cursors_mode = NULL; + static int first = 1; if (! accept_remote_cmds) { rfbLog("remote commands disabled: %s\n", cmd); return NULL; } + if (first && priv_remote) { + if (! remote_control_access_ok()) { + rfbLog("disabling remote commands in -privremote " + "mode.\n"); + accept_remote_cmds = 0; + return NULL; + } + } + first = 0; + strcpy(buf, ""); if (strstr(cmd, "cmd=") == cmd) { p += strlen("cmd="); @@ -8425,7 +8641,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !strcmp(p, "exit") || !strcmp(p, "shutdown")) { NOTAPP close_all_clients(); - rfbLog("process_remote_cmd: setting shut_down flag\n"); + rfbLog("remote_cmd: setting shut_down flag\n"); shut_down = 1; } else if (!strcmp(p, "ping")) { @@ -8515,7 +8731,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ok = 1; } if (ok) { - if (twin && ! valid_window(twin)) { + if (twin && ! valid_window(twin, NULL)) { rfbLog("skipping invalid sub-window: 0x%lx\n", twin); } else { @@ -8552,7 +8768,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { ok = 1; } if (ok) { - if (twin && ! valid_window(twin)) { + if (twin && ! valid_window(twin, NULL)) { rfbLog("skipping invalid sub-window: 0x%lx\n", twin); } else { @@ -8596,14 +8812,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, flash_cmap); goto qry; } - rfbLog("process_remote_cmd: turning on flashcmap mode.\n"); + rfbLog("remote_cmd: turning on flashcmap mode.\n"); flash_cmap = 1; } else if (!strcmp(p, "noflashcmap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !flash_cmap); goto qry; } - rfbLog("process_remote_cmd: turning off flashcmap mode.\n"); + rfbLog("remote_cmd: turning off flashcmap mode.\n"); flash_cmap = 0; } else if (strstr(p, "shiftcmap") == p) { @@ -8614,7 +8830,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("shiftcmap:"); shift_cmap = atoi(p); - rfbLog("process_remote_cmd: set -shiftcmap %d\n", shift_cmap); + rfbLog("remote_cmd: set -shiftcmap %d\n", shift_cmap); do_new_fb(1); } else if (!strcmp(p, "truecolor")) { @@ -8624,7 +8840,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !force_indexed_color); goto qry; } - rfbLog("process_remote_cmd: turning off notruecolor mode.\n"); + rfbLog("remote_cmd: turning off notruecolor mode.\n"); force_indexed_color = 0; if (orig != force_indexed_color) { if_8bpp_do_new_fb(); @@ -8636,7 +8852,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { force_indexed_color); goto qry; } - rfbLog("process_remote_cmd: turning on notruecolor mode.\n"); + rfbLog("remote_cmd: turning on notruecolor mode.\n"); force_indexed_color = 1; if (orig != force_indexed_color) { if_8bpp_do_new_fb(); @@ -8647,7 +8863,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, overlay); goto qry; } - rfbLog("process_remote_cmd: turning on -overlay mode.\n"); + rfbLog("remote_cmd: turning on -overlay mode.\n"); if (!overlay_present) { rfbLog("skipping: overlay extension not present.\n"); } else if (overlay) { @@ -8669,7 +8885,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !overlay); goto qry; } - rfbLog("process_remote_cmd: turning off overlay mode\n"); + rfbLog("remote_cmd: turning off overlay mode\n"); overlay = 0; if (!overlay_present) { rfbLog("warning: overlay extension not present.\n"); @@ -8687,7 +8903,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, overlay_cursor); goto qry; } - rfbLog("process_remote_cmd: turning on overlay_cursor mode.\n"); + rfbLog("remote_cmd: turning on overlay_cursor mode.\n"); overlay_cursor = 1; if (!overlay_present) { rfbLog("warning: overlay extension not present.\n"); @@ -8705,7 +8921,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !overlay_cursor); goto qry; } - rfbLog("process_remote_cmd: turning off overlay_cursor mode\n"); + rfbLog("remote_cmd: turning off overlay_cursor mode\n"); overlay_cursor = 0; if (!overlay_present) { rfbLog("warning: overlay extension not present.\n"); @@ -8768,14 +8984,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, view_only); goto qry; } - rfbLog("process_remote_cmd: enable viewonly mode.\n"); + rfbLog("remote_cmd: enable viewonly mode.\n"); view_only = 1; } else if (!strcmp(p, "noviewonly")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !view_only); goto qry; } - rfbLog("process_remote_cmd: disable viewonly mode.\n"); + rfbLog("remote_cmd: disable viewonly mode.\n"); view_only = 0; if (raw_fb) set_raw_fb_params(0); @@ -8783,7 +8999,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, shared); goto qry; } - rfbLog("process_remote_cmd: enable sharing.\n"); + rfbLog("remote_cmd: enable sharing.\n"); shared = 1; if (screen) { screen->alwaysShared = TRUE; @@ -8793,7 +9009,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !shared); goto qry; } - rfbLog("process_remote_cmd: disable sharing.\n"); + rfbLog("remote_cmd: disable sharing.\n"); shared = 0; if (screen) { screen->alwaysShared = FALSE; @@ -8805,14 +9021,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, 1-connect_once); goto qry; } - rfbLog("process_remote_cmd: enable -forever mode.\n"); + rfbLog("remote_cmd: enable -forever mode.\n"); connect_once = 0; } else if (!strcmp(p, "noforever") || !strcmp(p, "once")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, connect_once); goto qry; } - rfbLog("process_remote_cmd: disable -forever mode.\n"); + rfbLog("remote_cmd: disable -forever mode.\n"); connect_once = 1; } else if (strstr(p, "timeout") == p) { @@ -8829,21 +9045,21 @@ char *process_remote_cmd(char *cmd, int stringonly) { to = -to; } first_conn_timeout = to; - rfbLog("process_remote_cmd: set -timeout to %d\n", -to); + rfbLog("remote_cmd: set -timeout to %d\n", -to); } else if (!strcmp(p, "deny") || !strcmp(p, "lock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, deny_all); goto qry; } - rfbLog("process_remote_cmd: denying new connections.\n"); + rfbLog("remote_cmd: denying new connections.\n"); deny_all = 1; } else if (!strcmp(p, "nodeny") || !strcmp(p, "unlock")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !deny_all); goto qry; } - rfbLog("process_remote_cmd: allowing new connections.\n"); + rfbLog("remote_cmd: allowing new connections.\n"); deny_all = 0; } else if (strstr(p, "connect") == p) { @@ -8862,7 +9078,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("allowonce:"); allow_once = strdup(p); - rfbLog("process_remote_cmd: set allow_once %s\n", allow_once); + rfbLog("remote_cmd: set allow_once %s\n", allow_once); } else if (strstr(p, "allow") == p) { char *before, *old; @@ -8874,7 +9090,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("allow:"); if (allow_list && strchr(allow_list, '/')) { - rfbLog("process_remote_cmd: cannot use allow:host\n"); + rfbLog("remote_cmd: cannot use allow:host\n"); rfbLog("in '-allow %s' mode.\n", allow_list); goto done; } @@ -8896,7 +9112,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } if (strcmp(before, allow_list)) { - rfbLog("process_remote_cmd: modified allow_list:\n"); + rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } @@ -8925,7 +9141,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { allow_list = strdup("127.0.0.1"); if (strcmp(before, allow_list)) { - rfbLog("process_remote_cmd: modified allow_list:\n"); + rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } @@ -8966,7 +9182,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { allow_list = strdup(""); if (strcmp(before, allow_list)) { - rfbLog("process_remote_cmd: modified allow_list:\n"); + rfbLog("remote_cmd: modified allow_list:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", allow_list); } @@ -9006,7 +9222,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { listen_str = strdup(p); if (strcmp(before, listen_str)) { - rfbLog("process_remote_cmd: modified listen_str:\n"); + rfbLog("remote_cmd: modified listen_str:\n"); rfbLog(" from: \"%s\"\n", before); rfbLog(" to: \"%s\"\n", listen_str); mod = 1; @@ -9079,14 +9295,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, host_lookup); goto qry; } - rfbLog("process_remote_cmd: enabling hostname lookup.\n"); + rfbLog("remote_cmd: enabling hostname lookup.\n"); host_lookup = 1; } else if (!strcmp(p, "nolookup")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !host_lookup); goto qry; } - rfbLog("process_remote_cmd: disabling hostname lookup.\n"); + rfbLog("remote_cmd: disabling hostname lookup.\n"); host_lookup = 0; } else if (strstr(p, "accept") == p) { @@ -9125,7 +9341,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, using_shm); goto qry; } - rfbLog("process_remote_cmd: turning off noshm mode.\n"); + rfbLog("remote_cmd: turning off noshm mode.\n"); using_shm = 1; if (raw_fb) set_raw_fb_params(0); @@ -9140,7 +9356,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !using_shm); goto qry; } - rfbLog("process_remote_cmd: turning on noshm mode.\n"); + rfbLog("remote_cmd: turning on noshm mode.\n"); using_shm = 0; if (orig != using_shm) { do_new_fb(1); @@ -9154,7 +9370,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, flip_byte_order); goto qry; } - rfbLog("process_remote_cmd: turning on flipbyteorder mode.\n"); + rfbLog("remote_cmd: turning on flipbyteorder mode.\n"); flip_byte_order = 1; if (orig != flip_byte_order) { if (! using_shm) { @@ -9169,7 +9385,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !flip_byte_order); goto qry; } - rfbLog("process_remote_cmd: turning off flipbyteorder mode.\n"); + rfbLog("remote_cmd: turning off flipbyteorder mode.\n"); flip_byte_order = 0; if (orig != flip_byte_order) { if (! using_shm) { @@ -9184,14 +9400,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, single_copytile); goto qry; } - rfbLog("process_remote_cmd: enable -onetile mode.\n"); + rfbLog("remote_cmd: enable -onetile mode.\n"); single_copytile = 1; } else if (!strcmp(p, "noonetile")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !single_copytile); goto qry; } - rfbLog("process_remote_cmd: disable -onetile mode.\n"); + rfbLog("remote_cmd: disable -onetile mode.\n"); if (tile_shm_count < ntiles_x) { rfbLog(" this has no effect: tile_shm_count=%d" " ntiles_x=%d\n", tile_shm_count, ntiles_x); @@ -9200,6 +9416,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { single_copytile = 0; } else if (strstr(p, "solid_color") == p) { + /* + * n.b. this solid stuff perhaps should reflect + * safe_remote_only but at least the command names + * are fixed. + */ char *new; int doit = 1; COLON_CHECK("solid_color:") @@ -9214,8 +9435,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } else { new = strdup(solid_default); } - rfbLog("process_remote_cmd: solid %s -> %s\n", - NONUL(solid_str), new); + rfbLog("remote_cmd: solid %s -> %s\n", NONUL(solid_str), new); if (solid_str) { if (!strcmp(solid_str, new)) { @@ -9236,7 +9456,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, use_solid_bg); goto qry; } - rfbLog("process_remote_cmd: enable -solid mode\n"); + rfbLog("remote_cmd: enable -solid mode\n"); if (! solid_str) { solid_str = strdup(solid_default); } @@ -9251,7 +9471,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !use_solid_bg); goto qry; } - rfbLog("process_remote_cmd: disable -solid mode\n"); + rfbLog("remote_cmd: disable -solid mode\n"); use_solid_bg = 0; if (client_count && orig) { solid_bg(1); @@ -9282,7 +9502,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { blackout_str = strdup(p); } if (strcmp(before, blackout_str)) { - rfbLog("process_remote_cmd: changing -blackout\n"); + rfbLog("remote_cmd: changing -blackout\n"); rfbLog(" from: %s\n", before); rfbLog(" to: %s\n", blackout_str); if (0 && !strcmp(blackout_str, "") && @@ -9301,8 +9521,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, xinerama); goto qry; } - rfbLog("process_remote_cmd: enable xinerama mode." - "(if applicable).\n"); + rfbLog("remote_cmd: enable xinerama mode. (if applicable).\n"); xinerama = 1; initialize_blackouts_and_xinerama(); } else if (!strcmp(p, "noxinerama")) { @@ -9310,8 +9529,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !xinerama); goto qry; } - rfbLog("process_remote_cmd: disable xinerama mode." - "(if applicable).\n"); + rfbLog("remote_cmd: disable xinerama mode. (if applicable).\n"); xinerama = 0; initialize_blackouts_and_xinerama(); @@ -9320,7 +9538,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, xtrap_input); goto qry; } - rfbLog("process_remote_cmd: enable xtrap input mode." + rfbLog("remote_cmd: enable xtrap input mode." "(if applicable).\n"); if (! xtrap_input) { xtrap_input = 1; @@ -9332,7 +9550,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !xtrap_input); goto qry; } - rfbLog("process_remote_cmd: disable xtrap input mode." + rfbLog("remote_cmd: disable xtrap input mode." "(if applicable).\n"); if (xtrap_input) { xtrap_input = 0; @@ -9345,7 +9563,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, xrandr); goto qry; } if (xrandr_present) { - rfbLog("process_remote_cmd: enable xrandr mode.\n"); + rfbLog("remote_cmd: enable xrandr mode.\n"); xrandr = 1; if (raw_fb) set_raw_fb_params(0); if (! xrandr_mode) { @@ -9355,8 +9573,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { initialize_xrandr(); } } else { - rfbLog("process_remote_cmd: XRANDR ext. not " - "present.\n"); + rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (!strcmp(p, "noxrandr")) { int orig = xrandr; @@ -9365,13 +9582,12 @@ char *process_remote_cmd(char *cmd, int stringonly) { } xrandr = 0; if (xrandr_present) { - rfbLog("process_remote_cmd: disable xrandr mode.\n"); + rfbLog("remote_cmd: disable xrandr mode.\n"); if (orig != xrandr) { initialize_xrandr(); } } else { - rfbLog("process_remote_cmd: XRANDR ext. not " - "present.\n"); + rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (strstr(p, "xrandr_mode") == p) { int orig = xrandr; @@ -9396,11 +9612,9 @@ char *process_remote_cmd(char *cmd, int stringonly) { } if (xrandr_present) { if (xrandr) { - rfbLog("process_remote_cmd: enable xrandr" - " mode.\n"); + rfbLog("remote_cmd: enable xrandr mode.\n"); } else { - rfbLog("process_remote_cmd: disable xrandr" - " mode.\n"); + rfbLog("remote_cmd: disable xrandr mode.\n"); } if (! xrandr_mode) { xrandr_mode = strdup("default"); @@ -9409,8 +9623,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { initialize_xrandr(); } } else { - rfbLog("process_remote_cmd: XRANDR ext. not " - "present.\n"); + rfbLog("remote_cmd: XRANDR ext. not present.\n"); } } else if (strstr(p, "padgeom") == p) { @@ -9422,13 +9635,12 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("padgeom:"); if (!strcmp("force", p) || !strcmp("do",p) || !strcmp("go",p)) { - rfbLog("process_remote_cmd: invoking " - "install_padded_fb()\n"); + rfbLog("remote_cmd: invoking install_padded_fb()\n"); install_padded_fb(pad_geometry); } else { if (pad_geometry) free(pad_geometry); pad_geometry = strdup(p); - rfbLog("process_remote_cmd: set padgeom to: %s\n", + rfbLog("remote_cmd: set padgeom to: %s\n", pad_geometry); } @@ -9436,13 +9648,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, quiet); goto qry; } - rfbLog("process_remote_cmd: turning on quiet mode.\n"); + rfbLog("remote_cmd: turning on quiet mode.\n"); quiet = 1; } else if (!strcmp(p, "noquiet")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !quiet); goto qry; } - rfbLog("process_remote_cmd: turning off quiet mode.\n"); + rfbLog("remote_cmd: turning off quiet mode.\n"); quiet = 0; } else if (!strcmp(p, "modtweak")) { @@ -9450,7 +9662,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, use_modifier_tweak); goto qry; } - rfbLog("process_remote_cmd: enabling -modtweak mode.\n"); + rfbLog("remote_cmd: enabling -modtweak mode.\n"); if (! use_modifier_tweak) { use_modifier_tweak = 1; initialize_modtweak(); @@ -9463,7 +9675,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !use_modifier_tweak); goto qry; } - rfbLog("process_remote_cmd: enabling -nomodtweak mode.\n"); + rfbLog("remote_cmd: enabling -nomodtweak mode.\n"); use_modifier_tweak = 0; } else if (!strcmp(p, "xkb")) { @@ -9472,11 +9684,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xkb_present) { - rfbLog("process_remote_cmd: cannot enable -xkb " + rfbLog("remote_cmd: cannot enable -xkb " "modtweak mode (not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: enabling -xkb modtweak mode" + rfbLog("remote_cmd: enabling -xkb modtweak mode" " (if supported).\n"); if (! use_modifier_tweak || ! use_xkb_modtweak) { use_modifier_tweak = 1; @@ -9492,11 +9704,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xkb_present) { - rfbLog("process_remote_cmd: cannot disable -xkb " + rfbLog("remote_cmd: cannot disable -xkb " "modtweak mode (not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: disabling -xkb modtweak mode.\n"); + rfbLog("remote_cmd: disabling -xkb modtweak mode.\n"); use_xkb_modtweak = 0; } else if (strstr(p, "skip_keycodes") == p) { @@ -9507,16 +9719,15 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } p += strlen("skip_keycodes:"); - rfbLog("process_remote_cmd: setting xkb -skip_keycodes" + rfbLog("remote_cmd: setting xkb -skip_keycodes" " to:\n\t'%s'\n", p); if (! xkb_present) { - rfbLog("process_remote_cmd: warning xkb not present\n"); + rfbLog("remote_cmd: warning xkb not present\n"); } else if (! use_xkb_modtweak) { - rfbLog("process_remote_cmd: turning on xkb.\n"); + rfbLog("remote_cmd: turning on xkb.\n"); use_xkb_modtweak = 1; if (! use_modifier_tweak) { - rfbLog("process_remote_cmd: turning on " - "modtweak.\n"); + rfbLog("remote_cmd: turning on modtweak.\n"); use_modifier_tweak = 1; } } @@ -9529,7 +9740,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, add_keysyms); goto qry; } - rfbLog("process_remote_cmd: enabling -add_keysyms mode.\n"); + rfbLog("remote_cmd: enabling -add_keysyms mode.\n"); add_keysyms = 1; } else if (!strcmp(p, "noadd_keysyms")) { @@ -9537,7 +9748,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !add_keysyms); goto qry; } - rfbLog("process_remote_cmd: disabling -add_keysyms mode.\n"); + rfbLog("remote_cmd: disabling -add_keysyms mode.\n"); add_keysyms = 0; } else if (!strcmp(p, "clear_mods")) { @@ -9545,7 +9756,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 1); goto qry; } - rfbLog("process_remote_cmd: enabling -clear_mods mode.\n"); + rfbLog("remote_cmd: enabling -clear_mods mode.\n"); clear_mods = 1; clear_modifiers(0); @@ -9555,7 +9766,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !(clear_mods == 1)); goto qry; } - rfbLog("process_remote_cmd: disabling -clear_mods mode.\n"); + rfbLog("remote_cmd: disabling -clear_mods mode.\n"); clear_mods = 0; } else if (!strcmp(p, "clear_keys")) { @@ -9564,7 +9775,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { clear_mods == 2); goto qry; } - rfbLog("process_remote_cmd: enabling -clear_keys mode.\n"); + rfbLog("remote_cmd: enabling -clear_keys mode.\n"); clear_mods = 2; clear_keys(); @@ -9574,7 +9785,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !(clear_mods == 2)); goto qry; } - rfbLog("process_remote_cmd: disabling -clear_keys mode.\n"); + rfbLog("remote_cmd: disabling -clear_keys mode.\n"); clear_mods = 0; } else if (strstr(p, "remap") == p) { @@ -9588,7 +9799,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("remap:"); if ((*p == '+' || *p == '-') && remap_file && strchr(remap_file, '/')) { - rfbLog("process_remote_cmd: cannot use remap:+/-\n"); + rfbLog("remote_cmd: cannot use remap:+/-\n"); rfbLog("in '-remap %s' mode.\n", remap_file); goto done; } @@ -9611,7 +9822,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { remap_file = strdup(p); } if (strcmp(before, remap_file)) { - rfbLog("process_remote_cmd: changed -remap\n"); + rfbLog("remote_cmd: changed -remap\n"); rfbLog(" from: %s\n", before); rfbLog(" to: %s\n", remap_file); initialize_remap(remap_file); @@ -9624,7 +9835,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !no_autorepeat); goto qry; } - rfbLog("process_remote_cmd: enabling -repeat mode.\n"); + rfbLog("remote_cmd: enabling -repeat mode.\n"); autorepeat(1); /* restore initial setting */ no_autorepeat = 0; @@ -9633,7 +9844,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, no_autorepeat); goto qry; } - rfbLog("process_remote_cmd: enabling -norepeat mode.\n"); + rfbLog("remote_cmd: enabling -norepeat mode.\n"); no_autorepeat = 1; if (no_repeat_countdown >= 0) { no_repeat_countdown = 2; @@ -9648,7 +9859,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (nofb) { - rfbLog("process_remote_cmd: disabling nofb mode.\n"); + rfbLog("remote_cmd: disabling nofb mode.\n"); rfbLog(" you may need to these turn back on:\n"); rfbLog(" xfixes, xdamage, solid, flashcmap\n"); rfbLog(" overlay, shm, noonetile, nap, cursor\n"); @@ -9662,7 +9873,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (!nofb) { - rfbLog("process_remote_cmd: enabling nofb mode.\n"); + rfbLog("remote_cmd: enabling nofb mode.\n"); if (main_fb) { push_black_screen(4); } @@ -9678,7 +9889,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, sound_bell); goto qry; } - rfbLog("process_remote_cmd: enabling bell (if supported).\n"); + rfbLog("remote_cmd: enabling bell (if supported).\n"); initialize_watch_bell(); sound_bell = 1; @@ -9687,7 +9898,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !sound_bell); goto qry; } - rfbLog("process_remote_cmd: disabling bell.\n"); + rfbLog("remote_cmd: disabling bell.\n"); initialize_watch_bell(); sound_bell = 0; @@ -9696,8 +9907,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, watch_selection); goto qry; } - rfbLog("process_remote_cmd: enabling watch " - "selection+primary.\n"); + rfbLog("remote_cmd: enabling watch selection+primary.\n"); watch_selection = 1; watch_primary = 1; @@ -9706,8 +9916,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_selection); goto qry; } - rfbLog("process_remote_cmd: disabling watch " - "selection+primary.\n"); + rfbLog("remote_cmd: disabling watch selection+primary.\n"); watch_selection = 0; watch_primary = 0; @@ -9716,7 +9925,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, watch_primary); goto qry; } - rfbLog("process_remote_cmd: enabling watch_primary.\n"); + rfbLog("remote_cmd: enabling watch_primary.\n"); watch_primary = 1; } else if (!strcmp(p, "noprimary")) { @@ -9724,11 +9933,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !watch_primary); goto qry; } - rfbLog("process_remote_cmd: disabling watch_primary.\n"); + rfbLog("remote_cmd: disabling watch_primary.\n"); watch_primary = 0; } else if (!strcmp(p, "set_no_cursor")) { /* skip-cmd-list */ - rfbLog("process_remote_cmd: calling set_no_cursor()\n"); + rfbLog("remote_cmd: calling set_no_cursor()\n"); set_no_cursor(); } else if (!strcmp(p, "cursorshape")) { @@ -9737,7 +9946,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { cursor_shape_updates); goto qry; } - rfbLog("process_remote_cmd: turning on cursorshape mode.\n"); + rfbLog("remote_cmd: turning on cursorshape mode.\n"); set_no_cursor(); cursor_shape_updates = 1; @@ -9750,7 +9959,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !cursor_shape_updates); goto qry; } - rfbLog("process_remote_cmd: turning off cursorshape mode.\n"); + rfbLog("remote_cmd: turning off cursorshape mode.\n"); set_no_cursor(); for (i=0; i<max; i++) { @@ -9767,7 +9976,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { cursor_pos_updates); goto qry; } - rfbLog("process_remote_cmd: turning on cursorpos mode.\n"); + rfbLog("remote_cmd: turning on cursorpos mode.\n"); cursor_pos_updates = 1; } else if (!strcmp(p, "nocursorpos")) { if (query) { @@ -9775,7 +9984,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { !cursor_pos_updates); goto qry; } - rfbLog("process_remote_cmd: turning off cursorpos mode.\n"); + rfbLog("remote_cmd: turning off cursorpos mode.\n"); cursor_pos_updates = 0; } else if (strstr(p, "cursor") == p) { @@ -9793,12 +10002,12 @@ char *process_remote_cmd(char *cmd, int stringonly) { } multiple_cursors_mode = strdup(p); - rfbLog("process_remote_cmd: changed -cursor mode " + rfbLog("remote_cmd: changed -cursor mode " "to: %s\n", multiple_cursors_mode); if (strcmp(multiple_cursors_mode, "none") && !show_cursor) { show_cursor = 1; - rfbLog("process_remote_cmd: changed show_cursor " + rfbLog("remote_cmd: changed show_cursor " "to: %d\n", show_cursor); } initialize_cursors_mode(); @@ -9809,7 +10018,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, show_cursor); goto qry; } - rfbLog("process_remote_cmd: enabling show_cursor.\n"); + rfbLog("remote_cmd: enabling show_cursor.\n"); show_cursor = 1; if (multiple_cursors_mode && !strcmp(multiple_cursors_mode, "none")) { @@ -9820,7 +10029,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } else { multiple_cursors_mode = strdup("default"); } - rfbLog("process_remote_cmd: changed -cursor mode " + rfbLog("remote_cmd: changed -cursor mode " "to: %s\n", multiple_cursors_mode); } initialize_cursors_mode(); @@ -9833,7 +10042,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (prev_cursors_mode) free(prev_cursors_mode); prev_cursors_mode = strdup(multiple_cursors_mode); - rfbLog("process_remote_cmd: disabling show_cursor.\n"); + rfbLog("remote_cmd: disabling show_cursor.\n"); show_cursor = 0; initialize_cursors_mode(); first_cursor(); @@ -9846,8 +10055,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("arrow:"); alt_arrow = atoi(p); - rfbLog("process_remote_cmd: setting alt_arrow: %d.\n", - alt_arrow); + rfbLog("remote_cmd: setting alt_arrow: %d.\n", alt_arrow); setup_cursors_and_push(); } else if (!strcmp(p, "xfixes")) { @@ -9856,11 +10064,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xfixes_present) { - rfbLog("process_remote_cmd: cannot enable xfixes " + rfbLog("remote_cmd: cannot enable xfixes " "(not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: enabling -xfixes" + rfbLog("remote_cmd: enabling -xfixes" " (if supported).\n"); use_xfixes = 1; initialize_xfixes(); @@ -9871,11 +10079,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xfixes_present) { - rfbLog("process_remote_cmd: disabling xfixes " + rfbLog("remote_cmd: disabling xfixes " "(but not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: disabling -xfixes.\n"); + rfbLog("remote_cmd: disabling -xfixes.\n"); use_xfixes = 0; initialize_xfixes(); first_cursor(); @@ -9887,11 +10095,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xdamage_present) { - rfbLog("process_remote_cmd: cannot enable xdamage hints " + rfbLog("remote_cmd: cannot enable xdamage hints " "(not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: enabling xdamage hints" + rfbLog("remote_cmd: enabling xdamage hints" " (if supported).\n"); use_xdamage = 1; if (use_xdamage != orig) { @@ -9905,11 +10113,11 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (! xdamage_present) { - rfbLog("process_remote_cmd: disabling xdamage hints " + rfbLog("remote_cmd: disabling xdamage hints " "(but not supported on X display)\n"); goto done; } - rfbLog("process_remote_cmd: disabling xdamage hints.\n"); + rfbLog("remote_cmd: disabling xdamage hints.\n"); use_xdamage = 0; if (use_xdamage != orig) { initialize_xdamage(); @@ -9927,7 +10135,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("xd_area:"); a = atoi(p); if (a >= 0) { - rfbLog("process_remote_cmd: setting xdamage_max_area " + rfbLog("remote_cmd: setting xdamage_max_area " "%d -> %d.\n", xdamage_max_area, a); xdamage_max_area = a; } @@ -9942,7 +10150,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("xd_mem:"); a = atof(p); if (a >= 0.0) { - rfbLog("process_remote_cmd: setting xdamage_memory " + rfbLog("remote_cmd: setting xdamage_memory " "%.3f -> %.3f.\n", xdamage_memory, a); xdamage_memory = a; } @@ -9960,7 +10168,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (a < 0) a = 0; if (a > 256) a = 256; /* allow 256 for testing. */ if (alpha_threshold != a) { - rfbLog("process_remote_cmd: setting alphacut " + rfbLog("remote_cmd: setting alphacut " "%d -> %d.\n", alpha_threshold, a); if (a == 256) { rfbLog("note: alphacut=256 leads to completely" @@ -9982,7 +10190,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (a < 0.0) a = 0.0; if (a > 1.0) a = 1.0; if (alpha_frac != a) { - rfbLog("process_remote_cmd: setting alphafrac " + rfbLog("remote_cmd: setting alphafrac " "%f -> %f.\n", alpha_frac, a); alpha_frac = a; setup_cursors_and_push(); @@ -9993,7 +10201,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (!alpha_remove) { - rfbLog("process_remote_cmd: enable alpharemove\n"); + rfbLog("remote_cmd: enable alpharemove\n"); alpha_remove = 1; setup_cursors_and_push(); } @@ -10003,7 +10211,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (alpha_remove) { - rfbLog("process_remote_cmd: disable alpharemove\n"); + rfbLog("remote_cmd: disable alpharemove\n"); alpha_remove = 0; setup_cursors_and_push(); } @@ -10013,7 +10221,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (!alpha_blend) { - rfbLog("process_remote_cmd: enable alphablend\n"); + rfbLog("remote_cmd: enable alphablend\n"); alpha_remove = 0; alpha_blend = 1; setup_cursors_and_push(); @@ -10024,7 +10232,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { goto qry; } if (alpha_blend) { - rfbLog("process_remote_cmd: disable alphablend\n"); + rfbLog("remote_cmd: disable alphablend\n"); alpha_blend = 0; setup_cursors_and_push(); } @@ -10034,7 +10242,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, use_xwarppointer); goto qry; } - rfbLog("process_remote_cmd: turning on xwarppointer mode.\n"); + rfbLog("remote_cmd: turning on xwarppointer mode.\n"); use_xwarppointer = 1; } else if (strstr(p, "noxwarp") == p || strstr(p, "noxwarppointer") == p) { @@ -10042,7 +10250,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !use_xwarppointer); goto qry; } - rfbLog("process_remote_cmd: turning off xwarppointer mode.\n"); + rfbLog("remote_cmd: turning off xwarppointer mode.\n"); use_xwarppointer = 0; } else if (strstr(p, "buttonmap") == p) { @@ -10056,8 +10264,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (pointer_remap) free(pointer_remap); pointer_remap = strdup(p); - rfbLog("process_remote_cmd: setting -buttonmap to:\n" - "\t'%s'\n", p); + rfbLog("remote_cmd: setting -buttonmap to:\n\t'%s'\n", p); initialize_pointer_map(p); } else if (!strcmp(p, "dragging")) { @@ -10065,16 +10272,87 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, show_dragging); goto qry; } - rfbLog("process_remote_cmd: enabling mouse dragging mode.\n"); + rfbLog("remote_cmd: enabling mouse dragging mode.\n"); show_dragging = 1; } else if (!strcmp(p, "nodragging")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !show_dragging); goto qry; } - rfbLog("process_remote_cmd: enabling mouse nodragging mode.\n"); + rfbLog("remote_cmd: enabling mouse nodragging mode.\n"); show_dragging = 0; + } else if (strstr(p, "wireframe_mode") == p) { + COLON_CHECK("wireframe_mode:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + wireframe_str ? wireframe_str : WIREFRAME_PARMS); + goto qry; + } + p += strlen("wireframe_mode:"); + if (*p) { + if (wireframe_str) { + free(wireframe_str); + } + wireframe_str = strdup(p); + parse_wireframe(); + } + rfbLog("remote_cmd: enabling -wireframe mode.\n"); + wireframe = 1; + } else if (strstr(p, "wireframe:") == p) { /* skip-cmd-list */ + COLON_CHECK("wireframe:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe); + goto qry; + } + p += strlen("wireframe:"); + if (*p) { + if (wireframe_str) { + free(wireframe_str); + } + wireframe_str = strdup(p); + parse_wireframe(); + } + rfbLog("remote_cmd: enabling -wireframe mode.\n"); + wireframe = 1; + } else if (!strcmp(p, "wireframe")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, wireframe); + goto qry; + } + rfbLog("remote_cmd: enabling -wireframe mode.\n"); + wireframe = 1; + } else if (!strcmp(p, "nowireframe")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%d", p, !wireframe); + goto qry; + } + rfbLog("remote_cmd: enabling -nowireframe mode.\n"); + wireframe = 0; + + } else if (strstr(p, "wirecopyrect") == p) { + COLON_CHECK("wirecopyrect:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%s", p, co, + NONUL(wireframe_copyrect)); + goto qry; + } + p += strlen("wirecopyrect:"); + + set_wirecopyrect_mode(p); + rfbLog("remote_cmd: changed -wirecopyrect mode " + "to: %s\n", NONUL(wireframe_copyrect)); + } else if (!strcmp(p, "nowirecopyrect")) { + if (query) { + snprintf(buf, bufn, "ans=%s:%s", p, + NONUL(wireframe_copyrect)); + goto qry; + } + + set_wirecopyrect_mode("never"); + rfbLog("remote_cmd: changed -wirecopyrect mode " + "to: %s\n", NONUL(wireframe_copyrect)); + } else if (strstr(p, "pointer_mode") == p) { int pm; COLON_CHECK("pointer_mode:") @@ -10085,11 +10363,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("pointer_mode:"); pm = atoi(p); if (pm < 0 || pm > pointer_mode_max) { - rfbLog("process_remote_cmd: pointer_mode out of range:" + rfbLog("remote_cmd: pointer_mode out of range:" " 1-%d: %d\n", pointer_mode_max, pm); } else { - rfbLog("process_remote_cmd: setting pointer_mode %d\n", - pm); + rfbLog("remote_cmd: setting pointer_mode %d\n", pm); pointer_mode = pm; } } else if (strstr(p, "pm") == p) { @@ -10102,11 +10379,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("pm:"); pm = atoi(p); if (pm < 0 || pm > pointer_mode_max) { - rfbLog("process_remote_cmd: pointer_mode out of range:" + rfbLog("remote_cmd: pointer_mode out of range:" " 1-%d: %d\n", pointer_mode_max, pm); } else { - rfbLog("process_remote_cmd: setting pointer_mode %d\n", - pm); + rfbLog("remote_cmd: setting pointer_mode %d\n", pm); pointer_mode = pm; } @@ -10119,7 +10395,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("input_skip:"); is = atoi(p); - rfbLog("process_remote_cmd: setting input_skip %d\n", is); + rfbLog("remote_cmd: setting input_skip %d\n", is); ui_skip = is; } else if (strstr(p, "input") == p) { @@ -10134,7 +10410,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (allowed_input_str && !strcmp(p, allowed_input_str)) { doit = 0; } - rfbLog("process_remote_cmd: setting input %s\n", p); + rfbLog("remote_cmd: setting input %s\n", p); if (allowed_input_str) free(allowed_input_str); if (*p == '\0') { allowed_input_str = NULL; @@ -10161,8 +10437,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { if (speeds_str) free(speeds_str); speeds_str = strdup(p); - rfbLog("process_remote_cmd: setting -speeds to:\n" - "\t'%s'\n", p); + rfbLog("remote_cmd: setting -speeds to:\n\t'%s'\n", p); initialize_speeds(); } else if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) { @@ -10170,14 +10445,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, debug_pointer); goto qry; } - rfbLog("process_remote_cmd: turning on debug_pointer.\n"); + rfbLog("remote_cmd: turning on debug_pointer.\n"); debug_pointer = 1; } else if (!strcmp(p, "nodebug_pointer") || !strcmp(p, "nodp")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_pointer); goto qry; } - rfbLog("process_remote_cmd: turning off debug_pointer.\n"); + rfbLog("remote_cmd: turning off debug_pointer.\n"); debug_pointer = 0; } else if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) { @@ -10185,14 +10460,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, debug_keyboard); goto qry; } - rfbLog("process_remote_cmd: turning on debug_keyboard.\n"); + rfbLog("remote_cmd: turning on debug_keyboard.\n"); debug_keyboard = 1; } else if (!strcmp(p, "nodebug_keyboard") || !strcmp(p, "nodk")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !debug_keyboard); goto qry; } - rfbLog("process_remote_cmd: turning off debug_keyboard.\n"); + rfbLog("remote_cmd: turning off debug_keyboard.\n"); debug_keyboard = 0; } else if (strstr(p, "deferupdate") == p) { @@ -10206,7 +10481,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("deferupdate:"); d = atoi(p); if (d < 0) d = 0; - rfbLog("process_remote_cmd: setting defer to %d ms.\n", d); + rfbLog("remote_cmd: setting defer to %d ms.\n", d); screen->deferUpdateTime = d; } else if (strstr(p, "defer") == p) { @@ -10220,7 +10495,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("defer:"); d = atoi(p); if (d < 0) d = 0; - rfbLog("process_remote_cmd: setting defer to %d ms.\n", d); + rfbLog("remote_cmd: setting defer to %d ms.\n", d); /* XXX not part of API? */ screen->deferUpdateTime = d; @@ -10234,8 +10509,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("wait:"); w = atoi(p); if (w < 0) w = 0; - rfbLog("process_remote_cmd: setting wait %d -> %d ms.\n", - waitms, w); + rfbLog("remote_cmd: setting wait %d -> %d ms.\n", waitms, w); waitms = w; } else if (strstr(p, "rfbwait") == p) { @@ -10249,7 +10523,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("rfbwait:"); w = atoi(p); if (w < 0) w = 0; - rfbLog("process_remote_cmd: setting rfbMaxClientWait %d -> " + rfbLog("remote_cmd: setting rfbMaxClientWait %d -> " "%d ms.\n", orig, w); rfbMaxClientWait = w; if (screen) { @@ -10262,14 +10536,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, take_naps); goto qry; } - rfbLog("process_remote_cmd: turning on nap mode.\n"); + rfbLog("remote_cmd: turning on nap mode.\n"); take_naps = 1; } else if (!strcmp(p, "nonap")) { if (query) { snprintf(buf, bufn, "ans=%s:%d", p, !take_naps); goto qry; } - rfbLog("process_remote_cmd: turning off nap mode.\n"); + rfbLog("remote_cmd: turning off nap mode.\n"); take_naps = 0; } else if (strstr(p, "sb") == p) { @@ -10282,8 +10556,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("sb:"); w = atoi(p); if (w < 0) w = 0; - rfbLog("process_remote_cmd: setting screen_blank %d -> %d" - " sec.\n", screen_blank, w); + rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n", + screen_blank, w); screen_blank = w; } else if (strstr(p, "screen_blank") == p) { int w; @@ -10295,8 +10569,8 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("screen_blank:"); w = atoi(p); if (w < 0) w = 0; - rfbLog("process_remote_cmd: setting screen_blank %d -> %d" - " sec.\n", screen_blank, w); + rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n", + screen_blank, w); screen_blank = w; } else if (strstr(p, "fs") == p) { @@ -10307,7 +10581,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } p += strlen("fs:"); fs_frac = atof(p); - rfbLog("process_remote_cmd: setting -fs frac to %f\n", fs_frac); + rfbLog("remote_cmd: setting -fs frac to %f\n", fs_frac); } else if (strstr(p, "gaps") == p) { int g; @@ -10319,7 +10593,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("gaps:"); g = atoi(p); if (g < 0) g = 0; - rfbLog("process_remote_cmd: setting gaps_fill %d -> %d.\n", + rfbLog("remote_cmd: setting gaps_fill %d -> %d.\n", gaps_fill, g); gaps_fill = g; } else if (strstr(p, "grow") == p) { @@ -10332,7 +10606,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("grow:"); g = atoi(p); if (g < 0) g = 0; - rfbLog("process_remote_cmd: setting grow_fill %d -> %d.\n", + rfbLog("remote_cmd: setting grow_fill %d -> %d.\n", grow_fill, g); grow_fill = g; } else if (strstr(p, "fuzz") == p) { @@ -10345,7 +10619,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("fuzz:"); f = atoi(p); if (f < 0) f = 0; - rfbLog("process_remote_cmd: setting tile_fuzz %d -> %d.\n", + rfbLog("remote_cmd: setting tile_fuzz %d -> %d.\n", tile_fuzz, f); grow_fill = f; @@ -10355,7 +10629,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, use_snapfb); goto qry; } - rfbLog("process_remote_cmd: turning on snapfb mode.\n"); + rfbLog("remote_cmd: turning on snapfb mode.\n"); use_snapfb = 1; if (orig != use_snapfb) { do_new_fb(1); @@ -10366,7 +10640,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { snprintf(buf, bufn, "ans=%s:%d", p, !use_snapfb); goto qry; } - rfbLog("process_remote_cmd: turning off snapfb mode.\n"); + rfbLog("remote_cmd: turning off snapfb mode.\n"); use_snapfb = 0; if (orig != use_snapfb) { do_new_fb(1); @@ -10382,14 +10656,13 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("rawfb:"); if (raw_fb_str) free(raw_fb_str); raw_fb_str = strdup(p); - if (safe_remote_only && strstr(p, "setup:") == p) { + if (safe_remote_only && strstr(p, "setup:") == p) { /* skip-cmd-list */ /* n.b. we still allow filename, shm, of rawfb */ fprintf(stderr, "unsafe rawfb setup: %s\n", p); exit(1); } - rfbLog("process_remote_cmd: setting -rawfb to:\n" - "\t'%s'\n", p); + rfbLog("remote_cmd: setting -rawfb to:\n\t'%s'\n", p); if (*raw_fb_str == '\0') { free(raw_fb_str); @@ -10411,7 +10684,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { p += strlen("progressive:"); f = atoi(p); if (f < 0) f = 0; - rfbLog("process_remote_cmd: setting progressive %d -> %d.\n", + rfbLog("remote_cmd: setting progressive %d -> %d.\n", screen->progressiveSliceHeight, f); screen->progressiveSliceHeight = f; @@ -10569,7 +10842,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } rfb_desktop_name = strdup(p); screen->desktopName = rfb_desktop_name; - rfbLog("process_remote_cmd: setting desktop name to %s\n", + rfbLog("remote_cmd: setting desktop name to %s\n", rfb_desktop_name); } else if (!strcmp(p, "noremote")) { @@ -10578,10 +10851,10 @@ char *process_remote_cmd(char *cmd, int stringonly) { !accept_remote_cmds); goto qry; } - rfbLog("process_remote_cmd: disabling remote commands.\n"); + rfbLog("remote_cmd: disabling remote commands.\n"); accept_remote_cmds = 0; /* cannot be turned back on. */ - } else if (strstr(p, "debug_xevents:") == p) { + } else if (strstr(p, "debug_xevents") == p) { COLON_CHECK("debug_xevents:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xevents); @@ -10591,7 +10864,17 @@ char *process_remote_cmd(char *cmd, int stringonly) { debug_xevents = atoi(p); rfbLog("set debug_xevents to: %d\n", debug_xevents); - } else if (strstr(p, "hack:") == p) { /* skip-cmd-list */ + } else if (strstr(p, "debug_xdamage") == p) { + COLON_CHECK("debug_xdamage:") + if (query) { + snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xdamage); + goto qry; + } + p += strlen("debug_xdamage:"); + debug_xdamage = atoi(p); + rfbLog("set debug_xdamage to: %d\n", debug_xdamage); + + } else if (strstr(p, "hack") == p) { /* skip-cmd-list */ COLON_CHECK("hack:") if (query) { snprintf(buf, bufn, "ans=%s%s%d", p, co, hack_val); @@ -10667,10 +10950,14 @@ char *process_remote_cmd(char *cmd, int stringonly) { scaling_interpolate); } else if (!strcmp(p, "inetd")) { snprintf(buf, bufn, "aro=%s:%d", p, inetd); - } else if (!strcmp(p, "safer")) { - snprintf(buf, bufn, "aro=%s:%d", p, safe_remote_only); + } else if (!strcmp(p, "privremote")) { + snprintf(buf, bufn, "aro=%s:%d", p, priv_remote); } else if (!strcmp(p, "unsafe")) { snprintf(buf, bufn, "aro=%s:%d", p, !safe_remote_only); + } else if (!strcmp(p, "safer")) { + snprintf(buf, bufn, "aro=%s:%d", p, more_safe); + } else if (!strcmp(p, "nocmds")) { + snprintf(buf, bufn, "aro=%s:%d", p, no_external_cmds); } else if (!strcmp(p, "passwdfile")) { snprintf(buf, bufn, "aro=%s:%s", p, NONUL(passwdfile)); } else if (!strcmp(p, "using_shm")) { @@ -10770,7 +11057,7 @@ char *process_remote_cmd(char *cmd, int stringonly) { } else { char tmp[100]; NOTAPP - rfbLog("process_remote_cmd: warning unknown\n"); + rfbLog("remote_cmd: warning unknown\n"); strncpy(tmp, p, 90); rfbLog("command \"%s\"\n", tmp); goto done; @@ -10839,10 +11126,10 @@ void record_desired_xdamage_rect(int x, int y, int w, int h) { dt_x = w / tile_x; dt_y = h / tile_y; - if (!always_accept && dt_y >= 2 && area > 1000) { + if (!always_accept && dt_y >= 3 && area > 2000) { /* - * should be caught by a normal scanline poll, but we might - * as well keep if small. + * if it is real it should be caught by a normal scanline + * poll, but we might as well keep if small (tall line?). */ return; } @@ -10852,6 +11139,7 @@ void record_desired_xdamage_rect(int x, int y, int w, int h) { nt_y1 = nfix( (y)/tile_y, ntiles_y); nt_y2 = nfix((y+h)/tile_y, ntiles_y); + /* loop over the rectangle of tiles (1 tile for a small input rect */ for (ix = nt_x1; ix <= nt_x2; ix++) { for (iy = nt_y1; iy <= nt_y2; iy++) { @@ -10865,6 +11153,11 @@ void record_desired_xdamage_rect(int x, int y, int w, int h) { xdamage_tile_count++; } } + if (debug_xdamage > 1) { + fprintf(stderr, "xdamage: desired: %dx%d+%d+%d\tA: %6d tiles=" + "%02d-%02d/%02d-%02d tilecnt: %d\n", w, h, x, y, + w * h, nt_x1, nt_x2, nt_y1, nt_y2, cnt); + } } void collect_xdamage(int scancnt) { @@ -10973,6 +11266,11 @@ void collect_xdamage(int scancnt) { continue; } } + if (debug_xdamage > 2) { + fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:" + " %d dups: %d %s\n", w, h, x, y, w*h, dcount, + (w*h > xdamage_max_area) ? "TOO_BIG" : ""); + } record_desired_xdamage_rect(x, y, w, h); @@ -10996,6 +11294,11 @@ void collect_xdamage(int scancnt) { if (XD_tot) { rat = ((double) XD_skip)/XD_tot; } + if (debug_xdamage) { + fprintf(stderr, "xdamage: == scanline skip/tot: " + "%04d/%04d =%.3f rects: %d desired: %d\n", + XD_skip, XD_tot, rat, rect_count, XD_des); + } XD_skip = 0; XD_tot = 0; @@ -11081,6 +11384,9 @@ void initialize_xdamage(void) { } void create_xdamage_if_needed(void) { + + if (raw_fb && ! dpy) return; /* raw_fb hack */ + #if LIBVNCSERVER_HAVE_LIBXDAMAGE if (! xdamage) { X_LOCK; @@ -11093,6 +11399,9 @@ void create_xdamage_if_needed(void) { } void destroy_xdamage_if_needed(void) { + + if (raw_fb && ! dpy) return; /* raw_fb hack */ + #if LIBVNCSERVER_HAVE_LIBXDAMAGE if (xdamage) { XEvent ev; @@ -12422,6 +12731,7 @@ int get_which_cursor(void) { int mode = 0; if (drag_in_progress || button_mask) { + /* XXX not exactly what we want for menus */ return -1; } @@ -12878,7 +13188,7 @@ void check_x11_pointer(void) { int x, y; unsigned int mask; - if (raw_fb) return; /* raw_fb hack */ + if (raw_fb && ! dpy) return; /* raw_fb hack */ X_LOCK; ret = XQueryPointer(dpy, rootwin, &root_w, &child_w, &root_x, &root_y, @@ -13228,32 +13538,34 @@ void set_raw_fb_params(int restore) { if (first) { /* at least save the initial settings... */ vo0 = view_only; - us0 = use_snapfb; - sm0 = using_shm; ws0 = watch_selection; wp0 = watch_primary; wb0 = watch_bell; na0 = no_autorepeat; + sb0 = use_solid_bg; + + us0 = use_snapfb; + sm0 = using_shm; tn0 = take_naps; - mc0 = multiple_cursors_mode; xr0 = xrandr; - sb0 = use_solid_bg; + mc0 = multiple_cursors_mode; first = 0; } if (restore) { view_only = vo0; - use_snapfb = us0; - using_shm = sm0; watch_selection = ws0; watch_primary = wp0; watch_bell = wb0; no_autorepeat = na0; + use_solid_bg = sb0; + + use_snapfb = us0; + using_shm = sm0; take_naps = tn0; - multiple_cursors_mode = mc0; xrandr = xr0; - use_solid_bg = sb0; + multiple_cursors_mode = mc0; if (! dpy && raw_fb_orig_dpy) { dpy = XOpenDisplay(raw_fb_orig_dpy); @@ -13268,9 +13580,44 @@ void set_raw_fb_params(int restore) { return; } - if (! view_only) { - rfbLog("rawfb: setting view_only\n"); - view_only = 1; + rfbLog("set_raw_fb_params: modifying settings for -rawfb mode.\n"); + + if (got_noviewonly) { + /* + * The user input parameters are not unset under + * -noviewonly... this usage should be very rare + * (i.e. rawfb but also send user input to the X + * display, most likely using /dev/fb0 for some reason...) + */ + rfbLog("rawfb: -noviewonly mode: still sending mouse and\n"); + rfbLog("rawfb: keyboard input to the X DISPLAY!!\n"); + } else { + /* Normal case: */ + if (! view_only) { + rfbLog("rawfb: setting view_only\n"); + view_only = 1; + } + if (watch_selection) { + rfbLog("rawfb: turning off watch_selection\n"); + watch_selection = 0; + } + if (watch_primary) { + rfbLog("rawfb: turning off watch_primary\n"); + watch_primary = 0; + } + if (watch_bell) { + rfbLog("rawfb: turning off watch_bell\n"); + watch_bell = 0; + } + if (no_autorepeat) { + rfbLog("rawfb: turning off no_autorepeat\n"); + no_autorepeat = 0; + } + if (use_solid_bg) { + rfbLog("rawfb: turning off use_solid_bg\n"); + use_solid_bg = 0; + } + multiple_cursors_mode = strdup("arrow"); } if (use_snapfb) { rfbLog("rawfb: turning off use_snapfb\n"); @@ -13280,35 +13627,14 @@ void set_raw_fb_params(int restore) { rfbLog("rawfb: turning off using_shm\n"); using_shm = 0; } - if (watch_selection) { - rfbLog("rawfb: turning off watch_selection\n"); - watch_selection = 0; - } - if (watch_primary) { - rfbLog("rawfb: turning off watch_primary\n"); - watch_primary = 0; - } - if (watch_bell) { - rfbLog("rawfb: turning off watch_bell\n"); - watch_bell = 0; - } - if (no_autorepeat) { - rfbLog("rawfb: turning off no_autorepeat\n"); - no_autorepeat = 0; - } if (take_naps) { rfbLog("rawfb: turning off take_naps\n"); take_naps = 0; } - multiple_cursors_mode = strdup("arrow"); if (xrandr) { rfbLog("rawfb: turning off xrandr\n"); xrandr = 0; } - if (use_solid_bg) { - rfbLog("rawfb: turning off use_solid_bg\n"); - use_solid_bg = 0; - } } /* @@ -13477,6 +13803,13 @@ XImage *initialize_raw_fb(void) { set_child_info(); q += strlen("setup:"); + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds " + "mode:\n"); + rfbLog(" \"%s\"\n", q); + rfbLog(" exiting.\n"); + clean_up_exit(1); + } rfbLog("running command to setup rawfb: %s\n", q); pipe = popen(q, "r"); if (! pipe) { @@ -13521,6 +13854,14 @@ XImage *initialize_raw_fb(void) { closedpy = 0; } + if (closedpy && !view_only && got_noviewonly) { + rfbLog("not closing X DISPLAY under -noviewonly option.\n"); + closedpy = 0; + if (! window) { + window = rootwin; + } + } + if (! raw_fb_orig_dpy && dpy) { raw_fb_orig_dpy = strdup(DisplayString(dpy)); } @@ -13530,6 +13871,8 @@ XImage *initialize_raw_fb(void) { #if BOLDLY_CLOSE_DISPLAY if (closedpy) { if (dpy) { + rfbLog("closing X DISPLAY: %s in rawfb mode.\n", + DisplayString(dpy)); XCloseDisplay(dpy); /* yow! */ } dpy = 0; @@ -13575,6 +13918,25 @@ XImage *initialize_raw_fb(void) { rfbLog("invalid rawfb str: %s\n", str); clean_up_exit(1); } + *q = '\0'; + + if (strstr(str, "shm:") != str && strstr(str, "mmap:") != str && + strstr(str, "map:") != str && strstr(str, "file:") != str) { + /* hmmm, not following directions, see if map: applies */ + struct stat sbuf; + if (stat(str, &sbuf) == 0) { + char *new; + int len = strlen("map:") + strlen(str) + 1; + rfbLog("no type prefix: %s\n", raw_fb_str); + rfbLog(" but file exists, so assuming: map:%s\n", + raw_fb_str); + new = (char *)malloc(len); + strcpy(new, "map:"); + strcat(new, str); + free(str); + str = new; + } + } dpy_x = wdpy_x = w; dpy_y = wdpy_y = h; @@ -13587,7 +13949,6 @@ XImage *initialize_raw_fb(void) { raw_fb_fd = -1; raw_fb_addr = NULL; - *q = '\0'; if (sscanf(str, "shm:%d", &shmid) == 1) { /* shm:N */ raw_fb_addr = (char *) shmat(shmid, 0, SHM_RDONLY); @@ -13625,7 +13986,7 @@ XImage *initialize_raw_fb(void) { if (S_ISREG(sbuf.st_mode)) { if (0) size = sbuf.st_size; } else { - rfbLog("non-regular file: %s\n", q); + rfbLog("raw fb is non-regular file: %s\n", q); } } @@ -13790,7 +14151,7 @@ XImage *initialize_xdisplay_fb(void) { if (subwin_wait_mapped) { wait_until_mapped(subwin); } - if (!valid_window((Window) subwin)) { + if (!valid_window((Window) subwin, NULL)) { rfbLog("invalid sub-window: 0x%lx\n", subwin); X_UNLOCK; clean_up_exit(1); @@ -14198,6 +14559,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { main_bytes_per_line = fb->bytes_per_line; setup_scaling(&width, &height); + if (scaling) { rfbLog("scaling screen: %dx%d -> %dx%d scale_fac=%.5f\n", @@ -14452,7 +14814,6 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { rfbLog("\n"); } #endif - /* nofb is for pointer/keyboard only handling. */ if (nofb) { main_fb = NULL; @@ -14477,6 +14838,9 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { bpp = screen->serverFormat.bitsPerPixel; depth = screen->serverFormat.depth; + /* may need, bpp, main_red_max, etc. */ + parse_wireframe(); + setup_cursors_and_push(); if (scaling) { @@ -14597,6 +14961,13 @@ int dt_cmd(char *cmd) { return 0; } + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", cmd); + rfbLog(" dt_cmd: returning 1\n"); + return 1; + } + rfbLog("running command:\n %s\n", cmd); usr_bin_path(0); rc = system(cmd); @@ -14618,6 +14989,13 @@ char *cmd_output(char *cmd) { return ""; } + if (no_external_cmds) { + rfbLog("cannot run external commands in -nocmds mode:\n"); + rfbLog(" \"%s\"\n", cmd); + rfbLog(" cmd_output: null string.\n"); + return ""; + } + rfbLog("running pipe:\n %s\n", cmd); usr_bin_path(0); p = popen(cmd, "r"); @@ -14786,7 +15164,7 @@ void solid_cde(char *color) { if (! twin) { twin = rootwin; } - if (! valid_window(twin)) { + if (! valid_window(twin, NULL)) { continue; } @@ -15123,6 +15501,10 @@ void solid_kde(char *color) { char *guess_desktop() { Atom prop; + prop = XInternAtom(dpy, "XFCE_DESKTOP_WINDOW", True); + if (prop != None) { + return "xfce"; + } prop = XInternAtom(dpy, "_QT_DESKTOP_PROPERTIES", True); if (prop != None) { return "kde"; @@ -15448,6 +15830,8 @@ void initialize_xinerama (void) { char *bstr, *tstr; int ev, er, i, n, rcnt; + if (raw_fb && ! dpy) return; /* raw_fb hack */ + if (! XineramaQueryExtension(dpy, &ev, &er)) { rfbLog("Xinerama: disabling: display does not support it.\n"); xinerama = 0; @@ -15875,7 +16259,7 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) { X_LOCK; #if LIBVNCSERVER_HAVE_XSHM - if (shm != NULL && shm->shmid != -1 && dpy) { + if (shm != NULL && shm->shmid != -1 && dpy) { /* raw_fb hack */ XShmDetach_wr(dpy, shm); } #endif @@ -18217,6 +18601,15 @@ void run_gui(char *gui_xdisplay, int connect_to_x11vnc, int simple_gui, set_env("X11VNC_SIMPLE_GUI", "1"); } + if (no_external_cmds) { + fprintf(stderr, "cannot run external commands in -nocmds " + "mode:\n"); + fprintf(stderr, " \"%s\"\n", "gui + wish"); + fprintf(stderr, " exiting.\n"); + fflush(stderr); + exit(1); + } + sprintf(cmd, "%s -", wish); tmpf = tmpfile(); if (tmpf == NULL) { @@ -18357,12 +18750,1141 @@ void do_gui(char *opts) { } } -/* -- x11vnc.c -- */ +/* -- userinput.c -- */ /* - * main routine for the x11vnc program + * user input handling heuristics + */ + +/* + * For -wireframe: find the direct child of rootwin that has the + * pointer, assume that is the WM frame that contains the application + * (i.e. wm reparents the app toplevel) return frame position and size + * if successful. */ +int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h, Window *win) { + Window r, c; + XWindowAttributes attr; + Bool ret; + int rootx, rooty, wx, wy; + unsigned int mask; + + ret = XQueryPointer(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy, &mask); + + *win = c; + + /* current pointer position is returned too */ + *px = rootx; + *py = rooty; + + if (!ret || ! c || c == rootwin) { + /* no immediate child */ + return 0; + } + + /* child window position and size */ + if (! valid_window(c, &attr)) { + return 0; + } +#if 0 + XTranslateCoordinates(dpy, c, rootwin, 0, 0, &rootx, &rooty, &c2); + *x = rootx; + *y = rooty; +#endif + *x = attr.x; + *y = attr.y; + *w = attr.width; + *h = attr.height; + + return 1; +} + static int defer_update_nofb = 6; /* defer a shorter time under -nofb */ +static Window maybe_scrolling = 0; + +/* +WIREFRAME_PARMS "0xff,2,0,30+6+6+6,0.05+0.3+2.0,8" +shade,linewidth,percent,T+B+L+R,t1+t2+t3 + */ +#define LW_MAX 8 +unsigned long wireframe_shade; +int wireframe_lw; +double wireframe_frac; +int wireframe_top, wireframe_bot, wireframe_left, wireframe_right; +double wireframe_t1, wireframe_t2, wireframe_t3, wireframe_t4; + +/* + * Parse the gory -wireframe string for parameters. + */ +void parse_wireframe_str(char *wf) { + char *p, *str; + int i; + char *part[10]; + + for (i=0; i<10; i++) { + part[i] = NULL; + } + + if (wf == NULL || *wf == '\0') { + return; + } + + str = strdup(wf); + + /* leading ",", make it start with ignorable string "z" */ + if (*str == ',') { + char *tmp = (char *) malloc(strlen(str)+2); + strcpy(tmp, "z"); + strcat(tmp, str); + free(str); + str = tmp; + } + + p = strtok(str, ","); + i = 0; + while (p) { + part[i++] = strdup(p); + p = strtok(NULL, ","); + } + free(str); + + + /* Wireframe shade, color, RGB: */ + if ((str = part[0]) != NULL) { + unsigned long n; + int r, g, b, ok = 0; + XColor cdef; + Colormap cmap; + if (dpy && (bpp == 32 || bpp == 16)) { + cmap = DefaultColormap (dpy, scr); + if (XParseColor(dpy, cmap, str, &cdef) && + XAllocColor(dpy, cmap, &cdef)) { + r = cdef.red >> 8; + g = cdef.green >> 8; + b = cdef.blue >> 8; + if (r == 0 && g == 0) { + g = 1; /* need to be > 255 */ + } + n = 0; + n |= (r << main_red_shift); + n |= (g << main_green_shift); + n |= (b << main_blue_shift); + wireframe_shade = n; + ok = 1; + } + } + if (ok) { + ; + } else if (sscanf(str, "0x%lx", &n) == 1) { + wireframe_shade = n; + } else if (sscanf(str, "%ld", &n) == 1) { + wireframe_shade = n; + } else if (sscanf(str, "%lx", &n) == 1) { + wireframe_shade = n; + } + free(str); + } + + /* linewidth: # of pixels wide for the wireframe lines */ + if ((str = part[1]) != NULL) { + int n; + if (sscanf(str, "%d", &n) == 1) { + wireframe_lw = n; + if (wireframe_lw < 1) { + wireframe_lw = 1; + } + if (wireframe_lw > LW_MAX) { + wireframe_lw = LW_MAX; + } + } + free(str); + } + + /* percentage cutoff for opaque move/resize (like WM's) */ + if ((str = part[2]) != NULL) { + if (*str == '\0') { + ; + } else if (strchr(str, '.')) { + wireframe_frac = atof(str); + } else { + wireframe_frac = ((double) atoi(str))/100.0; + } + free(str); + } + + /* + * Top, Bottom, Left, Right tolerances to guess the wm frame is + * being grabbed (Top is traditionally bigger, i.e. titlebar): + */ + if ((str = part[3]) != NULL) { + int t, b, l, r; + if (sscanf(str, "%d+%d+%d+%d", &t, &b, &l, &r) == 4) { + wireframe_top = t; + wireframe_bot = b; + wireframe_left = l; + wireframe_right = r; + } + free(str); + } + + /* check_wireframe() timing heuristics. */ + if ((str = part[4]) != NULL) { + double t1, t2, t3, t4; + if (sscanf(str, "%lf+%lf+%lf+%lf", &t1, &t2, &t3, &t4) == 4) { + wireframe_t1 = t1; + wireframe_t2 = t2; + wireframe_t3 = t3; + wireframe_t4 = t4; + } + free(str); + } +} + +/* + * First parse the defaults and apply any user supplied ones (may be a subset) + */ +void parse_wireframe(void) { + parse_wireframe_str(WIREFRAME_PARMS); + if (! wireframe_str) { + wireframe_str = strdup(WIREFRAME_PARMS); + } + parse_wireframe_str(wireframe_str); +} + +/* + * Set wireframe_copyrect based on desired mode. + */ +void set_wirecopyrect_mode(char *str) { + char *orig = wireframe_copyrect; + if (str == NULL || *str == '\0') { + wireframe_copyrect = strdup(wireframe_copyrect_default); + } else if (!strcmp(str, "always") || !strcmp(str, "all")) { + wireframe_copyrect = strdup("always"); + } else if (!strcmp(str, "top")) { + wireframe_copyrect = strdup("top"); + } else if (!strcmp(str, "never") || !strcmp(str, "none")) { + wireframe_copyrect = strdup("never"); + } else { + if (! wireframe_copyrect) { + wireframe_copyrect = strdup(wireframe_copyrect_default); + } + rfbLog("unknown -wirecopyrect mode: %s, using: %s\n", str, + wireframe_copyrect); + } + if (orig) { + free(orig); + } +} + +typedef struct saveline { + int x0, y0, x1, y1; + int shift; + int vert; + int saved; + char *data; +} saveline_t; + +/* + * Draw the wireframe box onto the framebuffer. Saves the real + * framebuffer data to some storage lines. Restores previous lines. + * use restore = 1 to clean up (done with animation). + * This works with -scale. + */ +void draw_box(int x, int y, int w, int h, int restore) { + int x0, y0, x1, y1, i, pixelsize = bpp/8; + char *dst, *src; + static saveline_t *save[4]; + static int first = 1, len = 0; + int max = dpy_x > dpy_y ? dpy_x : dpy_y; + int sz, lw = wireframe_lw; + unsigned long shade = wireframe_shade; + int color = 0; + unsigned short us; + unsigned long ul; + + if (max > len) { + /* create/resize storage lines: */ + for (i=0; i<4; i++) { + len = max; + if (! first && save[i]) { + if (save[i]->data) { + free(save[i]->data); + } + free(save[i]); + } + save[i] = (saveline_t *) malloc(sizeof(saveline_t)); + save[i]->saved = 0; + sz = (LW_MAX+1)*len*pixelsize; + save[i]->data = (char *)malloc(sz); + + /* + * Four types of lines: + * 0) top horizontal + * 1) bottom horizontal + * 2) left vertical + * 3) right vertical + * + * shift means shifted by width or height. + */ + if (i == 0) { + save[i]->vert = 0; + save[i]->shift = 0; + } else if (i == 1) { + save[i]->vert = 0; + save[i]->shift = 1; + } else if (i == 2) { + save[i]->vert = 1; + save[i]->shift = 0; + } else if (i == 3) { + save[i]->vert = 1; + save[i]->shift = 1; + } + } + } + first = 0; + + /* + * restore any saved lines. see below for algorithm and + * how x0, etc. are used. we just reverse those steps. + */ + for (i=0; i<4; i++) { + int s = save[i]->shift; + int yu, y_min = -1, y_max = -1; + int y_start, y_stop, y_step; + + if (! save[i]->saved) { + continue; + } + x0 = save[i]->x0; + y0 = save[i]->y0; + x1 = save[i]->x1; + y1 = save[i]->y1; + if (save[i]->vert) { + y_start = y0+lw; + y_stop = y1-lw; + y_step = lw*pixelsize; + } else { + y_start = y0 - s*lw; + y_stop = y_start + lw; + y_step = max*pixelsize; + } + for (yu = y_start; yu < y_stop; yu++) { + if (x0 == x1) { + continue; + } + if (yu < 0 || yu >= dpy_y) { + continue; + } + if (y_min < 0 || yu < y_min) { + y_min = yu; + } + if (y_max < 0 || yu > y_max) { + y_max = yu; + } + src = save[i]->data + (yu-y_start)*y_step; + dst = main_fb + yu*main_bytes_per_line + + x0*pixelsize; + memcpy(dst, src, (x1-x0)*pixelsize); + } + if (y_min >= 0) { + mark_rect_as_modified(x0, y_min, x1, y_max+1, 0); + } + save[i]->saved = 0; + } + + if (restore) { + return; + } + +if (0) fprintf(stderr, " DrawBox: %dx%d+%d+%d\n", w, h, x, y); + + /* + * work out shade/color for the wireframe line, could be a color + * for 16bpp or 24bpp. + */ + if (shade > 255) { + if (pixelsize == 2) { + us = (unsigned short) (shade & 0xffff); + color = 1; + } else if (pixelsize == 4) { + ul = (unsigned long) shade; + color = 1; + } else { + shade = shade % 256; + } + } + + for (i=0; i<4; i++) { + int s = save[i]->shift; + int yu, y_min = -1, y_max = -1; + int yblack = -1, xblack1 = -1, xblack2 = -1; + int y_start, y_stop, y_step; + + if (save[i]->vert) { + /* + * make the narrow x's be on the screen, let + * the y's hang off (not drawn). + */ + save[i]->x0 = x0 = nfix(x + s*w - s*lw, dpy_x); + save[i]->y0 = y0 = y; + save[i]->x1 = x1 = nfix(x + s*w - s*lw + lw, dpy_x); + save[i]->y1 = y1 = y + h; + + /* + * start and stop a linewidth away from true edge, + * to avoid interfering with horizontal lines. + */ + y_start = y0+lw; + y_stop = y1-lw; + y_step = lw*pixelsize; + + /* draw a black pixel for the border if lw > 1 */ + if (s) { + xblack1 = x1-1; + } else { + xblack1 = x0; + } + } else { + /* + * make the wide x's be on the screen, let the y's + * hang off (not drawn). + */ + save[i]->x0 = x0 = nfix(x, dpy_x); + save[i]->y0 = y0 = y + s*h; + save[i]->x1 = x1 = nfix(x + w, dpy_x); + save[i]->y1 = y1 = y0 + lw; + y_start = y0 - s*lw; + y_stop = y_start + lw; + y_step = max*pixelsize; + + /* draw a black pixels for the border if lw > 1 */ + if (s) { + yblack = y_stop - 1; + } else { + yblack = y_start; + } + xblack1 = x0; + xblack2 = x1-1; + } + + /* now loop over the allowed y's for either case */ + for (yu = y_start; yu < y_stop; yu++) { + if (x0 == x1) { + continue; + } + if (yu < 0 || yu >= dpy_y) { + continue; + } + + /* record min and max y's for marking rectangle: */ + if (y_min < 0 || yu < y_min) { + y_min = yu; + } + if (y_max < 0 || yu > y_max) { + y_max = yu; + } + + /* save fb data for this line: */ + save[i]->saved = 1; + src = main_fb + yu*main_bytes_per_line + + x0*pixelsize; + dst = save[i]->data + (yu-y_start)*y_step; + memcpy(dst, src, (x1-x0)*pixelsize); + + /* apply the shade/color to make the wireframe line: */ + if (! color) { + memset(src, shade, (x1-x0)*pixelsize); + } else { + char *csrc = src; + unsigned short *usp; + unsigned long *ulp; + int k; + for (k=0; k < x1 - x0; k++) { + if (pixelsize == 4) { + ulp = (unsigned long *)csrc; + *ulp = ul; + } else if (pixelsize == 2) { + usp = (unsigned short *)csrc; + *usp = us; + } + csrc += pixelsize; + } + } + + /* apply black border for lw >= 2 */ + if (lw > 1) { + if (yu == yblack) { + memset(src, 0, (x1-x0)*pixelsize); + } + if (xblack1 >= 0) { + src = src + (xblack1 - x0)*pixelsize; + memset(src, 0, pixelsize); + } + if (xblack2 >= 0) { + src = src + (xblack2 - x0)*pixelsize; + memset(src, 0, pixelsize); + } + } + } + /* mark it for sending: */ + if (save[i]->saved) { + mark_rect_as_modified(x0, y_min, x1, y_max+1, 0); + } + } +} + +/* + * utility routine for CopyRect of the window (but not CopyRegion) + */ +int crfix(int x, int dx, int Lx) { + /* adjust x so that copy source is on screen */ + if (dx > 0) { + if (x-dx < 0) { + /* off on the left */ + x = dx; + } + } else { + if (x-dx >= Lx) { + /* off on the right */ + x = Lx + dx - 1; + } + } + return x; +} + +/* + * Applied just before any check_user_input() modes. Look for a + * ButtonPress; find window it happened in; find the wm frame window + * for it; watch for that window moving or resizing. If it does, do the + * wireframe animation. Do this until ButtonRelease or timeouts occur. + * Remove wireframe. + * + * Under -nowirecopyrect, return control to base scheme + * (check_user_input() ...) that will repaint the screen with the window + * in the new postion or size. Under -wirecopyrect, apply rfbDoCopyRect + * or rfbDoCopyRegion: this "pollutes" our framebuffer, but the normal + * polling will quickly repair it. Under happy circumstances, this + * reduces actual XShmGetImage work (i.e. if we correctly predicted how + * the X fb has changed. + * + * -scale doesn't work under -wirecopyrect, but the wireframe does. + * + * testing of this mode under -threads is incomplete. + * + * returns 1 if it did an animation, 0 if no move/resize triggers + * went off. + * + * TBD: see if we can select StructureNotify ConfigureNotify events for + * the toplevel windows to get better info on moves and resizes. + */ +int check_wireframe(void) { + Window frame, orig_frame; + XWindowAttributes attr; + int dx, dy; + + int orig_px, orig_py, orig_x, orig_y, orig_w, orig_h; + int px, py, x, y, w, h; + int box_x, box_y, box_w, box_h; + int orig_cursor_x, orig_cursor_y, g, g_in; + int already_down = 0, win_gone = 0, win_unmapped = 0; + double spin = 0.0, tm = 0.0, last_ptr, last_draw; + int frame_changed = 0, drew_box = 0, got_2nd_pointer = 0; + int break_reason = 0; + static double first_dt_ave = 0.0; + static int first_dt_cnt = 0; + static time_t last_save_stacklist = 0; + + /* heuristics: */ + int wf_t = wireframe_top; + int wf_b = wireframe_bot; + int wf_l = wireframe_left; + int wf_r = wireframe_right; + double first_event_spin = wireframe_t1; + double frame_changed_spin = wireframe_t2; + double max_spin = wireframe_t3; + double min_draw = wireframe_t4; + + int db = 0; + int db2 = 0; + + if (subwin) { + return 0; /* don't even bother for -id case */ + } + if (! button_mask) { + return 0; /* no button pressed down */ + } + if (!use_threads && !got_pointer_input) { + return 0; /* need ptr input, e.g. button down, motion */ + } + +if (db || db2) fprintf(stderr, "\n*** button down!! x: %d y: %d\n", cursor_x, cursor_y); + + /* + * Query where the pointer is and which child of the root + * window. We will assume this is the frame the window manager + * makes when it reparents the toplevel window. + */ + X_LOCK; + if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &frame)) { +if (db) fprintf(stderr, "NO get_wm_frame_pos: 0x%lx\n", frame); + X_UNLOCK; + return 0; + } + X_UNLOCK; +if (db) fprintf(stderr, "a: %d wf: %.3f A: %d\n", w*h, wireframe_frac, (dpy_x*dpy_y)); + + if (nabs(x + w - px) < 35) { + maybe_scrolling = frame; /* not yet used... */ + } + + /* + * apply the percentage size criterion (allow opaque moves for + * small windows) + */ + if ((double) w*h < wireframe_frac * (dpy_x * dpy_y)) { +if (db) fprintf(stderr, "small window %.3f\n", ((double) w*h)/(dpy_x * dpy_y)); + return 0; + } +if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, orig_frame); + + /* + * see if the pointer is within range of the assumed wm frame + * decorations on the edge of the window. + */ + if (wf_t || wf_b || wf_l || wf_r) { + int near_edge = 0; + if (nabs(y - py) < wf_t) { + near_edge = 1; + } + if (nabs(y + h - py) < wf_b) { + near_edge = 1; + } + if (nabs(x - px) < wf_l) { + near_edge = 1; + } + if (nabs(x + w - px) < wf_r) { + near_edge = 1; + } + if (! near_edge) { +if (db) fprintf(stderr, "INTERIOR %d %d %d %d\n", wf_t, wf_b, wf_l, wf_r); + return 0; + } + } + + wireframe_in_progress = 1; + + if (button_mask_prev) { + already_down = 1; + } + + /* + * pointer() should have snapped the stacking list for us, if + * not, do it now (if the XFakeButtonEvent has been flushed by + * now the stacking order may be incorrect). + */ + if (strcmp(wireframe_copyrect, "never")) { + if (already_down) { + /* + * see if we can reuse the stack list (pause + * with button down) + */ + if (stack_list) { + int k, got_me = 0; + for (k = stack_num -1; k >=0; k--) { + if (frame == stack_list[k]) { + got_me = 1; + break; + } + } + if (! got_me) { + last_save_stacklist = 0; + } + } + if (stack_list && time(0) > last_save_stacklist + 1) { + /* stack_list too old */ + X_LOCK; + XFree(stack_list); + stack_list = NULL; + stack_num = 0; + X_UNLOCK; + } + } else if (! stack_list) { + /* ! already_down, might as well get a copy */ + X_LOCK; + snapshot_stack_list(); + X_UNLOCK; + } + } + + /* store initial parameters, we look for changes in them */ + orig_frame = frame; + orig_px = px; /* pointer position */ + orig_py = py; + orig_x = x; /* frame position */ + orig_y = y; + orig_w = w; /* frame size */ + orig_h = h; + + orig_cursor_x = cursor_x; + orig_cursor_y = cursor_y; + + /* this is the box frame we would draw */ + box_x = x; + box_y = y; + box_w = w; + box_h = h; + + dtime(&tm); + + last_draw = spin; + + /* -threads support for check_wireframe() is rough... crash? */ + if (use_threads) { + /* purge any stored up pointer events: */ + pointer(-1, 0, 0, NULL); + } + + g = g_in = got_pointer_input; + + while (1) { + + X_LOCK; + XFlush(dpy); + X_UNLOCK; + + /* try do induce/waitfor some more user input */ + if (use_threads) { + usleep(1000); + } else if (drew_box) { + rfbPE(screen, 1000); + } else { + rfbCFD(screen, 1000); + } + + spin += dtime(&tm); + + /* check for any timeouts: */ + if (frame_changed) { + /* max time we play this game: */ + if (spin > max_spin) { +if (db || db2) fprintf(stderr, " SPIN-OUT-MAX: %.3f\n", spin); + break_reason = 1; + break; + } + /* pointer events slowing down: */ + if (spin > last_ptr + frame_changed_spin) { +if (db || db2) fprintf(stderr, " SPIN-OUT-NOT-FAST: %.3f\n", spin); + break_reason = 2; + break; + } + } else if(got_2nd_pointer) { + /* + * pointer is moving, max time we wait for wm + * move or resize to be detected + */ + if (spin > frame_changed_spin) { +if (db || db2) fprintf(stderr, " SPIN-OUT-NOFRAME-SPIN: %.3f\n", spin); + break_reason = 3; + break; + } + } else { + /* max time we wait for any pointer input */ + if (spin > first_event_spin) { +if (db || db2) fprintf(stderr, " SPIN-OUT-NO2ND_PTR: %.3f\n", spin); + break_reason = 4; + break; + } + } + + /* see if some pointer input occurred: */ + if (got_pointer_input > g) { +if (db) fprintf(stderr, " ++pointer event!! [%02d] dt: %.3f x: %d y: %d mask: %d\n", got_2nd_pointer+1, spin, cursor_x, cursor_y, button_mask); + + g = got_pointer_input; + + /* periodically try to let the wm get moving: */ + if (!frame_changed && got_2nd_pointer % 4 == 0) { +#if 0 + X_LOCK; + XSync(dpy, False); + X_UNLOCK; +#endif + if (got_2nd_pointer == 0) { + usleep(50 * 1000); + } else { + usleep(25 * 1000); + } + } + got_2nd_pointer++; + last_ptr = spin; + + /* + * see where the pointer currently is. It may + * not be our starting frame (i.e. mouse now + * outside of the moving window). + */ + frame = 0x0; + X_LOCK; + + if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h, + &frame)) { + frame = 0x0; +if (db) fprintf(stderr, "NO get_wm_frame_pos: 0x%lx\n", frame); + } + + if (frame != orig_frame) { + /* see if our original frame is still there */ + if (!valid_window(orig_frame, &attr)) { + X_UNLOCK; + /* our window frame went away! */ + win_gone = 1; +if (db) fprintf(stderr, "FRAME-GONE: 0x%lx\n", orig_frame); + break_reason = 5; + break; + } + if (attr.map_state == IsUnmapped) { + X_UNLOCK; + /* our window frame is now unmapped! */ + win_unmapped = 1; +if (db) fprintf(stderr, "FRAME-UNMAPPED: 0x%lx\n", orig_frame); + break_reason = 5; + break; + } + +if (db) fprintf(stderr, "OUT-OF-FRAME: old: x: %d y: %d px: %d py: %d 0x%lx\n", x, y, px, py, frame); + + /* new parameters for our frame */ + x = attr.x; /* n.b. rootwin is parent */ + y = attr.y; + w = attr.width; + h = attr.height; + } + X_UNLOCK; + + /* debugging output, to be removed: */ +if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, frame); +if (db) fprintf(stderr, " MO,PT,FR: %d/%d %d/%d %d/%d\n", cursor_x - orig_cursor_x, cursor_y - orig_cursor_y, px - orig_px, py - orig_py, x - orig_x, y - orig_y); + + if (frame_changed && frame != orig_frame) { +if (db) fprintf(stderr, "CHANGED and window switch: 0x%lx\n", frame); + } + if (frame_changed && px - orig_px != x - orig_x) { +if (db) fprintf(stderr, "MOVED and diff DX\n"); + } + if (frame_changed && py - orig_py != y - orig_y) { +if (db) fprintf(stderr, "MOVED and diff DY\n"); + } + + /* check and see if our frame has been resized: */ + if (!frame_changed && (w != orig_w || h != orig_h)) { + int n; + if (!already_down) { + first_dt_ave += spin; + first_dt_cnt++; + } + n = first_dt_cnt ? first_dt_cnt : 1; + frame_changed = 2; + +if (db) fprintf(stderr, "WIN RESIZE 1st-dt: %.3f\n", first_dt_ave/n); + } + + /* check and see if our frame has been moved: */ + if (!frame_changed && (x != orig_x || y != orig_y)) { + int n; + if (!already_down) { + first_dt_ave += spin; + first_dt_cnt++; + } + n = first_dt_cnt ? first_dt_cnt : 1; + frame_changed = 1; +if (db) fprintf(stderr, "FRAME MOVE 1st-dt: %.3f\n", first_dt_ave/n); + } + + /* + * see if it is time to draw any or a new wireframe box + */ + if (frame_changed) { + int drawit = 0; + if (x != box_x || y != box_y) { + /* moved since last */ + drawit = 1; + } else if (w != box_w || h != box_h) { + /* resize since last */ + drawit = 1; + } + if (drawit) { + /* + * check time (to avoid too much + * animations on slow machines + * or links). + */ + if (spin > last_draw + min_draw || + ! drew_box) { + draw_box(x, y, w, h, 0); + drew_box = 1; + rfbPE(screen, 1000); + last_draw = spin; + } + } + box_x = x; + box_y = y; + box_w = w; + box_h = h; + } + } + + /* + * Now (not earlier) check if the button has come back up. + * we check here to get a better location and size of + * the final window. + */ + if (! button_mask) { +if (db || db2) fprintf(stderr, "NO button_mask\n"); + break_reason = 6; + break; + } + } + + if (! drew_box) { + /* nice try, but no move or resize detected. cleanup. */ + if (stack_list) { + X_LOCK; + XFree(stack_list); + X_UNLOCK; + stack_list = NULL; + stack_num = 0; + } + wireframe_in_progress = 0; + return 0; + } + + /* remove the wireframe */ + draw_box(0, 0, 0, 0, 1); + + dx = x - orig_x; + dy = y - orig_y; + + /* + * see if we can apply CopyRect or CopyRegion to the change: + */ + if (!scaling && w == orig_w && h == orig_h && (dx != 0 || dy != 0) && + !win_gone && !win_unmapped && strcmp(wireframe_copyrect, "never")) { + + int x1, y1, x2, y2, t, tmax = 50; + int spin_ms = (int) (spin * 1000 * 1000); + int sent_copyrect = 0; + int obscured = 0; + static int dt_bad = 0; + static time_t dt_bad_check = 0; + + /* + * set a timescale comparable to the spin time, + * but not too short or too long. + */ + if (spin_ms < 30) { + spin_ms = 30; + } else if (spin_ms > 400) { + spin_ms = 400; + } + + /* try to flush the wireframe removal: */ + fb_update_sent(NULL); + rfbPE(screen, spin_ms/3); /* long select */ + for (t=0; t<tmax; t++) { + if (fb_update_sent(NULL)) { +if (db2) fprintf(stderr, "A-FB_UPDATE_SENT: t=%d\n", t); + break; + } + rfbPE(screen, 1000); /* short selects. */ + } + + /* + * XXX KDE and xfce do some weird things with the + * stacking, it does not match XQueryTree. Work around + * it for now by CopyRect-ing the *whole* on-screen + * rectangle (whether obscured or not!) + */ + if (time(0) > dt_bad_check + 5) { + if (!strcmp(guess_desktop(), "kde")) { + dt_bad = 1; + } else if (!strcmp(guess_desktop(), "xfce")) { + dt_bad = 1; + } else { + dt_bad = 0; + } + dt_bad_check = time(0); + } + + if (dt_bad) { + /* send the whole thing... */ + x1 = crfix(nfix(x, dpy_x), dx, dpy_x); + y1 = crfix(nfix(y, dpy_y), dy, dpy_y); + x2 = crfix(nfix(x+w, dpy_x), dx, dpy_x); + y2 = crfix(nfix(y+h, dpy_y), dy, dpy_y); + + rfbDoCopyRect(screen, x1, y1, x2, y2, dx, dy); + + sent_copyrect = 1; + obscured = 1; /* set to avoid an aggressive push */ + +if (db2) fprintf(stderr, "CopyRect: x1: %d y1: %d x2: %d y2: %d dx: %d dy: %d spin: %.3f\n", x1, y1, x2, y2, dx, dy, spin); + + } else if (stack_list) { + int k, tx1, tx2, ty1, ty2; + sraRegionPtr moved_win, tmp_win; + int saw_me = 0; + + tx1 = nfix(orig_x, dpy_x); + ty1 = nfix(orig_y, dpy_y); + tx2 = nfix(orig_x+w, dpy_x); + ty2 = nfix(orig_y+h, dpy_y); + +if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n", tx1, ty1, tx2, ty2, frame); + + moved_win = sraRgnCreateRect(tx1, ty1, tx2, ty2); + + X_LOCK; + + /* + * loop over the stack, top to bottom until we + * find our wm frame: + */ + for (k = stack_num - 1; k >= 0; k--) { + Window win = stack_list[k]; + if (win == frame) { +if (db2) { + saw_me = 1; + fprintf(stderr, " ----------\n"); +} else { + break; +} + } + + /* skip some unwanted cases: */ + if (win == None) { + continue; + } + if (!valid_window(win, &attr)) { + continue; + } + if (attr.map_state != IsViewable) { + continue; + } + + /* clip the window to the visable screen: */ + tx1 = nfix(attr.x, dpy_x); + ty1 = nfix(attr.y, dpy_y); + tx2 = nfix(attr.x + attr.width, dpy_x); + ty2 = nfix(attr.y + attr.height, dpy_y); + +if (db2) fprintf(stderr, " tmp_win: %4d %3d, %4d %3d 0x%lx\n", tx1, ty1, tx2, ty2, win); +if (db2 && saw_me) continue; + + /* see if window clips us: */ + tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2); + if (sraRgnAnd(tmp_win, moved_win)) { + obscured = 1; +if (db2) fprintf(stderr, " : clips it.\n"); + } + sraRgnDestroy(tmp_win); + + /* subtract it from our region: */ + tmp_win = sraRgnCreateRect(tx1, ty1, tx2, ty2); + sraRgnSubtract(moved_win, tmp_win); + sraRgnDestroy(tmp_win); + } + X_UNLOCK; + + if (obscured && !strcmp(wireframe_copyrect, "top")) { + ; /* cannot send CopyRegion */ + } else if (! sraRgnEmpty(moved_win)) { + sraRectangleIterator *iter; + sraRegionPtr whole, shifted_region; + sraRect rect; + + /* + * prepare for CopyRegion, apply dx and + * dy to each rectangle in the region. + * keep only the part on the screen. + */ + whole = sraRgnCreateRect(0, 0, dpy_x, dpy_y); + shifted_region = sraRgnCreate(); + +if (db2) fprintf(stderr, "\n"); + + iter = sraRgnGetIterator(moved_win); + while (sraRgnIteratorNext(iter, &rect)) { + tx1 = rect.x1 + dx; + ty1 = rect.y1 + dy; + tx2 = rect.x2 + dx; + ty2 = rect.y2 + dy; + +if (db2) fprintf(stderr, " shf_win: %4d %3d, %4d %3d\n", tx1, ty1, tx2, ty2); + + tmp_win = sraRgnCreateRect(tx1, ty1, + tx2, ty2); + sraRgnAnd(tmp_win, whole); + if (! sraRgnEmpty(tmp_win)) { + sraRgnOr(shifted_region, + tmp_win); + } + sraRgnDestroy(tmp_win); + } + sraRgnReleaseIterator(iter); + sraRgnDestroy(whole); + + /* now send the CopyRegion: */ + if (! sraRgnEmpty(shifted_region)) { + rfbDoCopyRegion(screen, shifted_region, + dx, dy); + sent_copyrect = 1; +if (db2) fprintf(stderr, " rfbDoCopyRegion\n"); + } + sraRgnDestroy(shifted_region); + } + sraRgnDestroy(moved_win); + } + + if (sent_copyrect) { + + /* try to push the changes to viewers: */ + fb_update_sent(NULL); + rfbPE(screen, spin_ms/3); + if (! obscured) { + for (t=0; t<tmax; t++) { + if (fb_update_sent(NULL)) { +if (db2) fprintf(stderr, "B-FB_UPDATE_SENT: t=%d\n", t); + break; + } + rfbPE(screen, 1000); + } + } + } + } + + if (stack_list) { + /* clean up stack_list for next time: */ + if (break_reason == 1 || break_reason == 2) { + /* + * save the stack list, perhaps the user has + * paused with button down. XXX unstable if + * windows in the list go away? + */ + last_save_stacklist = time(0); + } else { + X_LOCK; + XFree(stack_list); + X_UNLOCK; + stack_list = NULL; + stack_num = 0; + } + } + + /* final push (for -nowirecopyrect) */ + rfbPE(screen, 1000); + wireframe_in_progress = 0; + return 1; +} /* * We need to handle user input, particularly pointer input, carefully. @@ -18416,7 +19938,9 @@ static void check_user_input2(double dt) { } else { rfbCFD(screen, 1000); } + X_LOCK; XFlush(dpy); + X_UNLOCK; spin += dtime(&tm); @@ -18481,7 +20005,9 @@ static void check_user_input2(double dt) { } spin += dtime(&tm); if (got_pointer_input > g) { + X_LOCK; XFlush(dpy); + X_UNLOCK; miss = 0; } else { miss++; @@ -18533,7 +20059,9 @@ static void check_user_input3(double dt) { } else { rfbCFD(screen, 1000); } + X_LOCK; XFlush(dpy); + X_UNLOCK; spin += dtime(&tm); @@ -18614,7 +20142,9 @@ static void check_user_input3(double dt) { } spin += dtime(&tm); if (got_pointer_input > g) { + X_LOCK; XFlush(dpy); + X_UNLOCK; miss = 0; } else { miss++; @@ -18984,6 +20514,17 @@ static void check_user_input5(double dt, double dtr, int tile_diffs) { } static int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) { + + if (raw_fb && ! dpy) return 0; /* raw_fb hack */ + + maybe_scrolling = None; + + if (wireframe) { + if (check_wireframe()) { + return 0; + } + } + if (pointer_mode == 1) { if ((got_user_input || ui_skip < 0) && *cnt % ui_skip != 0) { /* every ui_skip-th drops thru to scan */ @@ -19022,6 +20563,11 @@ static int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) { return 0; } +/* -- x11vnc.c -- */ +/* + * main routine for the x11vnc program + */ + /* * simple function for measuring sub-second time differences, using * a double to hold the value. @@ -19351,6 +20897,8 @@ static void watch_loop(void) { /* true means loop back for more input */ continue; } + } else if (use_threads && wireframe && button_mask) { + check_wireframe(); } if (shut_down) { @@ -20146,6 +21694,62 @@ static void print_help(int mode) { " slow setups, but you lose all visual feedback for drags,\n" " text selection, and some menu traversals. It overrides\n" " any -pointer_mode setting\n" +"\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" +" the full opaque window. This is based completely on\n" +" heuristics and may not always work: it depends on your\n" +" window manager and even how you move things around.\n" +" See -pointer_mode below for discussion of the \"bogging\n" +" down\" problem this tries to avoid. Default: %s\n" +"\n" +" The value \"str\" is optional and, of course, is\n" +" packed with many tunable parameters for this scheme:\n" +"\n" +" Format: shade,linewidth,percent,T+B+L+R,t1+t2+t3+t4\n" +" Default: %s\n" +"\n" +" If you leave nothing between commas: \",,\" the default\n" +" value is used. If you don't specify enough commas,\n" +" the trailing parameters are set to their defaults.\n" +"\n" +" \"shade\" indicate the \"color\" for the wireframe,\n" +" usually a greyscale: 0-255, however for 16 and 32bpp you\n" +" can specify an rgb.txt X color (e.g. \"dodgerblue\") or\n" +" a value > 255 is treated as RGB (e.g. red is 0xff0000).\n" +" \"linewidth\" sets the width of the wireframe in pixels.\n" +" \"percent\" indicates to not apply the wireframe scheme\n" +" to windows with area less than this percent of the\n" +" full screen.\n" +"\n" +" \"T+B+L+R\" indicates four integers for how close in\n" +" pixels the pointer has to be from the Top, Bottom, Left,\n" +" or Right edges of the window to consider wireframing.\n" +" This is a speedup to quickly exclude a window from being\n" +" wireframed: set them all to zero to not try the speedup\n" +" (scrolling and selecting text will likely be slower).\n" +"\n" +" \"t1+t2+t3+t4\" specify four floating point times in\n" +" seconds: t1 is how long to wait for the pointer to move,\n" +" t2 is how long to wait for the window to start moving\n" +" or being resized (for some window managers this can be\n" +" rather long), t3 is how long to keep a wireframe moving\n" +" before repainting the window. t4 is the minimum time\n" +" between sending wireframe \"animations\". For a slow\n" +" link this might be a better choice: 0.25+0.6+6.0+0.15\n" +"\n" +"-wirecopyrect mode Since the -wireframe mechanism evidently tracks moving\n" +"-nowirecopyrect windows, a speedup can be obtained by telling the VNC\n" +" viewers to locally copy the translated window region.\n" +" This is the VNC CopyRect encoding: the framebuffer\n" +" update doesn't need to send the actual new image data.\n" +" \"mode\" can be \"never\" (same as -nowirecopyrect)\n" +" to never try the copyrect, \"top\" means only do it if\n" +" the window was not covered by any other windows, and\n" +" \"always\" means to translate the orginally unobscured\n" +" region (this may look odd as the remaining pieces come\n" +" in, but helps on a slow link) Default: %s\n" +"\n" "-pointer_mode n Various pointer motion update schemes. \"-pm\" is\n" " an alias. The problem is pointer motion can cause\n" " rapid changes on the screen: consider the rapid changes\n" @@ -20169,7 +21773,6 @@ static void print_help(int mode) { " n=2 is an improved scheme: by watching the current rate\n" " of input events it tries to detect if it should try to\n" " \"eat\" additional pointer events before continuing.\n" -" This mode was the default until Apr 2005.\n" "\n" " n=3 is basically the same as n=2 except with slightly\n" " tweaked parameters. We made this a new one so one\n" @@ -20311,8 +21914,9 @@ static void print_help(int mode) { " which specifies a shmid N and framebuffer Width, Height,\n" " and Bits per pixel. To memory map mmap(2) a file use:\n" " \"map:/path/to/a/file@WxHxB\". If there is trouble\n" -" with mmap, use \"file:/...\" for slower lseek(2) based\n" -" reading.\n" +" with mmap, use \"file:/...\" for slower lseek(2)\n" +" based reading. If you do not supply a type \"map\"\n" +" is assumed if the file exists.\n" "\n" " If string is \"setup:cmd\", then the command \"cmd\"\n" " is run and the first line from it is read and used\n" @@ -20336,10 +21940,16 @@ static void print_help(int mode) { " All user input is discarded. Most of the X11 (screen,\n" " keyboard, mouse) options do not make sense and many\n" " will cause this mode to crash, so please think twice\n" -" before setting/changing them. If you don't want x11vnc\n" -" to close the DISPLAY in rawfb mode, then capitalize\n" -" the prefix, SHM:, MAP: etc. Keeping the display open\n" -" enables default remote-control channel.\n" +" before setting/changing them.\n" +"\n" +" If you don't want x11vnc to close the X DISPLAY in\n" +" rawfb mode, then capitalize the prefix, SHM:, MAP:,\n" +" FILE: Keeping the display open enables the default\n" +" remote-control channel, which could be useful. Also,\n" +" if you also specify -noviewonly, then the mouse and\n" +" keyboard input are still sent to the X display, this\n" +" usage should be very rare, i.e. doing something strange\n" +" with /dev/fb0.\n" "\n" "-pipeinput cmd Another experimental option: it lets you supply\n" " an extern command in \"cmd\" that x11vnc will pipe\n" @@ -20594,6 +22204,11 @@ static void print_help(int mode) { " buttonmap:str set -buttonmap \"str\", empty to disable\n" " dragging disable -nodragging mode.\n" " nodragging enable -nodragging mode.\n" +" wireframe enable -wireframe mode.\n" +" nowireframe disable -wireframe mode.\n" +" wireframe:str enable -wireframe mode string.\n" +" wireframe_mode:str enable -wireframe mode string.\n" +" wirecopyrect:str set -wirecopyrect string.\n" " pointer_mode:n set -pointer_mode to n. same as \"pm\"\n" " input_skip:n set -input_skip to n.\n" " speeds:str set -speeds to str.\n" @@ -20690,31 +22305,33 @@ static void print_help(int mode) { " noxtrap xrandr noxrandr xrandr_mode padgeom quiet q\n" " noquiet modtweak nomodtweak xkb noxkb skip_keycodes\n" " add_keysyms noadd_keysyms clear_mods noclear_mods\n" -" clear_keys noclear_keys remap repeat norepeat fb nofb\n" -" bell nobell sel nosel primary noprimary cursorshape\n" -" nocursorshape cursorpos nocursorpos cursor show_cursor\n" -" noshow_cursor nocursor arrow xfixes noxfixes xdamage\n" -" noxdamage xd_area xd_mem alphacut alphafrac alpharemove\n" -" noalpharemove alphablend noalphablend xwarp xwarppointer\n" -" noxwarp noxwarppointer buttonmap dragging nodragging\n" +" clear_keys noclear_keys remap repeat norepeat\n" +" fb nofb bell nobell sel nosel primary noprimary\n" +" cursorshape nocursorshape cursorpos nocursorpos\n" +" cursor show_cursor noshow_cursor nocursor arrow\n" +" xfixes noxfixes xdamage noxdamage xd_area xd_mem\n" +" alphacut alphafrac alpharemove noalpharemove alphablend\n" +" noalphablend xwarp xwarppointer noxwarp noxwarppointer\n" +" buttonmap dragging nodragging wireframe_mode\n" +" wireframe nowireframe wirecopyrect nowirecopyrect\n" " pointer_mode pm input_skip input client_input speeds\n" " debug_pointer dp nodebug_pointer nodp debug_keyboard dk\n" -" nodebug_keyboard nodk deferupdate defer wait rfbwait nap\n" -" nonap sb screen_blank fs gaps grow fuzz snapfb nosnapfb\n" -" rawfb setup: progressive rfbport http nohttp httpport\n" +" nodebug_keyboard nodk deferupdate defer wait rfbwait\n" +" nap nonap sb screen_blank fs gaps grow fuzz snapfb\n" +" nosnapfb rawfb progressive rfbport http nohttp httpport\n" " httpdir enablehttpproxy noenablehttpproxy alwaysshared\n" " noalwaysshared nevershared noalwaysshared dontdisconnect\n" " nodontdisconnect desktop noremote\n" "\n" -" aro= debug_xevents: display vncdisplay desktopname\n" -" http_url auth users rootshift clipshift scale_str\n" -" scaled_x scaled_y scale_numer scale_denom\n" +" aro= debug_xevents debug_xdamage display vncdisplay\n" +" desktopname http_url auth users rootshift clipshift\n" +" scale_str scaled_x scaled_y scale_numer scale_denom\n" " scale_fac scaling_blend scaling_nomult4 scaling_pad\n" -" scaling_interpolate inetd safer unsafe passwdfile\n" -" using_shm logfile o flag rc norc h help V version\n" -" lastmod bg sigpipe threads pipeinput clients\n" -" client_count pid ext_xtest ext_xtrap ext_xkb ext_xshm\n" -" ext_xinerama ext_overlay ext_xfixes ext_xdamage\n" +" scaling_interpolate inetd privremote unsafe safer\n" +" nocmds passwdfile using_shm logfile o flag rc norc h\n" +" help V version lastmod bg sigpipe threads pipeinput\n" +" clients client_count pid ext_xtest ext_xtrap ext_xkb\n" +" ext_xshm ext_xinerama ext_overlay ext_xfixes ext_xdamage\n" " ext_xrandr rootwin num_buttons button_mask mouse_x\n" " mouse_y bpp depth indexed_color dpy_x dpy_y wdpy_x\n" " wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y rfbauth\n" @@ -20752,22 +22369,29 @@ static void print_help(int mode) { " channel is being used, obviously anyone who can write\n" " to /path/to/file can remotely control x11vnc. So be\n" " sure to protect the X display and that file's write\n" -" permissions.\n" +" permissions. See -privremote below.\n" "\n" " If you are paranoid and do not think -noremote is\n" " enough, to disable the VNC_CONNECT property channel\n" -" completely use -novncconnect.\n" +" completely use -novncconnect, or use the -safer\n" +" option that shuts many things off.\n" "\n" -"-unsafe If x11vnc is running as root (e.g. inetd or Xsetup for\n" -" a display manager) a few remote commands are disabled\n" -" (currently: id:pick, accept:<cmd>, and gone:<cmd>)\n" -" because they are associated with running external\n" -" programs. If you specify -unsafe, then these remote\n" -" control commands are allowed when running as root.\n" -" When running as non-root all commands are allowed.\n" -" See -safer below.\n" -"-safer Even if not running as root, disable the above unsafe\n" -" remote control commands.\n" +"-unsafe A few remote commands are disabled by default\n" +" (currently: id:pick, accept:<cmd>, gone:<cmd>, and\n" +" rawfb:setup:<cmd>) because they are associated with\n" +" running external programs. If you specify -unsafe, then\n" +" these remote-control commands are allowed. Note that\n" +" you can still specify these parameters on the command\n" +" line, they just cannot be changed via remote-control.\n" +"-safer Equivalent to: -novncconnect -noremote and prohibiting\n" +" -gui and the -connect file. Shuts off communcation\n" +" channels.\n" +"-privremote Perform some sanity checks and only allow remote-control\n" +" commands if it appears that the X DISPLAY and/or\n" +" connectfile cannot be accessed by other users. (not\n" +" complete, does not check for empty access control list)\n" +"-nocmds No external commands (e.g. system(3), popen(3), exec(3))\n" +" will be run.\n" "\n" "-deny_all For use with -remote nodeny: start out denying all\n" " incoming clients until \"-remote nodeny\" is used to\n" @@ -20814,6 +22438,9 @@ static void print_help(int mode) { alpha_threshold, alpha_frac, cursor_pos_updates ? "-cursorpos":"-nocursorpos", + wireframe ? "-wireframe":"-nowireframe", + WIREFRAME_PARMS, + wireframe_copyrect_default, pointer_mode_max, pointer_mode, ui_skip, defer_update, @@ -20942,7 +22569,7 @@ static char *choose_title(char *display) { } } strncat(title, display, MAXN - strlen(title)); - if (subwin && valid_window(subwin)) { + if (subwin && valid_window(subwin, NULL)) { char *name; if (XFetchName(dpy, subwin, &name)) { strncat(title, " ", MAXN - strlen(title)); @@ -21204,9 +22831,7 @@ int main(int argc, char* argv[]) { /* used to pass args we do not know about to rfbGetScreen(): */ int argc_vnc = 1; char *argv_vnc[128]; - /* if we are root limit some remote commands, etc: */ if (!getuid() || !geteuid()) { - safe_remote_only = 1; started_as_root = 1; /* check for '-users =bob' */ @@ -21270,7 +22895,7 @@ int main(int argc, char* argv[]) { } i++; if (!strcmp("pick", argv[i])) { - if (safe_remote_only) { + if (started_as_root) { fprintf(stderr, "unsafe: %s pick\n", arg); exit(1); @@ -21314,6 +22939,9 @@ int main(int argc, char* argv[]) { scale_cursor_str = strdup(argv[++i]); } else if (!strcmp(arg, "-viewonly")) { view_only = 1; + } else if (!strcmp(arg, "-noviewonly")) { + view_only = 0; + got_noviewonly = 1; } else if (!strcmp(arg, "-shared")) { shared = 1; } else if (!strcmp(arg, "-once")) { @@ -21532,6 +23160,21 @@ int main(int argc, char* argv[]) { pointer_remap = strdup(argv[++i]); } else if (!strcmp(arg, "-nodragging")) { show_dragging = 0; + } else if (!strcmp(arg, "-wireframe")) { + wireframe = 1; + if (i < argc-1) { + char *s = argv[i+1]; + if (*s != '-') { + wireframe_str = strdup(argv[++i]); + } + } + } else if (!strcmp(arg, "-nowireframe")) { + wireframe = 0; + } else if (!strcmp(arg, "-wirecopyrect")) { + CHECK_ARGC + set_wirecopyrect_mode(argv[++i]); + } else if (!strcmp(arg, "-nowirecopyrect")) { + set_wirecopyrect_mode("never"); } else if (!strcmp(arg, "-pointer_mode") || !strcmp(arg, "-pm")) { char *p, *s; @@ -21658,8 +23301,12 @@ int main(int argc, char* argv[]) { accept_remote_cmds = 0; } else if (!strcmp(arg, "-unsafe")) { safe_remote_only = 0; + } else if (!strcmp(arg, "-privremote")) { + priv_remote = 1; } else if (!strcmp(arg, "-safer")) { - safe_remote_only = 1; + more_safe = 1; + } else if (!strcmp(arg, "-nocmds")) { + no_external_cmds = 1; } else if (!strcmp(arg, "-deny_all")) { deny_all = 1; } else if (!strcmp(arg, "-httpdir")) { @@ -21857,6 +23504,20 @@ int main(int argc, char* argv[]) { exit(1); } + if (more_safe) { + if (! quiet) { + rfbLog("-safer mode:\n"); + rfbLog(" vnc_connect=0\n"); + rfbLog(" accept_remote_cmds=0\n"); + rfbLog(" safe_remote_only=1\n"); + rfbLog(" launch_gui=0\n"); + } + vnc_connect = 0; + accept_remote_cmds = 0; + safe_remote_only = 1; + launch_gui = 0; + } + /* fixup settings that do not make sense */ if (use_threads && nofb && cursor_pos_updates) { @@ -21898,6 +23559,10 @@ int main(int argc, char* argv[]) { rfbLog("warning: -flipbyte order only works with -noshm\n"); } + if (! wireframe_copyrect) { + set_wirecopyrect_mode(NULL); + } + /* increase rfbwait if threaded */ if (use_threads && ! got_rfbwait) { if (0) { @@ -22055,6 +23720,8 @@ int main(int argc, char* argv[]) { fprintf(stderr, " buttonmap: %s\n", pointer_remap ? pointer_remap : "null"); fprintf(stderr, " dragging: %d\n", show_dragging); + fprintf(stderr, " wireframe: %s\n", wireframe_str ? + wireframe_str : WIREFRAME_PARMS); fprintf(stderr, " ptr_mode: %d\n", pointer_mode); fprintf(stderr, " inputskip: %d\n", ui_skip); fprintf(stderr, " speeds: %s\n", speeds_str @@ -22085,6 +23752,9 @@ int main(int argc, char* argv[]) { ? gui_str : "null"); fprintf(stderr, " noremote: %d\n", !accept_remote_cmds); fprintf(stderr, " safemode: %d\n", safe_remote_only); + fprintf(stderr, " privremote: %d\n", priv_remote); + fprintf(stderr, " safer: %d\n", more_safe); + fprintf(stderr, " nocmds: %d\n", no_external_cmds); fprintf(stderr, " deny_all: %d\n", deny_all); fprintf(stderr, "\n"); rfbLog("x11vnc version: %s\n", lastmod); |