summaryrefslogtreecommitdiffstats
path: root/x11vnc/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/remote.c')
-rw-r--r--x11vnc/remote.c3766
1 files changed, 3766 insertions, 0 deletions
diff --git a/x11vnc/remote.c b/x11vnc/remote.c
new file mode 100644
index 0000000..2a82ca8
--- /dev/null
+++ b/x11vnc/remote.c
@@ -0,0 +1,3766 @@
+/* -- remote.c -- */
+
+#include "x11vnc.h"
+#include "inet.h"
+#include "xwrappers.h"
+#include "xevents.h"
+#include "xinerama.h"
+#include "xrandr.h"
+#include "xdamage.h"
+#include "xrecord.h"
+#include "xkb_bell.h"
+#include "win_utils.h"
+#include "screen.h"
+#include "cleanup.h"
+#include "gui.h"
+#include "solid.h"
+#include "user.h"
+#include "rates.h"
+#include "scan.h"
+#include "connections.h"
+#include "pointer.h"
+#include "cursor.h"
+#include "userinput.h"
+#include "keyboard.h"
+
+int send_remote_cmd(char *cmd, int query, int wait);
+int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
+ int qdefault);
+void check_black_fb(void);
+int check_httpdir(void);
+void http_connections(int on);
+int remote_control_access_ok(void);
+char *process_remote_cmd(char *cmd, int stringonly);
+
+
+static char *add_item(char *instr, char *item);
+static char *delete_item(char *instr, char *item);
+static void if_8bpp_do_new_fb(void);
+static void reset_httpport(int old, int new);
+static void reset_rfbport(int old, int new) ;
+
+
+/*
+ * for the wild-n-crazy -remote/-R interface.
+ */
+int send_remote_cmd(char *cmd, int query, int wait) {
+ FILE *in = NULL;
+
+ if (client_connect_file) {
+ in = fopen(client_connect_file, "w");
+ if (in == NULL) {
+ fprintf(stderr, "send_remote_cmd: could not open "
+ "connect file \"%s\" for writing\n",
+ client_connect_file);
+ perror("fopen");
+ return 1;
+ }
+ } else if (vnc_connect_prop == None) {
+ initialize_vnc_connect_prop();
+ if (vnc_connect_prop == None) {
+ fprintf(stderr, "send_remote_cmd: could not obtain "
+ "VNC_CONNECT X property\n");
+ return 1;
+ }
+ }
+
+ if (in != NULL) {
+ fprintf(stderr, ">>> sending remote command: \"%s\"\n via"
+ " connect file: %s\n", cmd, client_connect_file);
+ fprintf(in, "%s\n", cmd);
+ fclose(in);
+ } else {
+ fprintf(stderr, ">>> sending remote command: \"%s\" via"
+ " VNC_CONNECT X property.\n", cmd);
+ set_vnc_connect_prop(cmd);
+ XFlush(dpy);
+ }
+
+ if (query || wait) {
+ char line[VNC_CONNECT_MAX];
+ int rc=1, i=0, max=70, ms_sl=50;
+
+ if (!strcmp(cmd, "cmd=stop")) {
+ max = 20;
+ }
+ for (i=0; i<max; i++) {
+ usleep(ms_sl * 1000);
+ if (client_connect_file) {
+ char *q;
+ in = fopen(client_connect_file, "r");
+ if (in == NULL) {
+ fprintf(stderr, "send_remote_cmd: could"
+ " not open connect file \"%s\" for"
+ " writing\n", client_connect_file);
+ perror("fopen");
+ return 1;
+ }
+ fgets(line, VNC_CONNECT_MAX, in);
+ fclose(in);
+ q = line;
+ while (*q != '\0') {
+ if (*q == '\n') *q = '\0';
+ q++;
+ }
+ } else {
+ read_vnc_connect_prop();
+ strncpy(line, vnc_connect_str, VNC_CONNECT_MAX);
+ }
+ if (strcmp(cmd, line)){
+ if (query) {
+ fprintf(stdout, "%s\n", line);
+ fflush(stdout);
+ }
+ rc = 0;
+ break;
+ }
+ }
+ if (rc) {
+ fprintf(stderr, "error: could not connect to "
+ "an x11vnc server at %s (rc=%d)\n",
+ client_connect_file ? client_connect_file
+ : DisplayString(dpy), rc);
+ }
+ return rc;
+ }
+ return 0;
+}
+
+int do_remote_query(char *remote_cmd, char *query_cmd, int remote_sync,
+ int qdefault) {
+ char *rcmd = NULL, *qcmd = NULL;
+ int rc = 1;
+
+ if (qdefault && !query_cmd) {
+ query_cmd = remote_cmd;
+ remote_cmd = NULL;
+ }
+
+ if (remote_cmd) {
+ rcmd = (char *) malloc(strlen(remote_cmd) + 5);
+ strcpy(rcmd, "cmd=");
+ strcat(rcmd, remote_cmd);
+ }
+ if (query_cmd) {
+ qcmd = (char *) malloc(strlen(query_cmd) + 5);
+ strcpy(qcmd, "qry=");
+ strcat(qcmd, query_cmd);
+ }
+ if (qdefault) {
+ char *res;
+ if (!qcmd) {
+ return 1;
+ }
+ res = process_remote_cmd(qcmd, 1);
+ fprintf(stdout, "%s\n", res);
+ fflush(stdout);
+ return 0;
+ }
+
+ if (rcmd && qcmd) {
+ rc = send_remote_cmd(rcmd, 0, 1);
+ if (rc) {
+ free(rcmd);
+ free(qcmd);
+ return(rc);
+ }
+ rc = send_remote_cmd(qcmd, 1, 1);
+ } else if (rcmd) {
+ rc = send_remote_cmd(rcmd, 0, remote_sync);
+ free(rcmd);
+ } else if (qcmd) {
+ rc = send_remote_cmd(qcmd, 1, 1);
+ free(qcmd);
+ }
+ return rc;
+}
+
+static char *add_item(char *instr, char *item) {
+ char *p, *str;
+ int len, saw_item = 0;
+
+ if (! instr || *instr == '\0') {
+ str = strdup(item);
+ return str;
+ }
+ len = strlen(instr) + 1 + strlen(item) + 1;
+ str = (char *) malloc(len);
+ str[0] = '\0';
+
+ /* n.b. instr will be modified; caller replaces with returned string */
+ p = strtok(instr, ",");
+ while (p) {
+ if (!strcmp(p, item)) {
+ if (saw_item) {
+ p = strtok(NULL, ",");
+ continue;
+ }
+ saw_item = 1;
+ } else if (*p == '\0') {
+ p = strtok(NULL, ",");
+ continue;
+ }
+ if (str[0]) {
+ strcat(str, ",");
+ }
+ strcat(str, p);
+ p = strtok(NULL, ",");
+ }
+ if (! saw_item) {
+ if (str[0]) {
+ strcat(str, ",");
+ }
+ strcat(str, item);
+ }
+ return str;
+}
+
+static char *delete_item(char *instr, char *item) {
+ char *p, *str;
+ int len;
+
+ if (! instr || *instr == '\0') {
+ str = strdup("");
+ return str;
+ }
+ len = strlen(instr) + 1;
+ str = (char *) malloc(len);
+ str[0] = '\0';
+
+ /* n.b. instr will be modified; caller replaces with returned string */
+ p = strtok(instr, ",");
+ while (p) {
+ if (!strcmp(p, item) || *p == '\0') {
+ p = strtok(NULL, ",");
+ continue;
+ }
+ if (str[0]) {
+ strcat(str, ",");
+ }
+ strcat(str, p);
+ p = strtok(NULL, ",");
+ }
+ return str;
+}
+
+static void if_8bpp_do_new_fb(void) {
+ if (bpp == 8) {
+ do_new_fb(0);
+ } else {
+ rfbLog(" bpp(%d) is not 8bpp, not resetting fb\n", bpp);
+ }
+}
+
+void check_black_fb(void) {
+ if (!screen) {
+ return;
+ }
+ if (new_fb_size_clients(screen) != client_count) {
+ rfbLog("trying to send a black fb for non-newfbsize"
+ " clients %d != %d\n", client_count,
+ new_fb_size_clients(screen));
+ push_black_screen(4);
+ }
+}
+
+int check_httpdir(void) {
+ if (http_dir) {
+ return 1;
+ } else {
+ char *prog = NULL, *httpdir, *q;
+ struct stat sbuf;
+ int len;
+
+ rfbLog("check_httpdir: trying to guess httpdir...\n");
+ if (program_name[0] == '/') {
+ prog = strdup(program_name);
+ } else {
+ char cwd[1024];
+ getcwd(cwd, 1024);
+ len = strlen(cwd) + 1 + strlen(program_name) + 1;
+ prog = (char *) malloc(len);
+ snprintf(prog, len, "%s/%s", cwd, program_name);
+ if (stat(prog, &sbuf) != 0) {
+ char *path = strdup(getenv("PATH"));
+ char *p, *base;
+ base = strrchr(program_name, '/');
+ if (base) {
+ base++;
+ } else {
+ base = program_name;
+ }
+
+ p = strtok(path, ":");
+ while(p) {
+ free(prog);
+ len = strlen(p) + 1 + strlen(base) + 1;
+ prog = (char *) malloc(len);
+ snprintf(prog, len, "%s/%s", p, base);
+ if (stat(prog, &sbuf) == 0) {
+ break;
+ }
+ p = strtok(NULL, ":");
+ }
+ free(path);
+ }
+ }
+ /*
+ * /path/to/bin/x11vnc
+ * /path/to/bin/../share/x11vnc/classes
+ * 12345678901234567
+ */
+ if ((q = strrchr(prog, '/')) == NULL) {
+ rfbLog("check_httpdir: bad program path: %s\n", prog);
+ free(prog);
+ return 0;
+ }
+
+ len = strlen(prog) + 17 + 1;
+ *q = '\0';
+ httpdir = (char *) malloc(len);
+ snprintf(httpdir, len, "%s/../share/x11vnc/classes", prog);
+ free(prog);
+
+ if (stat(httpdir, &sbuf) == 0) {
+ /* good enough for me */
+ rfbLog("check_httpdir: guessed directory:\n");
+ rfbLog(" %s\n", httpdir);
+ http_dir = httpdir;
+ return 1;
+ } else {
+ /* try some hardwires: */
+ if (stat("/usr/local/share/x11vnc/classes",
+ &sbuf) == 0) {
+ http_dir =
+ strdup("/usr/local/share/x11vnc/classes");
+ return 1;
+ }
+ if (stat("/usr/share/x11vnc/classes", &sbuf) == 0) {
+ http_dir = strdup("/usr/share/x11vnc/classes");
+ return 1;
+ }
+ rfbLog("check_httpdir: bad guess:\n");
+ rfbLog(" %s\n", httpdir);
+ return 0;
+ }
+ }
+}
+
+void http_connections(int on) {
+ if (!screen) {
+ return;
+ }
+ if (on) {
+ rfbLog("http_connections: turning on http service.\n");
+ screen->httpInitDone = FALSE;
+ screen->httpDir = http_dir;
+ if (check_httpdir()) {
+ rfbHttpInitSockets(screen);
+ }
+ } else {
+ rfbLog("http_connections: turning off http service.\n");
+ if (screen->httpListenSock > -1) {
+ close(screen->httpListenSock);
+ }
+ screen->httpListenSock = -1;
+ screen->httpDir = NULL;
+ }
+}
+
+static void reset_httpport(int old, int new) {
+ int hp = new;
+ if (hp < 0) {
+ rfbLog("reset_httpport: invalid httpport: %d\n", hp);
+ } else if (hp == old) {
+ rfbLog("reset_httpport: unchanged httpport: %d\n", hp);
+ } else if (inetd) {
+ rfbLog("reset_httpport: cannot set httpport: %d"
+ " in inetd.\n", hp);
+ } else if (screen) {
+ screen->httpPort = hp;
+ screen->httpInitDone = FALSE;
+ if (screen->httpListenSock > -1) {
+ close(screen->httpListenSock);
+ }
+ rfbLog("reset_httpport: setting httpport %d -> %d.\n",
+ old == -1 ? hp : old, hp);
+ rfbHttpInitSockets(screen);
+ }
+}
+
+static void reset_rfbport(int old, int new) {
+ int rp = new;
+ if (rp < 0) {
+ rfbLog("reset_rfbport: invalid rfbport: %d\n", rp);
+ } else if (rp == old) {
+ rfbLog("reset_rfbport: unchanged rfbport: %d\n", rp);
+ } else if (inetd) {
+ rfbLog("reset_rfbport: cannot set rfbport: %d"
+ " in inetd.\n", rp);
+ } else if (screen) {
+ rfbClientIteratorPtr iter;
+ rfbClientPtr cl;
+ int maxfd;
+ if (rp == 0) {
+ screen->autoPort = TRUE;
+ } else {
+ screen->autoPort = FALSE;
+ }
+ screen->port = rp;
+ screen->socketState = RFB_SOCKET_INIT;
+
+ if (screen->listenSock > -1) {
+ close(screen->listenSock);
+ }
+
+ rfbLog("reset_rfbport: setting rfbport %d -> %d.\n",
+ old == -1 ? rp : old, rp);
+ rfbInitSockets(screen);
+
+ maxfd = screen->maxFd;
+ if (screen->udpSock > 0 && screen->udpSock > maxfd) {
+ maxfd = screen->udpSock;
+ }
+ iter = rfbGetClientIterator(screen);
+ while( (cl = rfbClientIteratorNext(iter)) ) {
+ if (cl->sock > -1) {
+ FD_SET(cl->sock, &(screen->allFds));
+ if (cl->sock > maxfd) {
+ maxfd = cl->sock;
+ }
+ }
+ }
+ rfbReleaseClientIterator(iter);
+
+ screen->maxFd = maxfd;
+
+ set_vnc_desktop_name();
+ }
+}
+
+/*
+ * 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;
+ XHostAddress *xha;
+ Bool enabled;
+ int n;
+
+ 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;
+ }
+ }
+
+ xha = XListHosts(dpy, &n, &enabled);
+ if (! enabled) {
+ rfbLog("X access control is disabled, X clients can\n");
+ rfbLog(" connect from any host. Run 'xhost -'\n");
+ return 0;
+ }
+ if (xha) {
+ int i;
+ rfbLog("The following hosts can connect w/o X11 "
+ "auth:\n");
+ for (i=0; i<n; i++) {
+ if (xha[i].family == FamilyInternet) {
+ char *str = raw2host(xha[i].address,
+ xha[i].length);
+ char *ip = raw2ip(xha[i].address);
+ rfbLog(" %s/%s\n", str, ip);
+ free(str);
+ free(ip);
+ } else {
+ rfbLog(" unknown-%d\n", i+1);
+ }
+ }
+ XFree(xha);
+ 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);
+ fflush(stderr);
+ fprintf(stderr, " -- (done checking) --\n\n");
+
+ 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;
+}
+
+static int hack_val = 0;
+
+/*
+ * Huge, ugly switch to handle all remote commands and queries
+ * -remote/-R and -query/-Q.
+ */
+char *process_remote_cmd(char *cmd, int stringonly) {
+#if REMOTE_CONTROL
+ char *p = cmd;
+ char *co = "";
+ char buf[VNC_CONNECT_MAX];
+ int bufn = VNC_CONNECT_MAX;
+ int query = 0;
+ static char *prev_cursors_mode = NULL;
+
+ if (!query_default && !accept_remote_cmds) {
+ rfbLog("remote commands disabled: %s\n", cmd);
+ return NULL;
+ }
+
+ if (!query_default && priv_remote) {
+ if (! remote_control_access_ok()) {
+ rfbLog("** Disabling remote commands in -privremote "
+ "mode.\n");
+ accept_remote_cmds = 0;
+ return NULL;
+ }
+ }
+
+ strcpy(buf, "");
+ if (strstr(cmd, "cmd=") == cmd) {
+ p += strlen("cmd=");
+ } else if (strstr(cmd, "qry=") == cmd) {
+ query = 1;
+ if (strchr(cmd, ',')) {
+ /* comma separated batch mode */
+ char *s, *q, *res;
+ char tmp[512];
+ strcpy(buf, "");
+ s = strdup(cmd + strlen("qry="));
+ q = strtok(s, ",");
+ while (q) {
+ strcpy(tmp, "qry=");
+ strncat(tmp, q, 500);
+ res = process_remote_cmd(tmp, 1);
+ if (res && strlen(buf)+strlen(res)
+ >= VNC_CONNECT_MAX - 1) {
+ rfbLog("overflow in process_remote_cmd:"
+ " %s -- %s\n", buf, res);
+ free(res);
+ break;
+ }
+ if (res) {
+ strcat(buf, res);
+ free(res);
+ }
+ q = strtok(NULL, ",");
+ if (q) {
+ strcat(buf, ",");
+ }
+ }
+ free(s);
+ goto qry;
+ }
+ p += strlen("qry=");
+ } else {
+ rfbLog("ignoring malformed command: %s\n", cmd);
+ goto done;
+ }
+
+ /* allow var=val usage */
+ if (!strchr(p, ':')) {
+ char *q = strchr(p, '=');
+ if (q) *q = ':';
+ }
+
+ /* always call like: COLON_CHECK("foobar:") */
+#define COLON_CHECK(str) \
+ if (strstr(p, str) != p) { \
+ co = ":"; \
+ if (! query) { \
+ goto done; \
+ } \
+ } else { \
+ char *q = strchr(p, ':'); \
+ if (query && q != NULL) { \
+ *(q+1) = '\0'; \
+ } \
+ }
+
+#define NOTAPP \
+ if (query) { \
+ if (strchr(p, ':')) { \
+ snprintf(buf, bufn, "ans=%sN/A", p); \
+ } else { \
+ snprintf(buf, bufn, "ans=%s:N/A", p); \
+ } \
+ goto qry; \
+ }
+
+#define NOTAPPRO \
+ if (query) { \
+ if (strchr(p, ':')) { \
+ snprintf(buf, bufn, "aro=%sN/A", p); \
+ } else { \
+ snprintf(buf, bufn, "aro=%s:N/A", p); \
+ } \
+ goto qry; \
+ }
+
+/*
+ * Maybe add: passwdfile logfile bg rfbauth passwd...
+ */
+ if (!strcmp(p, "stop") || !strcmp(p, "quit") ||
+ !strcmp(p, "exit") || !strcmp(p, "shutdown")) {
+ NOTAPP
+ close_all_clients();
+ rfbLog("remote_cmd: setting shut_down flag\n");
+ shut_down = 1;
+
+ } else if (!strcmp(p, "ping")) {
+ query = 1;
+ if (rfb_desktop_name) {
+ snprintf(buf, bufn, "ans=%s:%s", p, rfb_desktop_name);
+ } else {
+ snprintf(buf, bufn, "ans=%s:%s", p, "unknown");
+ }
+ goto qry;
+
+ } else if (!strcmp(p, "blacken") || !strcmp(p, "zero")) {
+ NOTAPP
+ push_black_screen(4);
+ } else if (!strcmp(p, "refresh")) {
+ NOTAPP
+ refresh_screen(1);
+ } else if (!strcmp(p, "reset")) {
+ NOTAPP
+ do_new_fb(1);
+ } else if (strstr(p, "zero:") == p) { /* skip-cmd-list */
+ int x1, y1, x2, y2;
+ NOTAPP
+ p += strlen("zero:");
+ if (sscanf(p, "%d,%d,%d,%d", &x1, &y1, &x2, &y2) == 4) {
+ int mark = 1;
+ rfbLog("zeroing rect: %s\n", p);
+ if (x1 < 0 || x2 < 0) {
+ x1 = nabs(x1);
+ x2 = nabs(x2);
+ mark = 0; /* hack for testing */
+ }
+
+ zero_fb(x1, y1, x2, y2);
+ if (mark) {
+ mark_rect_as_modified(x1, y1, x2, y2, 0);
+ }
+ push_sleep(4);
+ }
+ } else if (strstr(p, "damagefb:") == p) { /* skip-cmd-list */
+ int delay;
+ NOTAPP
+ p += strlen("damagefb:");
+ if (sscanf(p, "%d", &delay) == 1) {
+ rfbLog("damaging client fb's for %d secs "
+ "(by not marking rects.)\n", delay);
+ damage_time = time(0);
+ damage_delay = delay;
+ }
+
+ } else if (strstr(p, "close") == p) {
+ NOTAPP
+ COLON_CHECK("close:")
+ p += strlen("close:");
+ close_clients(p);
+ } else if (strstr(p, "disconnect") == p) {
+ NOTAPP
+ COLON_CHECK("disconnect:")
+ p += strlen("disconnect:");
+ close_clients(p);
+
+ } else if (strstr(p, "id") == p) {
+ int ok = 0;
+ Window twin;
+ COLON_CHECK("id:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s0x%lx", p, co,
+ rootshift ? 0 : subwin);
+ goto qry;
+ }
+ p += strlen("id:");
+ if (*p == '\0' || !strcmp("root", p)) {
+ /* back to root win */
+ twin = 0x0;
+ ok = 1;
+ } else if (!strcmp("pick", p)) {
+ twin = 0x0;
+ if (safe_remote_only) {
+ rfbLog("unsafe: '-id pick'\n");
+ } else if (pick_windowid(&twin)) {
+ ok = 1;
+ }
+ } else if (! scan_hexdec(p, &twin)) {
+ rfbLog("-id: skipping incorrect hex/dec number:"
+ " %s\n", p);
+ } else {
+ ok = 1;
+ }
+ if (ok) {
+ if (twin && ! valid_window(twin, NULL, 0)) {
+ rfbLog("skipping invalid sub-window: 0x%lx\n",
+ twin);
+ } else {
+ subwin = twin;
+ rootshift = 0;
+ check_black_fb();
+ do_new_fb(1);
+ }
+ }
+ } else if (strstr(p, "sid") == p) {
+ int ok = 0;
+ Window twin;
+ COLON_CHECK("sid:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s0x%lx", p, co,
+ !rootshift ? 0 : subwin);
+ goto qry;
+ }
+ p += strlen("sid:");
+ if (*p == '\0' || !strcmp("root", p)) {
+ /* back to root win */
+ twin = 0x0;
+ ok = 1;
+ } else if (!strcmp("pick", p)) {
+ twin = 0x0;
+ if (safe_remote_only) {
+ rfbLog("unsafe: '-sid pick'\n");
+ } else if (pick_windowid(&twin)) {
+ ok = 1;
+ }
+ } else if (! scan_hexdec(p, &twin)) {
+ rfbLog("-sid: skipping incorrect hex/dec number: %s\n", p);
+ } else {
+ ok = 1;
+ }
+ if (ok) {
+ if (twin && ! valid_window(twin, NULL, 0)) {
+ rfbLog("skipping invalid sub-window: 0x%lx\n",
+ twin);
+ } else {
+ subwin = twin;
+ rootshift = 1;
+ check_black_fb();
+ do_new_fb(1);
+ }
+ }
+ } else if (strstr(p, "waitmapped") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ subwin_wait_mapped);
+ goto qry;
+ }
+ subwin_wait_mapped = 1;
+ } else if (strstr(p, "nowaitmapped") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !subwin_wait_mapped);
+ goto qry;
+ }
+ subwin_wait_mapped = 0;
+
+ } else if (!strcmp(p, "clip") ||
+ strstr(p, "clip:") == p) { /* skip-cmd-list */
+ COLON_CHECK("clip:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(clip_str));
+ goto qry;
+ }
+ p += strlen("clip:");
+ if (clip_str) free(clip_str);
+ clip_str = strdup(p);
+
+ /* OK, this requires a new fb... */
+ do_new_fb(1);
+
+ } else if (!strcmp(p, "flashcmap")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, flash_cmap);
+ goto qry;
+ }
+ 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("remote_cmd: turning off flashcmap mode.\n");
+ flash_cmap = 0;
+
+ } else if (strstr(p, "shiftcmap") == p) {
+ COLON_CHECK("shiftcmap:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, shift_cmap);
+ goto qry;
+ }
+ p += strlen("shiftcmap:");
+ shift_cmap = atoi(p);
+ rfbLog("remote_cmd: set -shiftcmap %d\n", shift_cmap);
+ do_new_fb(1);
+
+ } else if (!strcmp(p, "truecolor")) {
+ int orig = force_indexed_color;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !force_indexed_color);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off notruecolor mode.\n");
+ force_indexed_color = 0;
+ if (orig != force_indexed_color) {
+ if_8bpp_do_new_fb();
+ }
+ } else if (!strcmp(p, "notruecolor")) {
+ int orig = force_indexed_color;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ force_indexed_color);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on notruecolor mode.\n");
+ force_indexed_color = 1;
+ if (orig != force_indexed_color) {
+ if_8bpp_do_new_fb();
+ }
+
+ } else if (!strcmp(p, "overlay")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, overlay);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on -overlay mode.\n");
+ if (!overlay_present) {
+ rfbLog("skipping: overlay extension not present.\n");
+ } else if (overlay) {
+ rfbLog("skipping: already in -overlay mode.\n");
+ } else {
+ int reset_mem = 0;
+ /* here we go... */
+ if (using_shm) {
+ rfbLog("setting -noshm mode.\n");
+ using_shm = 0;
+ reset_mem = 1;
+ }
+ overlay = 1;
+ do_new_fb(reset_mem);
+ }
+ } else if (!strcmp(p, "nooverlay")) {
+ int orig = overlay;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !overlay);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off overlay mode\n");
+ overlay = 0;
+ if (!overlay_present) {
+ rfbLog("warning: overlay extension not present.\n");
+ } else if (!orig) {
+ rfbLog("skipping: already not in -overlay mode.\n");
+ } else {
+ /* here we go... */
+ do_new_fb(0);
+ }
+
+ } else if (!strcmp(p, "overlay_cursor") ||
+ !strcmp(p, "overlay_yescursor") ||
+ !strcmp(p, "nooverlay_nocursor")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, overlay_cursor);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on overlay_cursor mode.\n");
+ overlay_cursor = 1;
+ if (!overlay_present) {
+ rfbLog("warning: overlay extension not present.\n");
+ } else if (!overlay) {
+ rfbLog("warning: not in -overlay mode.\n");
+ } else {
+ rfbLog("You may want to run -R noshow_cursor or\n");
+ rfbLog(" -R cursor:none to disable any extra "
+ "cursors.\n");
+ }
+ } else if (!strcmp(p, "nooverlay_cursor") ||
+ !strcmp(p, "nooverlay_yescursor") ||
+ !strcmp(p, "overlay_nocursor")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !overlay_cursor);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off overlay_cursor mode\n");
+ overlay_cursor = 0;
+ if (!overlay_present) {
+ rfbLog("warning: overlay extension not present.\n");
+ } else if (!overlay) {
+ rfbLog("warning: not in -overlay mode.\n");
+ } else {
+ rfbLog("You may want to run -R show_cursor or\n");
+ rfbLog(" -R cursor:... to re-enable any cursors.\n");
+ }
+
+ } else if (strstr(p, "visual") == p) {
+ COLON_CHECK("visual:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(visual_str));
+ goto qry;
+ }
+ p += strlen("visual:");
+ if (visual_str) free(visual_str);
+ visual_str = strdup(p);
+
+ /* OK, this requires a new fb... */
+ do_new_fb(0);
+
+ } else if (!strcmp(p, "scale") ||
+ strstr(p, "scale:") == p) { /* skip-cmd-list */
+ COLON_CHECK("scale:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(scale_str));
+ goto qry;
+ }
+ p += strlen("scale:");
+ if (scale_str) free(scale_str);
+ scale_str = strdup(p);
+
+ /* OK, this requires a new fb... */
+ check_black_fb();
+ do_new_fb(0);
+
+ } else if (!strcmp(p, "scale_cursor") ||
+ strstr(p, "scale_cursor:") == p) { /* skip-cmd-list */
+ COLON_CHECK("scale_cursor:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(scale_cursor_str));
+ goto qry;
+ }
+ p += strlen("scale_cursor:");
+ if (scale_cursor_str) free(scale_cursor_str);
+ if (*p == '\0') {
+ scale_cursor_str = NULL;
+ } else {
+ scale_cursor_str = strdup(p);
+ }
+ setup_cursors_and_push();
+
+ } else if (!strcmp(p, "viewonly")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, view_only);
+ goto qry;
+ }
+ 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("remote_cmd: disable viewonly mode.\n");
+ view_only = 0;
+ if (raw_fb) set_raw_fb_params(0);
+
+ } else if (!strcmp(p, "shared")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, shared); goto qry;
+ }
+ rfbLog("remote_cmd: enable sharing.\n");
+ shared = 1;
+ if (screen) {
+ screen->alwaysShared = TRUE;
+ screen->neverShared = FALSE;
+ }
+ } else if (!strcmp(p, "noshared")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !shared); goto qry;
+ }
+ rfbLog("remote_cmd: disable sharing.\n");
+ shared = 0;
+ if (screen) {
+ screen->alwaysShared = FALSE;
+ screen->neverShared = TRUE;
+ }
+
+ } else if (!strcmp(p, "forever")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, 1-connect_once);
+ goto qry;
+ }
+ 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("remote_cmd: disable -forever mode.\n");
+ connect_once = 1;
+
+ } else if (strstr(p, "timeout") == p) {
+ int to;
+ COLON_CHECK("timeout:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ first_conn_timeout);
+ goto qry;
+ }
+ p += strlen("timeout:");
+ to = atoi(p);
+ if (to > 0 ) {
+ to = -to;
+ }
+ first_conn_timeout = to;
+ rfbLog("remote_cmd: set -timeout to %d\n", -to);
+
+#if 0
+ } else if (!strcmp(p, "filexfer")) {
+ /* does this work after rfbInitServer? */
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, filexfer);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -filexfer.\n");
+ filexfer = 1;
+ rfbRegisterTightVNCFileTransferExtension();
+#endif
+
+ } else if (!strcmp(p, "deny") || !strcmp(p, "lock")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, deny_all);
+ goto qry;
+ }
+ 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("remote_cmd: allowing new connections.\n");
+ deny_all = 0;
+
+ } else if (strstr(p, "connect") == p) {
+ NOTAPP
+ COLON_CHECK("connect:")
+ p += strlen("connect:");
+ /* this is a reverse connection */
+ reverse_connect(p);
+
+ } else if (strstr(p, "allowonce") == p) {
+ COLON_CHECK("allowonce:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(allow_once));
+ goto qry;
+ }
+ p += strlen("allowonce:");
+ allow_once = strdup(p);
+ rfbLog("remote_cmd: set allow_once %s\n", allow_once);
+
+ } else if (strstr(p, "allow") == p) {
+ char *before, *old;
+ COLON_CHECK("allow:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(allow_list));
+ goto qry;
+ }
+ p += strlen("allow:");
+ if (allow_list && strchr(allow_list, '/')) {
+ rfbLog("remote_cmd: cannot use allow:host\n");
+ rfbLog("in '-allow %s' mode.\n", allow_list);
+ goto done;
+ }
+ if (allow_list) {
+ before = strdup(allow_list);
+ } else {
+ before = strdup("");
+ }
+
+ old = allow_list;
+ if (*p == '+') {
+ p++;
+ allow_list = add_item(allow_list, p);
+ } else if (*p == '-') {
+ p++;
+ allow_list = delete_item(allow_list, p);
+ } else {
+ allow_list = strdup(p);
+ }
+
+ if (strcmp(before, allow_list)) {
+ rfbLog("remote_cmd: modified allow_list:\n");
+ rfbLog(" from: \"%s\"\n", before);
+ rfbLog(" to: \"%s\"\n", allow_list);
+ }
+ if (old) free(old);
+ free(before);
+
+ } else if (!strcmp(p, "localhost")) {
+ char *before, *old;
+ if (query) {
+ int state = 0;
+ char *s = allow_list;
+ if (s && (!strcmp(s, "127.0.0.1") ||
+ !strcmp(s, "localhost"))) {
+ state = 1;
+ }
+ snprintf(buf, bufn, "ans=%s:%d", p, state);
+ goto qry;
+ }
+ if (allow_list) {
+ before = strdup(allow_list);
+ } else {
+ before = strdup("");
+ }
+ old = allow_list;
+
+ allow_list = strdup("127.0.0.1");
+
+ if (strcmp(before, allow_list)) {
+ rfbLog("remote_cmd: modified allow_list:\n");
+ rfbLog(" from: \"%s\"\n", before);
+ rfbLog(" to: \"%s\"\n", allow_list);
+ }
+ if (old) free(old);
+ free(before);
+
+ if (listen_str) {
+ free(listen_str);
+ }
+ listen_str = strdup("localhost");
+
+ screen->listenInterface = htonl(INADDR_LOOPBACK);
+ rfbLog("listening on loopback network only.\n");
+ rfbLog("allow list is: '%s'\n", NONUL(allow_list));
+ reset_rfbport(-1, screen->port);
+ if (screen->httpListenSock > -1) {
+ reset_httpport(-1, screen->httpPort);
+ }
+ } else if (!strcmp(p, "nolocalhost")) {
+ char *before, *old;
+ if (query) {
+ int state = 0;
+ char *s = allow_list;
+ if (s && (!strcmp(s, "127.0.0.1") ||
+ !strcmp(s, "localhost"))) {
+ state = 1;
+ }
+ snprintf(buf, bufn, "ans=%s:%d", p, !state);
+ goto qry;
+ }
+ if (allow_list) {
+ before = strdup(allow_list);
+ } else {
+ before = strdup("");
+ }
+ old = allow_list;
+
+ allow_list = strdup("");
+
+ if (strcmp(before, allow_list)) {
+ rfbLog("remote_cmd: modified allow_list:\n");
+ rfbLog(" from: \"%s\"\n", before);
+ rfbLog(" to: \"%s\"\n", allow_list);
+ }
+ if (old) free(old);
+ free(before);
+
+ if (listen_str) {
+ free(listen_str);
+ }
+ listen_str = NULL;
+
+ screen->listenInterface = htonl(INADDR_ANY);
+ rfbLog("listening on ALL network interfaces.\n");
+ rfbLog("allow list is: '%s'\n", NONUL(allow_list));
+ reset_rfbport(-1, screen->port);
+ if (screen->httpListenSock > -1) {
+ reset_httpport(-1, screen->httpPort);
+ }
+
+ } else if (strstr(p, "listen") == p) {
+ char *before;
+ int ok, mod = 0;
+
+ COLON_CHECK("listen:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(listen_str));
+ goto qry;
+ }
+ if (listen_str) {
+ before = strdup(listen_str);
+ } else {
+ before = strdup("");
+ }
+ p += strlen("listen:");
+
+ listen_str = strdup(p);
+
+ if (strcmp(before, listen_str)) {
+ rfbLog("remote_cmd: modified listen_str:\n");
+ rfbLog(" from: \"%s\"\n", before);
+ rfbLog(" to: \"%s\"\n", listen_str);
+ mod = 1;
+ }
+
+ ok = 1;
+ if (listen_str == NULL || *listen_str == '\0' ||
+ !strcmp(listen_str, "any")) {
+ screen->listenInterface = htonl(INADDR_ANY);
+ } else if (!strcmp(listen_str, "localhost")) {
+ screen->listenInterface = htonl(INADDR_LOOPBACK);
+ } else {
+ struct hostent *hp;
+ in_addr_t iface = inet_addr(listen_str);
+ if (iface == htonl(INADDR_NONE)) {
+ if (!host_lookup) {
+ ok = 0;
+ } else if (!(hp = gethostbyname(listen_str))) {
+ ok = 0;
+ } else {
+ iface = *(unsigned long *)hp->h_addr;
+ }
+ }
+ if (ok) {
+ screen->listenInterface = iface;
+ }
+ }
+
+ if (ok && mod) {
+ int is_loopback = 0;
+ in_addr_t iface = screen->listenInterface;
+
+ if (allow_list) {
+ if (!strcmp(allow_list, "127.0.0.1") ||
+ !strcmp(allow_list, "localhost")) {
+ is_loopback = 1;
+ }
+ }
+ if (iface != htonl(INADDR_LOOPBACK)) {
+ if (is_loopback) {
+ rfbLog("re-setting -allow list to all "
+ "hosts for non-loopback listening.\n");
+ if (allow_list) {
+ free(allow_list);
+ }
+ allow_list = NULL;
+ }
+ } else {
+ if (!is_loopback) {
+ if (allow_list) {
+ free(allow_list);
+ }
+ rfbLog("setting -allow list to 127.0.0.1\n");
+ allow_list = strdup("127.0.0.1");
+ }
+ }
+ }
+ if (ok) {
+ rfbLog("allow list is: '%s'\n", NONUL(allow_list));
+ reset_rfbport(-1, screen->port);
+ if (screen->httpListenSock > -1) {
+ reset_httpport(-1, screen->httpPort);
+ }
+ free(before);
+ } else {
+ rfbLog("invalid listen string: %s\n", listen_str);
+ free(listen_str);
+ listen_str = before;
+ }
+ } else if (!strcmp(p, "lookup")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, host_lookup);
+ goto qry;
+ }
+ 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("remote_cmd: disabling hostname lookup.\n");
+ host_lookup = 0;
+
+ } else if (strstr(p, "accept") == p) {
+ int doit = 1;
+ COLON_CHECK("accept:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(accept_cmd));
+ goto qry;
+ }
+ p += strlen("accept:");
+ if (safe_remote_only) {
+ if (icon_mode && !strcmp(p, "")) { /* skip-cmd-list */
+ ;
+ } else if (icon_mode && !strcmp(p, "popup")) { /* skip-cmd-list */
+ ;
+ } else {
+ rfbLog("unsafe: %s\n", p);
+ doit = 0;
+ }
+ }
+
+ if (doit) {
+ if (accept_cmd) free(accept_cmd);
+ accept_cmd = strdup(p);
+ }
+
+ } else if (strstr(p, "afteraccept") == p) {
+ COLON_CHECK("afteraccept:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(afteraccept_cmd));
+ goto qry;
+ }
+ if (safe_remote_only) {
+ rfbLog("unsafe: %s\n", p);
+ } else {
+ p += strlen("afteraccept:");
+ if (afteraccept_cmd) free(afteraccept_cmd);
+ afteraccept_cmd = strdup(p);
+ }
+
+ } else if (strstr(p, "gone") == p) {
+ COLON_CHECK("gone:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(gone_cmd));
+ goto qry;
+ }
+ if (safe_remote_only) {
+ rfbLog("unsafe: %s\n", p);
+ } else {
+ p += strlen("gone:");
+ if (gone_cmd) free(gone_cmd);
+ gone_cmd = strdup(p);
+ }
+
+ } else if (!strcmp(p, "shm")) {
+ int orig = using_shm;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, using_shm);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off noshm mode.\n");
+ using_shm = 1;
+ if (raw_fb) set_raw_fb_params(0);
+
+ if (orig != using_shm) {
+ do_new_fb(1);
+ } else {
+ rfbLog(" already in shm mode.\n");
+ }
+ } else if (!strcmp(p, "noshm")) {
+ int orig = using_shm;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !using_shm);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on noshm mode.\n");
+ using_shm = 0;
+ if (orig != using_shm) {
+ do_new_fb(1);
+ } else {
+ rfbLog(" already in noshm mode.\n");
+ }
+
+ } else if (!strcmp(p, "flipbyteorder")) {
+ int orig = flip_byte_order;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, flip_byte_order);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on flipbyteorder mode.\n");
+ flip_byte_order = 1;
+ if (orig != flip_byte_order) {
+ if (! using_shm) {
+ do_new_fb(1);
+ } else {
+ rfbLog(" using shm, not resetting fb\n");
+ }
+ }
+ } else if (!strcmp(p, "noflipbyteorder")) {
+ int orig = flip_byte_order;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !flip_byte_order);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off flipbyteorder mode.\n");
+ flip_byte_order = 0;
+ if (orig != flip_byte_order) {
+ if (! using_shm) {
+ do_new_fb(1);
+ } else {
+ rfbLog(" using shm, not resetting fb\n");
+ }
+ }
+
+ } else if (!strcmp(p, "onetile")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, single_copytile);
+ goto qry;
+ }
+ 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("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);
+
+ }
+ 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:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(solid_str));
+ goto qry;
+ }
+ p += strlen("solid_color:");
+ if (*p != '\0') {
+ new = strdup(p);
+ } else {
+ new = strdup(solid_default);
+ }
+ rfbLog("remote_cmd: solid %s -> %s\n", NONUL(solid_str), new);
+
+ if (solid_str) {
+ if (!strcmp(solid_str, new)) {
+ doit = 0;
+ }
+ free(solid_str);
+ }
+ solid_str = new;
+ use_solid_bg = 1;
+ if (raw_fb) set_raw_fb_params(0);
+
+ if (doit && client_count) {
+ solid_bg(0);
+ }
+ } else if (!strcmp(p, "solid")) {
+ int orig = use_solid_bg;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_solid_bg);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enable -solid mode\n");
+ if (! solid_str) {
+ solid_str = strdup(solid_default);
+ }
+ use_solid_bg = 1;
+ if (raw_fb) set_raw_fb_params(0);
+ if (client_count && !orig) {
+ solid_bg(0);
+ }
+ } else if (!strcmp(p, "nosolid")) {
+ int orig = use_solid_bg;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_solid_bg);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disable -solid mode\n");
+ use_solid_bg = 0;
+ if (client_count && orig) {
+ solid_bg(1);
+ }
+
+ } else if (strstr(p, "blackout") == p) {
+ char *before, *old;
+ COLON_CHECK("blackout:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(blackout_str));
+ goto qry;
+ }
+ p += strlen("blackout:");
+ if (blackout_str) {
+ before = strdup(blackout_str);
+ } else {
+ before = strdup("");
+ }
+ old = blackout_str;
+ if (*p == '+') {
+ p++;
+ blackout_str = add_item(blackout_str, p);
+ } else if (*p == '-') {
+ p++;
+ blackout_str = delete_item(blackout_str, p);
+ } else {
+ blackout_str = strdup(p);
+ }
+ if (strcmp(before, blackout_str)) {
+ rfbLog("remote_cmd: changing -blackout\n");
+ rfbLog(" from: %s\n", before);
+ rfbLog(" to: %s\n", blackout_str);
+ if (0 && !strcmp(blackout_str, "") &&
+ single_copytile_orig != single_copytile) {
+ rfbLog("resetting single_copytile to: %d\n",
+ single_copytile_orig);
+ single_copytile = single_copytile_orig;
+ }
+ initialize_blackouts_and_xinerama();
+ }
+ if (old) free(old);
+ free(before);
+
+ } else if (!strcmp(p, "xinerama")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, xinerama);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enable xinerama mode. (if applicable).\n");
+ xinerama = 1;
+ initialize_blackouts_and_xinerama();
+ } else if (!strcmp(p, "noxinerama")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !xinerama);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disable xinerama mode. (if applicable).\n");
+ xinerama = 0;
+ initialize_blackouts_and_xinerama();
+
+ } else if (!strcmp(p, "xtrap")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, xtrap_input);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enable xtrap input mode."
+ "(if applicable).\n");
+ if (! xtrap_input) {
+ xtrap_input = 1;
+ disable_grabserver(dpy, 1);
+ }
+
+ } else if (!strcmp(p, "noxtrap")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !xtrap_input);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disable xtrap input mode."
+ "(if applicable).\n");
+ if (xtrap_input) {
+ xtrap_input = 0;
+ disable_grabserver(dpy, 1);
+ }
+
+ } else if (!strcmp(p, "xrandr")) {
+ int orig = xrandr;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, xrandr); goto qry;
+ }
+ if (xrandr_present) {
+ rfbLog("remote_cmd: enable xrandr mode.\n");
+ xrandr = 1;
+ if (raw_fb) set_raw_fb_params(0);
+ if (! xrandr_mode) {
+ xrandr_mode = strdup("default");
+ }
+ if (orig != xrandr) {
+ initialize_xrandr();
+ }
+ } else {
+ rfbLog("remote_cmd: XRANDR ext. not present.\n");
+ }
+ } else if (!strcmp(p, "noxrandr")) {
+ int orig = xrandr;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !xrandr); goto qry;
+ }
+ xrandr = 0;
+ if (xrandr_present) {
+ rfbLog("remote_cmd: disable xrandr mode.\n");
+ if (orig != xrandr) {
+ initialize_xrandr();
+ }
+ } else {
+ rfbLog("remote_cmd: XRANDR ext. not present.\n");
+ }
+ } else if (strstr(p, "xrandr_mode") == p) {
+ int orig = xrandr;
+ COLON_CHECK("xrandr_mode:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(xrandr_mode));
+ goto qry;
+ }
+ p += strlen("xrandr_mode:");
+ if (!strcmp("none", p)) {
+ xrandr = 0;
+ } else {
+ if (known_xrandr_mode(p)) {
+ if (xrandr_mode) free(xrandr_mode);
+ xrandr_mode = strdup(p);
+ } else {
+ rfbLog("skipping unknown xrandr mode: %s\n", p);
+ goto done;
+ }
+ xrandr = 1;
+ }
+ if (xrandr_present) {
+ if (xrandr) {
+ rfbLog("remote_cmd: enable xrandr mode.\n");
+ } else {
+ rfbLog("remote_cmd: disable xrandr mode.\n");
+ }
+ if (! xrandr_mode) {
+ xrandr_mode = strdup("default");
+ }
+ if (orig != xrandr) {
+ initialize_xrandr();
+ }
+ } else {
+ rfbLog("remote_cmd: XRANDR ext. not present.\n");
+ }
+
+ } else if (strstr(p, "padgeom") == p) {
+ COLON_CHECK("padgeom:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(pad_geometry));
+ goto qry;
+ }
+ p += strlen("padgeom:");
+ if (!strcmp("force", p) || !strcmp("do",p) || !strcmp("go",p)) {
+ 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("remote_cmd: set padgeom to: %s\n",
+ pad_geometry);
+ }
+
+ } else if (!strcmp(p, "quiet") || !strcmp(p, "q")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, quiet); goto qry;
+ }
+ 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("remote_cmd: turning off quiet mode.\n");
+ quiet = 0;
+
+ } else if (!strcmp(p, "modtweak")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_modifier_tweak);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -modtweak mode.\n");
+ if (! use_modifier_tweak) {
+ use_modifier_tweak = 1;
+ initialize_modtweak();
+ }
+ use_modifier_tweak = 1;
+
+ } else if (!strcmp(p, "nomodtweak")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !use_modifier_tweak);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -nomodtweak mode.\n");
+ got_nomodtweak = 1;
+ use_modifier_tweak = 0;
+
+ } else if (!strcmp(p, "xkb")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_xkb_modtweak);
+ goto qry;
+ }
+ if (! xkb_present) {
+ rfbLog("remote_cmd: cannot enable -xkb "
+ "modtweak mode (not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: enabling -xkb modtweak mode"
+ " (if supported).\n");
+ if (! use_modifier_tweak || ! use_xkb_modtweak) {
+ use_modifier_tweak = 1;
+ use_xkb_modtweak = 1;
+ initialize_modtweak();
+ }
+ use_modifier_tweak = 1;
+ use_xkb_modtweak = 1;
+
+ } else if (!strcmp(p, "noxkb")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_xkb_modtweak);
+ goto qry;
+ }
+ if (! xkb_present) {
+ rfbLog("remote_cmd: cannot disable -xkb "
+ "modtweak mode (not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: disabling -xkb modtweak mode.\n");
+ use_xkb_modtweak = 0;
+ got_noxkb = 1;
+ initialize_modtweak();
+
+ } else if (strstr(p, "skip_keycodes") == p) {
+ COLON_CHECK("skip_keycodes:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(skip_keycodes));
+ goto qry;
+ }
+ p += strlen("skip_keycodes:");
+ rfbLog("remote_cmd: setting xkb -skip_keycodes"
+ " to:\n\t'%s'\n", p);
+ if (! xkb_present) {
+ rfbLog("remote_cmd: warning xkb not present\n");
+ } else if (! use_xkb_modtweak) {
+ rfbLog("remote_cmd: turning on xkb.\n");
+ use_xkb_modtweak = 1;
+ if (! use_modifier_tweak) {
+ rfbLog("remote_cmd: turning on modtweak.\n");
+ use_modifier_tweak = 1;
+ }
+ }
+ if (skip_keycodes) free(skip_keycodes);
+ skip_keycodes = strdup(p);
+ initialize_modtweak();
+
+ } else if (!strcmp(p, "sloppy_keys")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, sloppy_keys);
+ goto qry;
+ }
+ sloppy_keys += 1;
+ rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys);
+ } else if (!strcmp(p, "nosloppy_keys")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !sloppy_keys);
+ goto qry;
+ }
+ sloppy_keys = 0;
+ rfbLog("remote_cmd: set sloppy_keys to: %d\n", sloppy_keys);
+
+ } else if (!strcmp(p, "skip_dups")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ skip_duplicate_key_events);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -skip_dups mode\n");
+ skip_duplicate_key_events = 1;
+ } else if (!strcmp(p, "noskip_dups")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !skip_duplicate_key_events);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -skip_dups mode\n");
+ skip_duplicate_key_events = 0;
+
+ } else if (!strcmp(p, "add_keysyms")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, add_keysyms);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -add_keysyms mode.\n");
+ add_keysyms = 1;
+
+ } else if (!strcmp(p, "noadd_keysyms")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !add_keysyms);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -add_keysyms mode.\n");
+ add_keysyms = 0;
+
+ } else if (!strcmp(p, "clear_mods")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, clear_mods == 1);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -clear_mods mode.\n");
+ clear_mods = 1;
+ clear_modifiers(0);
+
+ } else if (!strcmp(p, "noclear_mods")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !(clear_mods == 1));
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -clear_mods mode.\n");
+ clear_mods = 0;
+
+ } else if (!strcmp(p, "clear_keys")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ clear_mods == 2);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -clear_keys mode.\n");
+ clear_mods = 2;
+ clear_keys();
+
+ } else if (!strcmp(p, "noclear_keys")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !(clear_mods == 2));
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling -clear_keys mode.\n");
+ clear_mods = 0;
+
+ } else if (strstr(p, "remap") == p) {
+ char *before, *old;
+ COLON_CHECK("remap:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(remap_file));
+ goto qry;
+ }
+ p += strlen("remap:");
+ if ((*p == '+' || *p == '-') && remap_file &&
+ strchr(remap_file, '/')) {
+ rfbLog("remote_cmd: cannot use remap:+/-\n");
+ rfbLog("in '-remap %s' mode.\n", remap_file);
+ goto done;
+ }
+ if (remap_file) {
+ before = strdup(remap_file);
+ } else {
+ before = strdup("");
+ }
+ old = remap_file;
+ if (*p == '+') {
+ p++;
+ remap_file = add_item(remap_file, p);
+ } else if (*p == '-') {
+ p++;
+ remap_file = delete_item(remap_file, p);
+ if (! strchr(remap_file, '-')) {
+ *remap_file = '\0';
+ }
+ } else {
+ remap_file = strdup(p);
+ }
+ if (strcmp(before, remap_file)) {
+ rfbLog("remote_cmd: changed -remap\n");
+ rfbLog(" from: %s\n", before);
+ rfbLog(" to: %s\n", remap_file);
+ initialize_remap(remap_file);
+ }
+ if (old) free(old);
+ free(before);
+
+ } else if (!strcmp(p, "repeat")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !no_autorepeat);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -repeat mode.\n");
+ autorepeat(1, 0); /* restore initial setting */
+ no_autorepeat = 0;
+
+ } else if (!strcmp(p, "norepeat")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, no_autorepeat);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling -norepeat mode.\n");
+ no_autorepeat = 1;
+ if (no_repeat_countdown >= 0) {
+ no_repeat_countdown = 2;
+ }
+ if (client_count && ! view_only) {
+ autorepeat(0, 0); /* disable if any clients */
+ }
+
+ } else if (!strcmp(p, "fb")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !nofb);
+ goto qry;
+ }
+ if (nofb) {
+ 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");
+ rfbLog(" cursorpos, cursorshape, bell.\n");
+ nofb = 0;
+ set_nofb_params(1);
+ do_new_fb(1);
+ }
+ } else if (!strcmp(p, "nofb")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, nofb);
+ goto qry;
+ }
+ if (!nofb) {
+ rfbLog("remote_cmd: enabling nofb mode.\n");
+ if (main_fb) {
+ push_black_screen(4);
+ }
+ nofb = 1;
+ sound_bell = 0;
+ initialize_watch_bell();
+ set_nofb_params(0);
+ do_new_fb(1);
+ }
+
+ } else if (!strcmp(p, "bell")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, sound_bell);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling bell (if supported).\n");
+ initialize_watch_bell();
+ sound_bell = 1;
+
+ } else if (!strcmp(p, "nobell")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !sound_bell);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling bell.\n");
+ initialize_watch_bell();
+ sound_bell = 0;
+
+ } else if (!strcmp(p, "sel")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, watch_selection);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling watch selection+primary.\n");
+ watch_selection = 1;
+ watch_primary = 1;
+
+ } else if (!strcmp(p, "nosel")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !watch_selection);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling watch selection+primary.\n");
+ watch_selection = 0;
+ watch_primary = 0;
+
+ } else if (!strcmp(p, "primary")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, watch_primary);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling watch_primary.\n");
+ watch_primary = 1;
+
+ } else if (!strcmp(p, "noprimary")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !watch_primary);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling watch_primary.\n");
+ watch_primary = 0;
+
+ } else if (strstr(p, "seldir") == p) {
+ COLON_CHECK("seldir:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(sel_direction));
+ goto qry;
+ }
+ p += strlen("seldir:");
+ rfbLog("remote_cmd: setting -seldir to %s\n", p);
+ if (sel_direction) free(sel_direction);
+ sel_direction = strdup(p);
+
+ } else if (!strcmp(p, "set_no_cursor")) { /* skip-cmd-list */
+ rfbLog("remote_cmd: calling set_no_cursor()\n");
+ set_no_cursor();
+
+ } else if (!strcmp(p, "cursorshape")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ cursor_shape_updates);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on cursorshape mode.\n");
+
+ set_no_cursor();
+ cursor_shape_updates = 1;
+ restore_cursor_shape_updates(screen);
+ first_cursor();
+ } else if (!strcmp(p, "nocursorshape")) {
+ int i, max = 5;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !cursor_shape_updates);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off cursorshape mode.\n");
+
+ set_no_cursor();
+ for (i=0; i<max; i++) {
+ /* XXX: try to force empty cursor back to client */
+ rfbPE(-1);
+ }
+ cursor_shape_updates = 0;
+ disable_cursor_shape_updates(screen);
+ first_cursor();
+
+ } else if (!strcmp(p, "cursorpos")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ cursor_pos_updates);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on cursorpos mode.\n");
+ cursor_pos_updates = 1;
+ } else if (!strcmp(p, "nocursorpos")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !cursor_pos_updates);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off cursorpos mode.\n");
+ cursor_pos_updates = 0;
+
+ } else if (strstr(p, "cursor") == p) {
+ COLON_CHECK("cursor:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(multiple_cursors_mode));
+ goto qry;
+ }
+ p += strlen("cursor:");
+ if (multiple_cursors_mode) {
+ if (prev_cursors_mode) free(prev_cursors_mode);
+ prev_cursors_mode = strdup(multiple_cursors_mode);
+ free(multiple_cursors_mode);
+ }
+ multiple_cursors_mode = strdup(p);
+
+ rfbLog("remote_cmd: changed -cursor mode "
+ "to: %s\n", multiple_cursors_mode);
+
+ if (strcmp(multiple_cursors_mode, "none") && !show_cursor) {
+ show_cursor = 1;
+ rfbLog("remote_cmd: changed show_cursor "
+ "to: %d\n", show_cursor);
+ }
+ initialize_cursors_mode();
+ first_cursor();
+
+ } else if (!strcmp(p, "show_cursor")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, show_cursor);
+ goto qry;
+ }
+ rfbLog("remote_cmd: enabling show_cursor.\n");
+ show_cursor = 1;
+ if (multiple_cursors_mode && !strcmp(multiple_cursors_mode,
+ "none")) {
+ free(multiple_cursors_mode);
+ if (prev_cursors_mode) {
+ multiple_cursors_mode =
+ strdup(prev_cursors_mode);
+ } else {
+ multiple_cursors_mode = strdup("default");
+ }
+ rfbLog("remote_cmd: changed -cursor mode "
+ "to: %s\n", multiple_cursors_mode);
+ }
+ initialize_cursors_mode();
+ first_cursor();
+ } else if (!strcmp(p, "noshow_cursor") || !strcmp(p, "nocursor")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !show_cursor);
+ goto qry;
+ }
+ if (prev_cursors_mode) free(prev_cursors_mode);
+ prev_cursors_mode = strdup(multiple_cursors_mode);
+
+ rfbLog("remote_cmd: disabling show_cursor.\n");
+ show_cursor = 0;
+ initialize_cursors_mode();
+ first_cursor();
+
+ } else if (strstr(p, "arrow") == p) {
+ COLON_CHECK("arrow:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, alt_arrow);
+ goto qry;
+ }
+ p += strlen("arrow:");
+ alt_arrow = atoi(p);
+ rfbLog("remote_cmd: setting alt_arrow: %d.\n", alt_arrow);
+ setup_cursors_and_push();
+
+ } else if (!strcmp(p, "xfixes")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_xfixes);
+ goto qry;
+ }
+ if (! xfixes_present) {
+ rfbLog("remote_cmd: cannot enable xfixes "
+ "(not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: enabling -xfixes"
+ " (if supported).\n");
+ use_xfixes = 1;
+ initialize_xfixes();
+ first_cursor();
+ } else if (!strcmp(p, "noxfixes")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_xfixes);
+ goto qry;
+ }
+ if (! xfixes_present) {
+ rfbLog("remote_cmd: disabling xfixes "
+ "(but not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: disabling -xfixes.\n");
+ use_xfixes = 0;
+ initialize_xfixes();
+ first_cursor();
+
+ } else if (!strcmp(p, "xdamage")) {
+ int orig = use_xdamage;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_xdamage);
+ goto qry;
+ }
+ if (! xdamage_present) {
+ rfbLog("remote_cmd: cannot enable xdamage hints "
+ "(not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: enabling xdamage hints"
+ " (if supported).\n");
+ use_xdamage = 1;
+ if (use_xdamage != orig) {
+ initialize_xdamage();
+ create_xdamage_if_needed();
+ }
+ } else if (!strcmp(p, "noxdamage")) {
+ int orig = use_xdamage;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_xdamage);
+ goto qry;
+ }
+ if (! xdamage_present) {
+ rfbLog("remote_cmd: disabling xdamage hints "
+ "(but not supported on X display)\n");
+ goto done;
+ }
+ rfbLog("remote_cmd: disabling xdamage hints.\n");
+ use_xdamage = 0;
+ if (use_xdamage != orig) {
+ initialize_xdamage();
+ destroy_xdamage_if_needed();
+ }
+
+ } else if (strstr(p, "xd_area") == p) {
+ int a;
+ COLON_CHECK("xd_area:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ xdamage_max_area);
+ goto qry;
+ }
+ p += strlen("xd_area:");
+ a = atoi(p);
+ if (a >= 0) {
+ rfbLog("remote_cmd: setting xdamage_max_area "
+ "%d -> %d.\n", xdamage_max_area, a);
+ xdamage_max_area = a;
+ }
+ } else if (strstr(p, "xd_mem") == p) {
+ double a;
+ COLON_CHECK("xd_mem:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%.3f", p, co,
+ xdamage_memory);
+ goto qry;
+ }
+ p += strlen("xd_mem:");
+ a = atof(p);
+ if (a >= 0.0) {
+ rfbLog("remote_cmd: setting xdamage_memory "
+ "%.3f -> %.3f.\n", xdamage_memory, a);
+ xdamage_memory = a;
+ }
+
+ } else if (strstr(p, "alphacut") == p) {
+ int a;
+ COLON_CHECK("alphacut:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ alpha_threshold);
+ goto qry;
+ }
+ p += strlen("alphacut:");
+ a = atoi(p);
+ if (a < 0) a = 0;
+ if (a > 256) a = 256; /* allow 256 for testing. */
+ if (alpha_threshold != a) {
+ rfbLog("remote_cmd: setting alphacut "
+ "%d -> %d.\n", alpha_threshold, a);
+ if (a == 256) {
+ rfbLog("note: alphacut=256 leads to completely"
+ " transparent cursors.\n");
+ }
+ alpha_threshold = a;
+ setup_cursors_and_push();
+ }
+ } else if (strstr(p, "alphafrac") == p) {
+ double a;
+ COLON_CHECK("alphafrac:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%f", p, co,
+ alpha_frac);
+ goto qry;
+ }
+ p += strlen("alphafrac:");
+ a = atof(p);
+ if (a < 0.0) a = 0.0;
+ if (a > 1.0) a = 1.0;
+ if (alpha_frac != a) {
+ rfbLog("remote_cmd: setting alphafrac "
+ "%f -> %f.\n", alpha_frac, a);
+ alpha_frac = a;
+ setup_cursors_and_push();
+ }
+ } else if (strstr(p, "alpharemove") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, alpha_remove);
+ goto qry;
+ }
+ if (!alpha_remove) {
+ rfbLog("remote_cmd: enable alpharemove\n");
+ alpha_remove = 1;
+ setup_cursors_and_push();
+ }
+ } else if (strstr(p, "noalpharemove") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !alpha_remove);
+ goto qry;
+ }
+ if (alpha_remove) {
+ rfbLog("remote_cmd: disable alpharemove\n");
+ alpha_remove = 0;
+ setup_cursors_and_push();
+ }
+ } else if (strstr(p, "alphablend") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, alpha_blend);
+ goto qry;
+ }
+ if (!alpha_blend) {
+ rfbLog("remote_cmd: enable alphablend\n");
+ alpha_remove = 0;
+ alpha_blend = 1;
+ setup_cursors_and_push();
+ }
+ } else if (strstr(p, "noalphablend") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !alpha_blend);
+ goto qry;
+ }
+ if (alpha_blend) {
+ rfbLog("remote_cmd: disable alphablend\n");
+ alpha_blend = 0;
+ setup_cursors_and_push();
+ }
+
+ } else if (strstr(p, "xwarppointer") == p || strstr(p, "xwarp") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_xwarppointer);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on xwarppointer mode.\n");
+ use_xwarppointer = 1;
+ } else if (strstr(p, "noxwarppointer") == p ||
+ strstr(p, "noxwarp") == p) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_xwarppointer);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off xwarppointer mode.\n");
+ use_xwarppointer = 0;
+
+ } else if (strstr(p, "buttonmap") == p) {
+ COLON_CHECK("buttonmap:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(pointer_remap));
+ goto qry;
+ }
+ p += strlen("buttonmap:");
+ if (pointer_remap) free(pointer_remap);
+ pointer_remap = strdup(p);
+
+ rfbLog("remote_cmd: setting -buttonmap to:\n\t'%s'\n", p);
+ initialize_pointer_map(p);
+
+ } else if (!strcmp(p, "dragging")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, show_dragging);
+ goto qry;
+ }
+ 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("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 (strstr(p, "wf:") == p) { /* skip-cmd-list */
+ COLON_CHECK("wf:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, wireframe);
+ goto qry;
+ }
+ p += strlen("wf:");
+ 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") || !strcmp(p, "wf")) {
+ 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") || !strcmp(p, "nowf")) {
+ 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));
+ got_wirecopyrect = 1;
+ } else if (strstr(p, "wcr") == p) {
+ COLON_CHECK("wcr:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(wireframe_copyrect));
+ goto qry;
+ }
+ p += strlen("wcr:");
+
+ set_wirecopyrect_mode(p);
+ rfbLog("remote_cmd: changed -wirecopyrect mode "
+ "to: %s\n", NONUL(wireframe_copyrect));
+ got_wirecopyrect = 1;
+ } else if (!strcmp(p, "nowirecopyrect") || !strcmp(p, "nowcr")) {
+ 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, "scr_area") == p) {
+ COLON_CHECK("scr_area:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ scrollcopyrect_min_area);
+ goto qry;
+ }
+ p += strlen("scr_area:");
+
+ scrollcopyrect_min_area = atoi(p);
+ rfbLog("remote_cmd: changed -scr_area to: %d\n",
+ scrollcopyrect_min_area);
+
+ } else if (strstr(p, "scr_skip") == p) {
+ char *s = scroll_skip_str;
+ COLON_CHECK("scr_skip:")
+ if (!s || *s == '\0') s = scroll_skip_str0;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
+ goto qry;
+ }
+ p += strlen("scr_skip:");
+ if (scroll_skip_str) {
+ free(scroll_skip_str);
+ }
+
+ scroll_skip_str = strdup(p);
+ rfbLog("remote_cmd: changed -scr_skip to: %s\n",
+ scroll_skip_str);
+ initialize_scroll_matches();
+ } else if (strstr(p, "scr_inc") == p) {
+ char *s = scroll_good_str;
+ if (!s || *s == '\0') s = scroll_good_str0;
+ COLON_CHECK("scr_inc:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
+ goto qry;
+ }
+ p += strlen("scr_inc:");
+ if (scroll_good_str) {
+ free(scroll_good_str);
+ }
+
+ scroll_good_str = strdup(p);
+ rfbLog("remote_cmd: changed -scr_inc to: %s\n",
+ scroll_good_str);
+ initialize_scroll_matches();
+ } else if (strstr(p, "scr_keys") == p) {
+ COLON_CHECK("scr_keys:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(scroll_key_list_str));
+ goto qry;
+ }
+ p += strlen("scr_keys:");
+ if (scroll_key_list_str) {
+ free(scroll_key_list_str);
+ }
+
+ scroll_key_list_str = strdup(p);
+ rfbLog("remote_cmd: changed -scr_keys to: %s\n",
+ scroll_key_list_str);
+ initialize_scroll_keys();
+ } else if (strstr(p, "scr_term") == p) {
+ char *s = scroll_term_str;
+ if (!s || *s == '\0') s = scroll_term_str0;
+ COLON_CHECK("scr_term:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
+ goto qry;
+ }
+ p += strlen("scr_term:");
+ if (scroll_term_str) {
+ free(scroll_term_str);
+ }
+
+ scroll_term_str = strdup(p);
+ rfbLog("remote_cmd: changed -scr_term to: %s\n",
+ scroll_term_str);
+ initialize_scroll_term();
+
+ } else if (strstr(p, "scr_keyrepeat") == p) {
+ char *s = max_keyrepeat_str;
+ if (!s || *s == '\0') s = max_keyrepeat_str0;
+ COLON_CHECK("scr_keyrepeat:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co, NONUL(s));
+ goto qry;
+ }
+ p += strlen("scr_keyrepeat:");
+ if (max_keyrepeat_str) {
+ free(max_keyrepeat_str);
+ }
+
+ max_keyrepeat_str = strdup(p);
+ rfbLog("remote_cmd: changed -scr_keyrepeat to: %s\n",
+ max_keyrepeat_str);
+ initialize_max_keyrepeat();
+
+ } else if (strstr(p, "scr_parms") == p) {
+ COLON_CHECK("scr_parms:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ scroll_copyrect_str ? scroll_copyrect_str
+ : SCROLL_COPYRECT_PARMS);
+ goto qry;
+ }
+ p += strlen("scr_parms:");
+ if (*p) {
+ if (scroll_copyrect_str) {
+ free(scroll_copyrect_str);
+ }
+ set_scrollcopyrect_mode("always");
+ scroll_copyrect_str = strdup(p);
+ parse_scroll_copyrect();
+ }
+ rfbLog("remote_cmd: set -scr_parms %s.\n",
+ NONUL(scroll_copyrect_str));
+ got_scrollcopyrect = 1;
+
+ } else if (strstr(p, "scrollcopyrect") == p) {
+ COLON_CHECK("scrollcopyrect:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(scroll_copyrect));
+ goto qry;
+ }
+ p += strlen("scrollcopyrect:");
+
+ set_scrollcopyrect_mode(p);
+ rfbLog("remote_cmd: changed -scrollcopyrect mode "
+ "to: %s\n", NONUL(scroll_copyrect));
+ got_scrollcopyrect = 1;
+ } else if (!strcmp(p, "scr") ||
+ strstr(p, "scr:") == p) { /* skip-cmd-list */
+ COLON_CHECK("scr:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(scroll_copyrect));
+ goto qry;
+ }
+ p += strlen("scr:");
+
+ set_scrollcopyrect_mode(p);
+ rfbLog("remote_cmd: changed -scrollcopyrect mode "
+ "to: %s\n", NONUL(scroll_copyrect));
+ got_scrollcopyrect = 1;
+ } else if (!strcmp(p, "noscrollcopyrect") || !strcmp(p, "noscr")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%s", p,
+ NONUL(scroll_copyrect));
+ goto qry;
+ }
+
+ set_scrollcopyrect_mode("never");
+ rfbLog("remote_cmd: changed -scrollcopyrect mode "
+ "to: %s\n", NONUL(scroll_copyrect));
+
+ } else if (strstr(p, "fixscreen") == p) {
+ COLON_CHECK("fixscreen:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(screen_fixup_str));
+ goto qry;
+ }
+ p += strlen("fixscreen:");
+ if (screen_fixup_str) {
+ free(screen_fixup_str);
+ }
+ screen_fixup_str = strdup(p);
+ parse_fixscreen();
+ rfbLog("remote_cmd: set -fixscreen %s.\n",
+ NONUL(screen_fixup_str));
+
+ } else if (!strcmp(p, "noxrecord")) {
+ int orig = noxrecord;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, noxrecord);
+ goto qry;
+ }
+ noxrecord = 1;
+ rfbLog("set noxrecord to: %d\n", noxrecord);
+ if (orig != noxrecord) {
+ shutdown_xrecord();
+ }
+ } else if (!strcmp(p, "xrecord")) {
+ int orig = noxrecord;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !noxrecord);
+ goto qry;
+ }
+ noxrecord = 0;
+ rfbLog("set noxrecord to: %d\n", noxrecord);
+ if (orig != noxrecord) {
+ initialize_xrecord();
+ }
+ } else if (!strcmp(p, "reset_record")) {
+ NOTAPP
+ if (use_xrecord) {
+ rfbLog("resetting RECORD\n");
+ check_xrecord_reset(1);
+ } else {
+ rfbLog("RECORD is disabled, not resetting.\n");
+ }
+
+ } else if (strstr(p, "pointer_mode") == p) {
+ int pm;
+ COLON_CHECK("pointer_mode:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode);
+ goto qry;
+ }
+ p += strlen("pointer_mode:");
+ pm = atoi(p);
+ if (pm < 0 || pm > pointer_mode_max) {
+ rfbLog("remote_cmd: pointer_mode out of range:"
+ " 1-%d: %d\n", pointer_mode_max, pm);
+ } else {
+ rfbLog("remote_cmd: setting pointer_mode %d\n", pm);
+ pointer_mode = pm;
+ }
+ } else if (strstr(p, "pm") == p) {
+ int pm;
+ COLON_CHECK("pm:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, pointer_mode);
+ goto qry;
+ }
+ p += strlen("pm:");
+ pm = atoi(p);
+ if (pm < 0 || pm > pointer_mode_max) {
+ rfbLog("remote_cmd: pointer_mode out of range:"
+ " 1-%d: %d\n", pointer_mode_max, pm);
+ } else {
+ rfbLog("remote_cmd: setting pointer_mode %d\n", pm);
+ pointer_mode = pm;
+ }
+
+ } else if (strstr(p, "input_skip") == p) {
+ int is;
+ COLON_CHECK("input_skip:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, ui_skip);
+ goto qry;
+ }
+ p += strlen("input_skip:");
+ is = atoi(p);
+ rfbLog("remote_cmd: setting input_skip %d\n", is);
+ ui_skip = is;
+
+ } else if (strstr(p, "input") == p) {
+ int doit = 1;
+ COLON_CHECK("input:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(allowed_input_str));
+ goto qry;
+ }
+ p += strlen("input:");
+ if (allowed_input_str && !strcmp(p, allowed_input_str)) {
+ doit = 0;
+ }
+ rfbLog("remote_cmd: setting input %s\n", p);
+ if (allowed_input_str) free(allowed_input_str);
+ if (*p == '\0') {
+ allowed_input_str = NULL;
+ } else {
+ allowed_input_str = strdup(p);
+ }
+ if (doit) {
+ initialize_allowed_input();
+ }
+ } else if (strstr(p, "client_input") == p) {
+ NOTAPP
+ COLON_CHECK("client_input:")
+ p += strlen("client_input:");
+ set_client_input(p);
+
+ } else if (strstr(p, "speeds") == p) {
+ COLON_CHECK("speeds:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(speeds_str));
+ goto qry;
+ }
+ p += strlen("speeds:");
+ if (speeds_str) free(speeds_str);
+ speeds_str = strdup(p);
+
+ rfbLog("remote_cmd: setting -speeds to:\n\t'%s'\n", p);
+ initialize_speeds();
+
+ } else if (strstr(p, "wmdt") == p) {
+ COLON_CHECK("wmdt:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(wmdt_str));
+ goto qry;
+ }
+ p += strlen("wmdt:");
+ if (wmdt_str) free(wmdt_str);
+ wmdt_str = strdup(p);
+
+ rfbLog("remote_cmd: setting -wmdt to: %s\n", p);
+
+ } else if (!strcmp(p, "debug_pointer") || !strcmp(p, "dp")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_pointer);
+ goto qry;
+ }
+ 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("remote_cmd: turning off debug_pointer.\n");
+ debug_pointer = 0;
+
+ } else if (!strcmp(p, "debug_keyboard") || !strcmp(p, "dk")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_keyboard);
+ goto qry;
+ }
+ 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("remote_cmd: turning off debug_keyboard.\n");
+ debug_keyboard = 0;
+
+ } else if (strstr(p, "deferupdate") == p) {
+ int d;
+ COLON_CHECK("deferupdate:")
+ if (query) {
+ if (!screen) {
+ d = defer_update;
+ } else {
+ d = screen->deferUpdateTime;
+ }
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, d);
+ goto qry;
+ }
+ p += strlen("deferupdate:");
+ d = atoi(p);
+ if (d < 0) d = 0;
+ rfbLog("remote_cmd: setting defer to %d ms.\n", d);
+ screen->deferUpdateTime = d;
+ got_defer = 1;
+
+ } else if (strstr(p, "defer") == p) {
+ int d;
+ COLON_CHECK("defer:")
+ if (query) {
+ if (!screen) {
+ d = defer_update;
+ } else {
+ d = screen->deferUpdateTime;
+ }
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, d);
+ goto qry;
+ }
+ p += strlen("defer:");
+ d = atoi(p);
+ if (d < 0) d = 0;
+ rfbLog("remote_cmd: setting defer to %d ms.\n", d);
+ screen->deferUpdateTime = d;
+ got_defer = 1;
+
+ } else if (strstr(p, "wait_ui") == p) {
+ double w;
+ COLON_CHECK("wait_ui:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%.2f", p, co, wait_ui);
+ goto qry;
+ }
+ p += strlen("wait_ui:");
+ w = atof(p);
+ if (w <= 0) w = 1.0;
+ rfbLog("remote_cmd: setting wait_ui factor %.2f -> %.2f\n",
+ wait_ui, w);
+ wait_ui = w;
+
+ } else if (!strcmp(p, "wait_bog")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, wait_bog);
+ goto qry;
+ }
+ wait_bog = 1;
+ rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
+ } else if (!strcmp(p, "nowait_bog")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !wait_bog);
+ goto qry;
+ }
+ wait_bog = 0;
+ rfbLog("remote_cmd: setting wait_bog to %d\n", wait_bog);
+
+ } else if (strstr(p, "slow_fb") == p) {
+ double w;
+ COLON_CHECK("slow_fb:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%.2f", p, co, slow_fb);
+ goto qry;
+ }
+ p += strlen("slow_fb:");
+ w = atof(p);
+ if (w <= 0) w = 0.0;
+ rfbLog("remote_cmd: setting slow_fb factor %.2f -> %.2f\n",
+ slow_fb, w);
+ slow_fb = w;
+
+ } else if (strstr(p, "wait") == p) {
+ int w;
+ COLON_CHECK("wait:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, waitms);
+ goto qry;
+ }
+ p += strlen("wait:");
+ w = atoi(p);
+ if (w < 0) w = 0;
+ rfbLog("remote_cmd: setting wait %d -> %d ms.\n", waitms, w);
+ waitms = w;
+
+ } else if (strstr(p, "readtimeout") == p) {
+ int w, orig = rfbMaxClientWait;
+ COLON_CHECK("readtimeout:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ rfbMaxClientWait/1000);
+ goto qry;
+ }
+ p += strlen("readtimeout:");
+ w = atoi(p) * 1000;
+ if (w <= 0) w = 0;
+ rfbLog("remote_cmd: setting rfbMaxClientWait %d -> "
+ "%d msec.\n", orig, w);
+ rfbMaxClientWait = w;
+
+ } else if (!strcmp(p, "nap")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, take_naps);
+ goto qry;
+ }
+ 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("remote_cmd: turning off nap mode.\n");
+ take_naps = 0;
+
+ } else if (strstr(p, "sb") == p) {
+ int w;
+ COLON_CHECK("sb:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
+ goto qry;
+ }
+ p += strlen("sb:");
+ w = atoi(p);
+ if (w < 0) w = 0;
+ 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;
+ COLON_CHECK("screen_blank:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, screen_blank);
+ goto qry;
+ }
+ p += strlen("screen_blank:");
+ w = atoi(p);
+ if (w < 0) w = 0;
+ rfbLog("remote_cmd: setting screen_blank %d -> %d sec.\n",
+ screen_blank, w);
+ screen_blank = w;
+
+ } else if (strstr(p, "fs") == p) {
+ COLON_CHECK("fs:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%f", p, co, fs_frac);
+ goto qry;
+ }
+ p += strlen("fs:");
+ fs_frac = atof(p);
+ rfbLog("remote_cmd: setting -fs frac to %f\n", fs_frac);
+
+ } else if (strstr(p, "gaps") == p) {
+ int g;
+ COLON_CHECK("gaps:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, gaps_fill);
+ goto qry;
+ }
+ p += strlen("gaps:");
+ g = atoi(p);
+ if (g < 0) g = 0;
+ rfbLog("remote_cmd: setting gaps_fill %d -> %d.\n",
+ gaps_fill, g);
+ gaps_fill = g;
+ } else if (strstr(p, "grow") == p) {
+ int g;
+ COLON_CHECK("grow:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, grow_fill);
+ goto qry;
+ }
+ p += strlen("grow:");
+ g = atoi(p);
+ if (g < 0) g = 0;
+ rfbLog("remote_cmd: setting grow_fill %d -> %d.\n",
+ grow_fill, g);
+ grow_fill = g;
+ } else if (strstr(p, "fuzz") == p) {
+ int f;
+ COLON_CHECK("fuzz:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, tile_fuzz);
+ goto qry;
+ }
+ p += strlen("fuzz:");
+ f = atoi(p);
+ if (f < 0) f = 0;
+ rfbLog("remote_cmd: setting tile_fuzz %d -> %d.\n",
+ tile_fuzz, f);
+ grow_fill = f;
+
+ } else if (!strcmp(p, "snapfb")) {
+ int orig = use_snapfb;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, use_snapfb);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning on snapfb mode.\n");
+ use_snapfb = 1;
+ if (orig != use_snapfb) {
+ do_new_fb(1);
+ }
+ } else if (!strcmp(p, "nosnapfb")) {
+ int orig = use_snapfb;
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !use_snapfb);
+ goto qry;
+ }
+ rfbLog("remote_cmd: turning off snapfb mode.\n");
+ use_snapfb = 0;
+ if (orig != use_snapfb) {
+ do_new_fb(1);
+ }
+
+ } else if (strstr(p, "rawfb") == p) {
+ COLON_CHECK("rawfb:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(raw_fb_str));
+ goto qry;
+ }
+ p += strlen("rawfb:");
+ if (raw_fb_str) free(raw_fb_str);
+ raw_fb_str = strdup(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("remote_cmd: setting -rawfb to:\n\t'%s'\n", p);
+
+ if (*raw_fb_str == '\0') {
+ free(raw_fb_str);
+ raw_fb_str = NULL;
+ rfbLog("restoring per-rawfb settings...\n");
+ set_raw_fb_params(1);
+ }
+ rfbLog("hang on tight, here we go...\n");
+ do_new_fb(1);
+
+ } else if (strstr(p, "progressive") == p) {
+ int f;
+ COLON_CHECK("progressive:")
+ if (query) {
+ if (!screen) {
+ f = 0;
+ } else {
+ f = screen->progressiveSliceHeight;
+ }
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, f);
+ goto qry;
+ }
+ p += strlen("progressive:");
+ f = atoi(p);
+ if (f < 0) f = 0;
+ rfbLog("remote_cmd: setting progressive %d -> %d.\n",
+ screen->progressiveSliceHeight, f);
+ screen->progressiveSliceHeight = f;
+
+ } else if (strstr(p, "rfbport") == p) {
+ int rp, orig = screen ? screen->port : 5900;
+ COLON_CHECK("rfbport:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, orig);
+ goto qry;
+ }
+ p += strlen("rfbport:");
+ rp = atoi(p);
+ reset_rfbport(orig, rp);
+
+ } else if (!strcmp(p, "http")) {
+ if (query) {
+ int ls = screen ? screen->httpListenSock : -1;
+ snprintf(buf, bufn, "ans=%s:%d", p, (ls > -1));
+ goto qry;
+ }
+ if (screen->httpListenSock > -1) {
+ rfbLog("already listening for http connections.\n");
+ } else {
+ rfbLog("turning on listening for http connections.\n");
+ if (check_httpdir()) {
+ http_connections(1);
+ }
+ }
+ } else if (!strcmp(p, "nohttp")) {
+ if (query) {
+ int ls = screen ? screen->httpListenSock : -1;
+ snprintf(buf, bufn, "ans=%s:%d", p, !(ls > -1));
+ goto qry;
+ }
+ if (screen->httpListenSock < 0) {
+ rfbLog("already not listening for http connections.\n");
+ } else {
+ rfbLog("turning off listening for http connections.\n");
+ if (check_httpdir()) {
+ http_connections(0);
+ }
+ }
+
+ } else if (strstr(p, "httpport") == p) {
+ int hp, orig = screen ? screen->httpPort : 0;
+ COLON_CHECK("httpport:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, orig);
+ goto qry;
+ }
+ p += strlen("httpport:");
+ hp = atoi(p);
+ reset_httpport(orig, hp);
+
+ } else if (strstr(p, "httpdir") == p) {
+ COLON_CHECK("httpdir:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(http_dir));
+ goto qry;
+ }
+ p += strlen("httpdir:");
+ if (http_dir && !strcmp(http_dir, p)) {
+ rfbLog("no change in httpdir: %s\n", http_dir);
+ } else {
+ if (http_dir) {
+ free(http_dir);
+ }
+ http_dir = strdup(p);
+ http_connections(0);
+ if (*p != '\0') {
+ http_connections(1);
+ }
+ }
+
+ } else if (!strcmp(p, "enablehttpproxy")) {
+ if (query) {
+ int ht = screen ? screen->httpEnableProxyConnect : 0;
+ snprintf(buf, bufn, "ans=%s:%d", p, ht != 0);
+ goto qry;
+ }
+ rfbLog("turning on enablehttpproxy.\n");
+ screen->httpEnableProxyConnect = 1;
+ } else if (!strcmp(p, "noenablehttpproxy")) {
+ if (query) {
+ int ht = screen ? screen->httpEnableProxyConnect : 0;
+ snprintf(buf, bufn, "ans=%s:%d", p, ht == 0);
+ goto qry;
+ }
+ rfbLog("turning off enablehttpproxy.\n");
+ screen->httpEnableProxyConnect = 0;
+
+ } else if (!strcmp(p, "alwaysshared")) {
+ if (query) {
+ int t = screen ? screen->alwaysShared : 0;
+ snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
+ goto qry;
+ }
+ rfbLog("turning on alwaysshared.\n");
+ screen->alwaysShared = 1;
+ } else if (!strcmp(p, "noalwaysshared")) {
+ if (query) {
+ int t = screen ? screen->alwaysShared : 0;
+ snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
+ goto qry;
+ }
+ rfbLog("turning off alwaysshared.\n");
+ screen->alwaysShared = 0;
+
+ } else if (!strcmp(p, "nevershared")) {
+ if (query) {
+ int t = screen ? screen->neverShared : 1;
+ snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
+ goto qry;
+ }
+ rfbLog("turning on nevershared.\n");
+ screen->neverShared = 1;
+ } else if (!strcmp(p, "noalwaysshared")) {
+ if (query) {
+ int t = screen ? screen->neverShared : 1;
+ snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
+ goto qry;
+ }
+ rfbLog("turning off nevershared.\n");
+ screen->neverShared = 0;
+
+ } else if (!strcmp(p, "dontdisconnect")) {
+ if (query) {
+ int t = screen ? screen->dontDisconnect : 1;
+ snprintf(buf, bufn, "ans=%s:%d", p, t != 0);
+ goto qry;
+ }
+ rfbLog("turning on dontdisconnect.\n");
+ screen->dontDisconnect = 1;
+ } else if (!strcmp(p, "nodontdisconnect")) {
+ if (query) {
+ int t = screen ? screen->dontDisconnect : 1;
+ snprintf(buf, bufn, "ans=%s:%d", p, t == 0);
+ goto qry;
+ }
+ rfbLog("turning off dontdisconnect.\n");
+ screen->dontDisconnect = 0;
+
+ } else if (!strcmp(p, "desktop") ||
+ strstr(p, "desktop:") == p) { /* skip-cmd-list */
+ COLON_CHECK("desktop:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%s", p, co,
+ NONUL(rfb_desktop_name));
+ goto qry;
+ }
+ p += strlen("desktop:");
+ if (rfb_desktop_name) {
+ free(rfb_desktop_name);
+ }
+ rfb_desktop_name = strdup(p);
+ screen->desktopName = rfb_desktop_name;
+ rfbLog("remote_cmd: setting desktop name to %s\n",
+ rfb_desktop_name);
+
+ } else if (!strcmp(p, "debug_xevents")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_xevents);
+ goto qry;
+ }
+ debug_xevents = 1;
+ rfbLog("set debug_xevents to: %d\n", debug_xevents);
+ } else if (!strcmp(p, "nodebug_xevents")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_xevents);
+ goto qry;
+ }
+ debug_xevents = 0;
+ rfbLog("set debug_xevents to: %d\n", debug_xevents);
+ } else if (strstr(p, "debug_xevents") == p) {
+ COLON_CHECK("debug_xevents:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co, debug_xevents);
+ goto qry;
+ }
+ p += strlen("debug_xevents:");
+ debug_xevents = atoi(p);
+ rfbLog("set debug_xevents to: %d\n", debug_xevents);
+
+ } else if (!strcmp(p, "debug_xdamage")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_xdamage);
+ goto qry;
+ }
+ debug_xdamage = 1;
+ rfbLog("set debug_xdamage to: %d\n", debug_xdamage);
+ } else if (!strcmp(p, "nodebug_xdamage")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_xdamage);
+ goto qry;
+ }
+ debug_xdamage = 0;
+ rfbLog("set debug_xdamage to: %d\n", debug_xdamage);
+ } 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 (!strcmp(p, "debug_wireframe")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_wireframe);
+ goto qry;
+ }
+ debug_wireframe = 1;
+ rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
+ } else if (!strcmp(p, "nodebug_wireframe")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_wireframe);
+ goto qry;
+ }
+ debug_wireframe = 0;
+ rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
+ } else if (strstr(p, "debug_wireframe") == p) {
+ COLON_CHECK("debug_wireframe:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ debug_wireframe);
+ goto qry;
+ }
+ p += strlen("debug_wireframe:");
+ debug_wireframe = atoi(p);
+ rfbLog("set debug_wireframe to: %d\n", debug_wireframe);
+
+ } else if (!strcmp(p, "debug_scroll")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_scroll);
+ goto qry;
+ }
+ debug_scroll = 1;
+ rfbLog("set debug_scroll to: %d\n", debug_scroll);
+ } else if (!strcmp(p, "nodebug_scroll")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_scroll);
+ goto qry;
+ }
+ debug_scroll = 0;
+ rfbLog("set debug_scroll to: %d\n", debug_scroll);
+ } else if (strstr(p, "debug_scroll") == p) {
+ COLON_CHECK("debug_scroll:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ debug_scroll);
+ goto qry;
+ }
+ p += strlen("debug_scroll:");
+ debug_scroll = atoi(p);
+ rfbLog("set debug_scroll to: %d\n", debug_scroll);
+
+ } else if (!strcmp(p, "debug_tiles") || !strcmp(p, "dbt")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_tiles);
+ goto qry;
+ }
+ debug_tiles = 1;
+ rfbLog("set debug_tiles to: %d\n", debug_tiles);
+ } else if (!strcmp(p, "nodebug_tiles") || !strcmp(p, "nodbt")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_tiles);
+ goto qry;
+ }
+ debug_tiles = 0;
+ rfbLog("set debug_tiles to: %d\n", debug_tiles);
+ } else if (strstr(p, "debug_tiles") == p) {
+ COLON_CHECK("debug_tiles:")
+ if (query) {
+ snprintf(buf, bufn, "ans=%s%s%d", p, co,
+ debug_tiles);
+ goto qry;
+ }
+ p += strlen("debug_tiles:");
+ debug_tiles = atoi(p);
+ rfbLog("set debug_tiles to: %d\n", debug_tiles);
+
+ } else if (!strcmp(p, "debug_grabs")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, debug_grabs);
+ goto qry;
+ }
+ debug_grabs = 1;
+ rfbLog("set debug_grabs to: %d\n", debug_grabs);
+ } else if (!strcmp(p, "nodebug_grabs")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !debug_grabs);
+ goto qry;
+ }
+ debug_grabs = 0;
+ rfbLog("set debug_grabs to: %d\n", debug_grabs);
+
+ } else if (!strcmp(p, "dbg")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, crash_debug);
+ goto qry;
+ }
+ crash_debug = 1;
+ rfbLog("set crash_debug to: %d\n", crash_debug);
+ } else if (!strcmp(p, "nodbg")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p, !crash_debug);
+ goto qry;
+ }
+ crash_debug = 0;
+ rfbLog("set crash_debug to: %d\n", crash_debug);
+
+ } 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);
+ goto qry;
+ }
+ p += strlen("hack:");
+ hack_val = atoi(p);
+ rfbLog("set hack_val to: %d\n", hack_val);
+
+ } else if (!strcmp(p, "noremote")) {
+ if (query) {
+ snprintf(buf, bufn, "ans=%s:%d", p,
+ !accept_remote_cmds);
+ goto qry;
+ }
+ rfbLog("remote_cmd: disabling remote commands.\n");
+ accept_remote_cmds = 0; /* cannot be turned back on. */
+
+ } else if (strstr(p, "client_info_sock") == p) { /* skip-cmd-list */
+ NOTAPP
+ p += strlen("client_info_sock:");
+ if (*p != '\0') {
+ start_client_info_sock(p);
+ }
+
+ } else if (strstr(p, "noop") == p) {
+ NOTAPP
+ rfbLog("remote_cmd: noop\n");
+
+ } else if (icon_mode && !query && strstr(p, "passwd") == p) { /* skip-cmd-list */
+ char **passwds_new = (char **) malloc(3*sizeof(char *));
+ char **passwds_old = (char **) screen->authPasswdData;
+
+ COLON_CHECK("passwd:")
+ p += strlen("passwd:");
+
+ passwds_new[0] = strdup(p);
+
+ if (screen->authPasswdData &&
+ screen->passwordCheck == rfbCheckPasswordByList) {
+ passwds_new[1] = passwds_old[1];
+ } else {
+ passwds_new[1] = NULL;
+ screen->passwordCheck = rfbCheckPasswordByList;
+ }
+ passwds_new[2] = NULL;
+
+ screen->authPasswdData = (void*) passwds_new;
+ if (*p == '\0') {
+ screen->authPasswdData = (void*) NULL;
+ }
+ rfbLog("remote_cmd: changed full access passwd.\n");
+
+ } else if (icon_mode && !query && strstr(p, "viewpasswd") == p) { /* skip-cmd-list */
+ char **passwds_new = (char **) malloc(3*sizeof(char *));
+ char **passwds_old = (char **) screen->authPasswdData;
+
+ COLON_CHECK("viewpasswd:")
+ p += strlen("viewpasswd:");
+
+ passwds_new[1] = strdup(p);
+
+ if (screen->authPasswdData &&
+ screen->passwordCheck == rfbCheckPasswordByList) {
+ passwds_new[0] = passwds_old[0];
+ } else {
+ char *tmp = (char *) malloc(4 + CHALLENGESIZE);
+ rfbRandomBytes((unsigned char*)tmp);
+ passwds_new[0] = tmp;
+ screen->passwordCheck = rfbCheckPasswordByList;
+ }
+ passwds_new[2] = NULL;
+
+ if (*p == '\0') {
+ passwds_new[1] = NULL;
+ }
+
+ screen->authPasswdData = (void*) passwds_new;
+ rfbLog("remote_cmd: changed view only passwd.\n");
+
+ } else if (strstr(p, "trayembed") == p) { /* skip-cmd-list */
+ unsigned long id;
+ NOTAPP
+
+ COLON_CHECK("trayembed:")
+ p += strlen("trayembed:");
+ if (scan_hexdec(p, &id)) {
+ tray_request = (Window) id;
+ tray_unembed = 0;
+ rfbLog("remote_cmd: will try to embed 0x%x in"
+ " the system tray.\n", id);
+ }
+ } else if (strstr(p, "trayunembed") == p) { /* skip-cmd-list */
+ unsigned long id;
+ NOTAPP
+
+ COLON_CHECK("trayunembed:")
+ p += strlen("trayunembed:");
+ if (scan_hexdec(p, &id)) {
+ tray_request = (Window) id;
+ tray_unembed = 1;
+ rfbLog("remote_cmd: will try to unembed 0x%x out"
+ " of the system tray.\n", id);
+ }
+
+
+ } else if (query) {
+ /* read-only variables that can only be queried: */
+
+ if (!strcmp(p, "display")) {
+ if (raw_fb) {
+ snprintf(buf, bufn, "aro=%s:rawfb:%p",
+ p, raw_fb_addr);
+ } else if (! dpy) {
+ snprintf(buf, bufn, "aro=%s:", p);
+ } else {
+ char *d;
+ d = DisplayString(dpy);
+ if (! d) d = "unknown";
+ if (*d == ':') {
+ snprintf(buf, bufn, "aro=%s:%s%s", p,
+ this_host(), d);
+ } else {
+ snprintf(buf, bufn, "aro=%s:%s", p, d);
+ }
+ }
+ } else if (!strcmp(p, "vncdisplay")) {
+ snprintf(buf, bufn, "aro=%s:%s", p,
+ NONUL(vnc_desktop_name));
+ } else if (!strcmp(p, "desktopname")) {
+ snprintf(buf, bufn, "aro=%s:%s", p,
+ NONUL(rfb_desktop_name));
+ } else if (!strcmp(p, "guess_desktop")) {
+ snprintf(buf, bufn, "aro=%s:%s", p,
+ NONUL(guess_desktop()));
+ } else if (!strcmp(p, "http_url")) {
+ if (!screen) {
+ snprintf(buf, bufn, "aro=%s:", p);
+ } else if (screen->httpListenSock > -1) {
+ snprintf(buf, bufn, "aro=%s:http://%s:%d", p,
+ NONUL(screen->thisHost), screen->httpPort);
+ } else {
+ snprintf(buf, bufn, "aro=%s:%s", p,
+ "http_not_active");
+ }
+ } else if (!strcmp(p, "auth") || !strcmp(p, "xauth")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(auth_file));
+ } else if (!strcmp(p, "users")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(users_list));
+ } else if (!strcmp(p, "rootshift")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, rootshift);
+ } else if (!strcmp(p, "clipshift")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, clipshift);
+ } else if (!strcmp(p, "scale_str")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(scale_str));
+ } else if (!strcmp(p, "scaled_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scaled_x);
+ } else if (!strcmp(p, "scaled_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scaled_y);
+ } else if (!strcmp(p, "scale_numer")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scale_numer);
+ } else if (!strcmp(p, "scale_denom")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scale_denom);
+ } else if (!strcmp(p, "scale_fac")) {
+ snprintf(buf, bufn, "aro=%s:%f", p, scale_fac);
+ } else if (!strcmp(p, "scaling_blend")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scaling_blend);
+ } else if (!strcmp(p, "scaling_nomult4")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scaling_nomult4);
+ } else if (!strcmp(p, "scaling_pad")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, scaling_pad);
+ } else if (!strcmp(p, "scaling_interpolate")) {
+ snprintf(buf, bufn, "aro=%s:%d", p,
+ scaling_interpolate);
+ } else if (!strcmp(p, "inetd")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, inetd);
+ } 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")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, !using_shm);
+ } else if (!strcmp(p, "logfile") || !strcmp(p, "o")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(logfile));
+ } else if (!strcmp(p, "flag")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(flagfile));
+ } else if (!strcmp(p, "rc")) {
+ char *s = rc_rcfile;
+ if (rc_rcfile_default) {
+ s = NULL;
+ }
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(s));
+ } else if (!strcmp(p, "norc")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, got_norc);
+ } else if (!strcmp(p, "h") || !strcmp(p, "help") ||
+ !strcmp(p, "V") || !strcmp(p, "version") ||
+ !strcmp(p, "lastmod")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(lastmod));
+ } else if (!strcmp(p, "bg")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, opts_bg);
+ } else if (!strcmp(p, "sigpipe")) {
+ snprintf(buf, bufn, "aro=%s:%s", p, NONUL(sigpipe));
+ } else if (!strcmp(p, "threads")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, use_threads);
+ } else if (!strcmp(p, "readrate")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, get_read_rate());
+ } else if (!strcmp(p, "netrate")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, get_net_rate());
+ } else if (!strcmp(p, "netlatency")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, get_net_latency());
+ } else if (!strcmp(p, "pipeinput")) {
+ snprintf(buf, bufn, "aro=%s:%s", p,
+ NONUL(pipeinput_str));
+ } else if (!strcmp(p, "clients")) {
+ char *str = list_clients();
+ snprintf(buf, bufn, "aro=%s:%s", p, str);
+ free(str);
+ } else if (!strcmp(p, "client_count")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, client_count);
+ } else if (!strcmp(p, "pid")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, (int) getpid());
+ } else if (!strcmp(p, "ext_xtest")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xtest_present);
+ } else if (!strcmp(p, "ext_xtrap")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xtrap_present);
+ } else if (!strcmp(p, "ext_xrecord")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xrecord_present);
+ } else if (!strcmp(p, "ext_xkb")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xkb_present);
+ } else if (!strcmp(p, "ext_xshm")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xshm_present);
+ } else if (!strcmp(p, "ext_xinerama")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xinerama_present);
+ } else if (!strcmp(p, "ext_overlay")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, overlay_present);
+ } else if (!strcmp(p, "ext_xfixes")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xfixes_present);
+ } else if (!strcmp(p, "ext_xdamage")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xdamage_present);
+ } else if (!strcmp(p, "ext_xrandr")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, xrandr_present);
+ } else if (!strcmp(p, "rootwin")) {
+ snprintf(buf, bufn, "aro=%s:0x%x", p,
+ (unsigned int) rootwin);
+ } else if (!strcmp(p, "num_buttons")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, num_buttons);
+ } else if (!strcmp(p, "button_mask")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, button_mask);
+ } else if (!strcmp(p, "mouse_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, cursor_x);
+ } else if (!strcmp(p, "mouse_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, cursor_y);
+ } else if (!strcmp(p, "bpp")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, bpp);
+ } else if (!strcmp(p, "depth")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, depth);
+ } else if (!strcmp(p, "indexed_color")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, indexed_color);
+ } else if (!strcmp(p, "dpy_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, dpy_x);
+ } else if (!strcmp(p, "dpy_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, dpy_y);
+ } else if (!strcmp(p, "wdpy_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, wdpy_x);
+ } else if (!strcmp(p, "wdpy_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, wdpy_y);
+ } else if (!strcmp(p, "off_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, off_x);
+ } else if (!strcmp(p, "off_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, off_y);
+ } else if (!strcmp(p, "cdpy_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, cdpy_x);
+ } else if (!strcmp(p, "cdpy_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, cdpy_y);
+ } else if (!strcmp(p, "coff_x")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, coff_x);
+ } else if (!strcmp(p, "coff_y")) {
+ snprintf(buf, bufn, "aro=%s:%d", p, coff_y);
+ } else if (!strcmp(p, "rfbauth")) {
+ NOTAPPRO
+ } else if (!strcmp(p, "passwd")) {
+ NOTAPPRO
+ } else if (!strcmp(p, "viewpasswd")) {
+ NOTAPPRO
+ } else {
+ NOTAPP
+ }
+ goto qry;
+ } else {
+ char tmp[100];
+ NOTAPP
+ rfbLog("remote_cmd: warning unknown\n");
+ strncpy(tmp, p, 90);
+ rfbLog("command \"%s\"\n", tmp);
+ goto done;
+ }
+
+ done:
+
+ if (*buf == '\0') {
+ sprintf(buf, "ack=1");
+ }
+
+ qry:
+
+ if (stringonly) {
+ return strdup(buf);
+ } else if (client_connect_file) {
+ FILE *out = fopen(client_connect_file, "w");
+ if (out != NULL) {
+ fprintf(out, "%s\n", buf);
+ fclose(out);
+ usleep(20*1000);
+ }
+ } else {
+ if (dpy) { /* raw_fb hack */
+ set_vnc_connect_prop(buf);
+ XFlush(dpy);
+ }
+ }
+#endif
+ return NULL;
+}
+
+