diff options
Diffstat (limited to 'x11vnc/win_utils.c')
-rw-r--r-- | x11vnc/win_utils.c | 771 |
1 files changed, 0 insertions, 771 deletions
diff --git a/x11vnc/win_utils.c b/x11vnc/win_utils.c deleted file mode 100644 index 7aa9b4c..0000000 --- a/x11vnc/win_utils.c +++ /dev/null @@ -1,771 +0,0 @@ -/* - Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com> - All rights reserved. - -This file is part of x11vnc. - -x11vnc is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at -your option) any later version. - -x11vnc is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with x11vnc; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -or see <http://www.gnu.org/licenses/>. - -In addition, as a special exception, Karl J. Runge -gives permission to link the code of its release of x11vnc with the -OpenSSL project's "OpenSSL" library (or with modified versions of it -that use the same license as the "OpenSSL" library), and distribute -the linked executables. You must obey the GNU General Public License -in all respects for all of the code used other than "OpenSSL". If you -modify this file, you may extend this exception to your version of the -file, but you are not obligated to do so. If you do not wish to do -so, delete this exception statement from your version. -*/ - -/* -- win_utils.c -- */ - -#include "x11vnc.h" -#include "xinerama.h" -#include "winattr_t.h" -#include "cleanup.h" -#include "xwrappers.h" -#include "connections.h" -#include "xrandr.h" -#include "macosx.h" - -winattr_t *stack_list = NULL; -int stack_list_len = 0; -int stack_list_num = 0; - - -Window parent_window(Window win, char **name); -int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet); -Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x, - int *dst_y, Window *child, int bequiet); -int get_window_size(Window win, int *w, int *h); -void snapshot_stack_list(int free_only, double allowed_age); -int get_boff(void); -int get_bwin(void); -void update_stack_list(void); -Window query_pointer(Window start); -unsigned int mask_state(void); -int pick_windowid(unsigned long *num); -Window descend_pointer(int depth, Window start, char *name_info, int len); -void id_cmd(char *cmd); - - -Window parent_window(Window win, char **name) { -#if !NO_X11 - Window r, parent; - Window *list; - XErrorHandler old_handler; - unsigned int nchild; - int rc; -#endif - - if (name != NULL) { - *name = NULL; - } - RAWFB_RET(None) -#if NO_X11 - nox11_exit(1); - if (!name || !win) {} - return None; -#else - - old_handler = XSetErrorHandler(trap_xerror); - trapped_xerror = 0; - rc = XQueryTree_wr(dpy, win, &r, &parent, &list, &nchild); - XSetErrorHandler(old_handler); - - if (! rc || trapped_xerror) { - trapped_xerror = 0; - return None; - } - trapped_xerror = 0; - - if (list) { - XFree_wr(list); - } - if (parent && name) { - XFetchName(dpy, parent, name); - } - return parent; -#endif /* NO_X11 */ -} - -/* trapping utility to check for a valid window: */ -int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) { - XWindowAttributes attr, *pattr; -#if !NO_X11 - XErrorHandler old_handler; - int ok = 0; -#endif - - if (attr_ret == NULL) { - pattr = &attr; - } else { - pattr = attr_ret; - } - - if (win == None) { - return 0; - } - -#ifdef MACOSX - if (macosx_console) { - return macosx_valid_window(win, attr_ret); - } -#endif - - RAWFB_RET(0) - -#if NO_X11 - nox11_exit(1); - if (!win || !attr_ret || !bequiet) {} - return 0; -#else - - old_handler = XSetErrorHandler(trap_xerror); - trapped_xerror = 0; - if (XGetWindowAttributes(dpy, win, pattr)) { - ok = 1; - } - if (trapped_xerror && trapped_xerror_event) { - if (! quiet && ! bequiet) { - rfbLog("valid_window: trapped XError: %s (0x%lx)\n", - xerror_string(trapped_xerror_event), win); - } - ok = 0; - } - XSetErrorHandler(old_handler); - trapped_xerror = 0; - - return ok; -#endif /* NO_X11 */ -} - -Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x, - int *dst_y, Window *child, int bequiet) { - XErrorHandler old_handler = NULL; - Bool ok = False; - - RAWFB_RET(False) -#if NO_X11 - nox11_exit(1); - if (!src || !dst || !src_x || !src_y || !dst_x || !dst_y || !child || !bequiet) {} - if (!old_handler || !ok) {} - return False; -#else - - trapped_xerror = 0; - old_handler = XSetErrorHandler(trap_xerror); - if (XTranslateCoordinates(dpy, src, dst, src_x, src_y, dst_x, - dst_y, child)) { - ok = True; - } - if (trapped_xerror && trapped_xerror_event) { - if (! quiet && ! bequiet) { - rfbLog("xtranslate: trapped XError: %s (0x%lx)\n", - xerror_string(trapped_xerror_event), src); - } - ok = False; - } - XSetErrorHandler(old_handler); - trapped_xerror = 0; - - return ok; -#endif /* NO_X11 */ -} - -int get_window_size(Window win, int *w, int *h) { - XWindowAttributes attr; - /* valid_window? */ - if (valid_window(win, &attr, 1)) { - *w = attr.width; - *h = attr.height; - return 1; - } else { - return 0; - } -} - -/* - * For use in the -wireframe stuff, save the stacking order of the direct - * children of the root window. Ideally done before we send ButtonPress - * to the X server. - */ -void snapshot_stack_list(int free_only, double allowed_age) { - static double last_snap = 0.0, last_free = 0.0; - double now; - int num, rc, i, j; - unsigned int ui; - Window r, w; - Window *list; - - if (! stack_list) { - stack_list = (winattr_t *) malloc(256*sizeof(winattr_t)); - stack_list_num = 0; - stack_list_len = 256; - } - - dtime0(&now); - if (free_only) { - /* we really don't free it, just reset to zero windows */ - stack_list_num = 0; - last_free = now; - return; - } - - if (stack_list_num && now < last_snap + allowed_age) { - return; - } - - stack_list_num = 0; - last_free = now; - -#ifdef MACOSX - if (! macosx_console) { - RAWFB_RET_VOID - } -#else - RAWFB_RET_VOID -#endif - -#if NO_X11 && !defined(MACOSX) - num = rc = i = j = 0; /* compiler warnings */ - ui = 0; - r = w = None; - list = NULL; - return; -#else - - X_LOCK; - /* no need to trap error since rootwin */ - rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui); - num = (int) ui; - - if (! rc) { - stack_list_num = 0; - last_free = now; - last_snap = 0.0; - X_UNLOCK; - return; - } - - last_snap = now; - if (num > stack_list_len + blackouts) { - int n = 2*num; - free(stack_list); - stack_list = (winattr_t *) malloc(n*sizeof(winattr_t)); - stack_list_len = n; - } - j = 0; - for (i=0; i<num; i++) { - stack_list[j].win = list[i]; - stack_list[j].fetched = 0; - stack_list[j].valid = 0; - stack_list[j].time = now; - j++; - } - for (i=0; i<blackouts; i++) { - stack_list[j].win = get_boff() + 1; - stack_list[j].fetched = 1; - stack_list[j].valid = 1; - stack_list[j].x = blackr[i].x1; - stack_list[j].y = blackr[i].y1; - stack_list[j].width = blackr[i].x2 - blackr[i].x1; - stack_list[j].height = blackr[i].y2 - blackr[i].y1; - stack_list[j].time = now; - stack_list[j].map_state = IsViewable; - stack_list[j].rx = -1; - stack_list[j].ry = -1; - j++; - -if (0) fprintf(stderr, "blackr: %d %dx%d+%d+%d\n", i, - stack_list[j-1].width, stack_list[j-1].height, - stack_list[j-1].x, stack_list[j-1].y); - - } - stack_list_num = num + blackouts; - if (debug_wireframe > 1) { - fprintf(stderr, "snapshot_stack_list: num=%d len=%d\n", - stack_list_num, stack_list_len); - } - - XFree_wr(list); - X_UNLOCK; -#endif /* NO_X11 */ -} - -int get_boff(void) { - if (macosx_console) { - return 0x1000000; - } else { - return 0; - } -} - -int get_bwin(void) { - return 10; -} - -void update_stack_list(void) { - int k; - double now; - XWindowAttributes attr; - int boff, bwin; - - if (! stack_list) { - return; - } - if (! stack_list_num) { - return; - } - - dtime0(&now); - - boff = get_boff(); - bwin = get_bwin(); - - X_LOCK; - for (k=0; k < stack_list_num; k++) { - Window win = stack_list[k].win; - if (win != None && boff <= (int) win && (int) win < boff + bwin) { - ; /* special, blackout */ - } else if (!valid_window(win, &attr, 1)) { - stack_list[k].valid = 0; - } else { - stack_list[k].valid = 1; - stack_list[k].x = attr.x; - stack_list[k].y = attr.y; - stack_list[k].width = attr.width; - stack_list[k].height = attr.height; - stack_list[k].border_width = attr.border_width; - stack_list[k].depth = attr.depth; - stack_list[k].class = attr.class; - stack_list[k].backing_store = attr.backing_store; - stack_list[k].map_state = attr.map_state; - - /* root_x, root_y not used for stack_list usage: */ - stack_list[k].rx = -1; - stack_list[k].ry = -1; - } - stack_list[k].fetched = 1; - stack_list[k].time = now; - } - X_UNLOCK; -if (0) fprintf(stderr, "update_stack_list[%d]: %.4f %.4f\n", stack_list_num, now - x11vnc_start, dtime(&now)); -} - -Window query_pointer(Window start) { - int rx, ry; -#if !NO_X11 - Window r, c; /* compiler warnings */ - int wx, wy; - unsigned int mask; -#endif - -#ifdef MACOSX - if (macosx_console) { - macosx_get_cursor_pos(&rx, &ry); - } -#endif - - RAWFB_RET(None) - -#if NO_X11 - if (!start) { rx = ry = 0; } - return None; -#else - if (start == None) { - start = rootwin; - } - if (XQueryPointer_wr(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) { - return c; - } else { - return None; - } -#endif /* NO_X11 */ -} - -unsigned int mask_state(void) { -#if NO_X11 - RAWFB_RET(0) - return 0; -#else - Window r, c; - int rx, ry, wx, wy; - unsigned int mask; - - RAWFB_RET(0) - - if (XQueryPointer_wr(dpy, rootwin, &r, &c, &rx, &ry, &wx, &wy, &mask)) { - return mask; - } else { - return 0; - } -#endif /* NO_X11 */ -} - -int pick_windowid(unsigned long *num) { - char line[512]; - int ok = 0, n = 0, msec = 10, secmax = 15; - FILE *p; - - RAWFB_RET(0) - - if (use_dpy) { - set_env("DISPLAY", use_dpy); - } - /* id */ - if (no_external_cmds || !cmd_ok("id")) { - rfbLogEnable(1); - rfbLog("cannot run external commands in -nocmds mode:\n"); - rfbLog(" \"%s\"\n", "xwininfo"); - rfbLog(" exiting.\n"); - clean_up_exit(1); - } - close_exec_fds(); - p = popen("xwininfo", "r"); - - if (! p) { - return 0; - } - - fprintf(stderr, "\n"); - fprintf(stderr, " Please select the window for x11vnc to poll\n"); - fprintf(stderr, " by clicking the mouse in that window.\n"); - fprintf(stderr, "\n"); - - while (msec * n++ < 1000 * secmax) { - unsigned long tmp; - char *q; - fd_set set; - struct timeval tv; - - if (screen && screen->clientHead) { - /* they may be doing the pointer-pick thru vnc: */ - int nfds; - tv.tv_sec = 0; - tv.tv_usec = msec * 1000; - FD_ZERO(&set); - FD_SET(fileno(p), &set); - - nfds = select(fileno(p)+1, &set, NULL, NULL, &tv); - - if (nfds == 0 || nfds < 0) { - /* - * select timedout or error. - * note this rfbPE takes about 30ms too: - */ - rfbPE(-1); - XFlush_wr(dpy); - continue; - } - } - - if (fgets(line, 512, p) == NULL) { - break; - } - q = strstr(line, " id: 0x"); - if (q) { - q += 5; - if (sscanf(q, "0x%lx ", &tmp) == 1) { - ok = 1; - *num = tmp; - fprintf(stderr, " Picked: 0x%lx\n\n", tmp); - break; - } - } - } - pclose(p); - return ok; -} - -Window descend_pointer(int depth, Window start, char *name_info, int len) { -#if NO_X11 - RAWFB_RET(None) - if (!depth || !start || !name_info || !len) {} - return None; -#else - Window r, c, clast = None; - int i, rx, ry, wx, wy; - int written = 0, filled = 0; - char *store = NULL; - unsigned int m; - static XClassHint *classhint = NULL; - static char *nm_cache = NULL; - static int nm_cache_len = 0; - static Window prev_start = None; - - RAWFB_RET(None) - - if (! classhint) { - classhint = XAllocClassHint(); - } - - if (! nm_cache) { - nm_cache = (char *) malloc(1024); - nm_cache_len = 1024; - nm_cache[0] = '\0'; - } - if (name_info && nm_cache_len < len) { - if (nm_cache) { - free(nm_cache); - } - nm_cache_len = 2*len; - nm_cache = (char *) malloc(nm_cache_len); - } - - if (name_info) { - if (start != None && start == prev_start) { - store = NULL; - strncpy(name_info, nm_cache, len); - } else { - store = name_info; - name_info[0] = '\0'; - } - } - - if (start != None) { - c = start; - if (name_info) { - prev_start = start; - } - } else { - c = rootwin; - } - - for (i=0; i<depth; i++) { - clast = c; - if (store && ! filled) { - char *name; - if (XFetchName(dpy, clast, &name) && name != NULL) { - int l = strlen(name); - if (written + l+2 < len) { - strcat(store, "^^"); - written += 2; - strcat(store, name); - written += l; - } else { - filled = 1; - } - XFree_wr(name); - } - } - if (store && classhint && ! filled) { - classhint->res_name = NULL; - classhint->res_class = NULL; - if (XGetClassHint(dpy, clast, classhint)) { - int l = 0; - if (classhint->res_class) { - l += strlen(classhint->res_class); - } - if (classhint->res_name) { - l += strlen(classhint->res_name); - } - if (written + l+4 < len) { - strcat(store, "##"); - if (classhint->res_class) { - strcat(store, - classhint->res_class); - } - strcat(store, "++"); - if (classhint->res_name) { - strcat(store, - classhint->res_name); - } - written += l+4; - } else { - filled = 1; - } - if (classhint->res_class) { - XFree_wr(classhint->res_class); - } - if (classhint->res_name) { - XFree_wr(classhint->res_name); - } - } - } - if (! XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) { - break; - } - if (! c) { - break; - } - } - if (start != None && name_info) { - strncpy(nm_cache, name_info, nm_cache_len); - } - - return clast; -#endif /* NO_X11 */ -} - -void id_cmd(char *cmd) { - int rc, dx = 0, dy = 0, dw = 0, dh = 0; - int x0, y0, w0, h0; - int x, y, w, h, do_move = 0, do_resize = 0; - int disp_x = DisplayWidth(dpy, scr); - int disp_y = DisplayHeight(dpy, scr); - Window win = subwin; - XWindowAttributes attr; - XErrorHandler old_handler = NULL; - Window twin; - - if (!cmd || !strcmp(cmd, "")) { - return; - } - if (strstr(cmd, "win=") == cmd) { - if (! scan_hexdec(cmd + strlen("win="), &win)) { - rfbLog("id_cmd: incorrect win= hex/dec number: %s\n", cmd); - return; - } else { - char *q = strchr(cmd, ':'); - if (!q) { - rfbLog("id_cmd: incorrect win=...: hex/dec number: %s\n", cmd); - return; - } - rfbLog("id_cmd:%s set window id to 0x%lx\n", cmd, win); - cmd = q+1; - } - } - if (!win) { - rfbLog("id_cmd:%s not in sub-window mode or no win=0xNNNN.\n", cmd); - return; - } -#if !NO_X11 - X_LOCK; - if (!valid_window(win, &attr, 1)) { - X_UNLOCK; - return; - } - w0 = w = attr.width; - h0 = h = attr.height; - old_handler = XSetErrorHandler(trap_xerror); - trapped_xerror = 0; - XTranslateCoordinates(dpy, win, rootwin, 0, 0, &x, &y, &twin); - x0 = x; - y0 = y; - if (strstr(cmd, "move:") == cmd) { - if (sscanf(cmd, "move:%d%d", &dx, &dy) == 2) { - x = x + dx; - y = y + dy; - do_move = 1; - } - } else if (strstr(cmd, "resize:") == cmd) { - if (sscanf(cmd, "resize:%d%d", &dw, &dh) == 2) { - w = w + dw; - h = h + dh; - do_move = 1; - do_resize = 1; - } - } else if (strstr(cmd, "geom:") == cmd) { - if (parse_geom(cmd+strlen("geom:"), &w, &h, &x, &y, disp_x, disp_y)) { - do_move = 1; - do_resize = 1; - if (w <= 0) { - w = w0; - } - if (h <= 0) { - h = h0; - } - if (scaling && getenv("X11VNC_APPSHARE_ACTIVE")) { - x /= scale_fac_x; - y /= scale_fac_y; - } - } - } else if (!strcmp(cmd, "raise")) { - rc = XRaiseWindow(dpy, win); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (!strcmp(cmd, "lower")) { - rc = XLowerWindow(dpy, win); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (!strcmp(cmd, "map")) { - rc= XMapRaised(dpy, win); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (!strcmp(cmd, "unmap")) { - rc= XUnmapWindow(dpy, win); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (!strcmp(cmd, "iconify")) { - rc= XIconifyWindow(dpy, win, scr); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (strstr(cmd, "wm_name:") == cmd) { - rc= XStoreName(dpy, win, cmd+strlen("wm_name:")); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (strstr(cmd, "icon_name:") == cmd) { - rc= XSetIconName(dpy, win, cmd+strlen("icon_name:")); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else if (!strcmp(cmd, "wm_delete")) { - XClientMessageEvent ev; - memset(&ev, 0, sizeof(ev)); - ev.type = ClientMessage; - ev.send_event = True; - ev.display = dpy; - ev.window = win; - ev.message_type = XInternAtom(dpy, "WM_PROTOCOLS", False); - ev.format = 32; - ev.data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - rc = XSendEvent(dpy, win, False, 0, (XEvent *) &ev); - rfbLog("id_cmd:%s rc=%d\n", cmd, rc); - } else { - rfbLog("id_cmd:%s unrecognized command.\n", cmd); - } - if (do_move || do_resize) { - if (w >= disp_x) { - w = disp_x - 4; - } - if (h >= disp_y) { - h = disp_y - 4; - } - if (w < 1) { - w = 1; - } - if (h < 1) { - h = 1; - } - if (x + w > disp_x) { - x = disp_x - w - 1; - } - if (y + h > disp_y) { - y = disp_y - h - 1; - } - if (x < 0) { - x = 1; - } - if (y < 0) { - y = 1; - } - rc = 0; - rc += XMoveWindow(dpy, win, x, y); - off_x = x; - off_y = y; - - rc += XResizeWindow(dpy, win, w, h); - - rfbLog("id_cmd:%s rc=%d dx=%d dy=%d dw=%d dh=%d %dx%d+%d+%d -> %dx%d+%d+%d\n", - cmd, rc, dx, dy, dw, dh, w0, h0, x0, y0, w, h, x, h); - } - XSync(dpy, False); - XSetErrorHandler(old_handler); - if (trapped_xerror) { - rfbLog("id_cmd:%s trapped_xerror.\n", cmd); - } - trapped_xerror = 0; - if (do_resize) { - rfbLog("id_cmd:%s calling check_xrandr_event.\n", cmd); - check_xrandr_event("id_cmd"); - } - X_UNLOCK; -#endif -} - |