1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat   All rights reserved.
4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatThis file is part of x11vnc.
6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is free software; you can redistribute it and/or modify
8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatit under the terms of the GNU General Public License as published by
9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe Free Software Foundation; either version 2 of the License, or (at
10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatyour option) any later version.
11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatx11vnc is distributed in the hope that it will be useful,
13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatbut WITHOUT ANY WARRANTY; without even the implied warranty of
14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatGNU General Public License for more details.
16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatYou should have received a copy of the GNU General Public License
18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatalong with x11vnc; if not, write to the Free Software
19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehator see <http://www.gnu.org/licenses/>.
21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatIn addition, as a special exception, Karl J. Runge
23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatgives permission to link the code of its release of x11vnc with the
24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatOpenSSL project's "OpenSSL" library (or with modified versions of it
25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthat use the same license as the "OpenSSL" library), and distribute
26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatthe linked executables.  You must obey the GNU General Public License
27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatin all respects for all of the code used other than "OpenSSL".  If you
28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatmodify this file, you may extend this exception to your version of the
29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatfile, but you are not obligated to do so.  If you do not wish to do
30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatso, delete this exception statement from your version.
31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat*/
32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* -- win_utils.c -- */
34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "x11vnc.h"
36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xinerama.h"
37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "winattr_t.h"
38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "cleanup.h"
39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xwrappers.h"
40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "connections.h"
41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "xrandr.h"
42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include "macosx.h"
43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatwinattr_t *stack_list = NULL;
45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint stack_list_len = 0;
46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint stack_list_num = 0;
47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow parent_window(Window win, char **name);
50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint valid_window(Window win, XWindowAttributes *attr_ret, int bequiet);
51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatBool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int *dst_y, Window *child, int bequiet);
53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_window_size(Window win, int *w, int *h);
54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid snapshot_stack_list(int free_only, double allowed_age);
55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_boff(void);
56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_bwin(void);
57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid update_stack_list(void);
58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow query_pointer(Window start);
59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatunsigned int mask_state(void);
60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint pick_windowid(unsigned long *num);
61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow descend_pointer(int depth, Window start, char *name_info, int len);
62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid id_cmd(char *cmd);
63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow parent_window(Window win, char **name) {
66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !NO_X11
67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window r, parent;
68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window *list;
69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XErrorHandler old_handler;
70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int nchild;
71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rc;
72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (name != NULL) {
75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*name = NULL;
76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(None)
78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	nox11_exit(1);
80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!name || !win) {}
81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return None;
82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	old_handler = XSetErrorHandler(trap_xerror);
85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rc = XQueryTree_wr(dpy, win, &r, &parent, &list, &nchild);
87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSetErrorHandler(old_handler);
88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! rc || trapped_xerror) {
90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		trapped_xerror = 0;
91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return None;
92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (list) {
96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		XFree_wr(list);
97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (parent && name) {
99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		XFetchName(dpy, parent, name);
100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return parent;
102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* trapping utility to check for a valid window: */
106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XWindowAttributes attr, *pattr;
108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !NO_X11
109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XErrorHandler old_handler;
110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int ok = 0;
111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (attr_ret == NULL) {
114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pattr = &attr;
115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		pattr = attr_ret;
117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (win == None) {
120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef MACOSX
124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (macosx_console) {
125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return macosx_valid_window(win, attr_ret);
126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(0)
130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	nox11_exit(1);
133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!win || !attr_ret || !bequiet) {}
134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 0;
135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	old_handler = XSetErrorHandler(trap_xerror);
138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (XGetWindowAttributes(dpy, win, pattr)) {
140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ok = 1;
141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (trapped_xerror && trapped_xerror_event) {
143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! quiet && ! bequiet) {
144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("valid_window: trapped XError: %s (0x%lx)\n",
145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    xerror_string(trapped_xerror_event), win);
146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ok = 0;
148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSetErrorHandler(old_handler);
150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return ok;
153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatBool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat    int *dst_y, Window *child, int bequiet) {
158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XErrorHandler old_handler = NULL;
159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Bool ok = False;
160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(False)
162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	nox11_exit(1);
164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!src || !dst || !src_x || !src_y || !dst_x || !dst_y || !child || !bequiet) {}
165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!old_handler || !ok) {}
166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return False;
167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	old_handler = XSetErrorHandler(trap_xerror);
171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (XTranslateCoordinates(dpy, src, dst, src_x, src_y, dst_x,
172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	    dst_y, child)) {
173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ok = True;
174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (trapped_xerror && trapped_xerror_event) {
176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! quiet && ! bequiet) {
177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("xtranslate: trapped XError: %s (0x%lx)\n",
178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			    xerror_string(trapped_xerror_event), src);
179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ok = False;
181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSetErrorHandler(old_handler);
183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return ok;
186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_window_size(Window win, int *w, int *h) {
190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XWindowAttributes attr;
191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* valid_window? */
192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (valid_window(win, &attr, 1)) {
193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*w = attr.width;
194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		*h = attr.height;
195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 1;
196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/*
202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * For use in the -wireframe stuff, save the stacking order of the direct
203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * children of the root window.  Ideally done before we send ButtonPress
204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * to the X server.
205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */
206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid snapshot_stack_list(int free_only, double allowed_age) {
207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static double last_snap = 0.0, last_free = 0.0;
208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	double now;
209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int num, rc, i, j;
210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int ui;
211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window r, w;
212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window *list;
213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! stack_list) {
215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list = (winattr_t *) malloc(256*sizeof(winattr_t));
216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list_num = 0;
217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list_len = 256;
218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	dtime0(&now);
221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (free_only) {
222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		/* we really don't free it, just reset to zero windows */
223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list_num = 0;
224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_free = now;
225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
228a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (stack_list_num && now < last_snap + allowed_age) {
229a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
230a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
231a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
232a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	stack_list_num = 0;
233a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	last_free = now;
234a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
235a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef MACOSX
236a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! macosx_console) {
237a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		RAWFB_RET_VOID
238a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
239a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
240a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET_VOID
241a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
242a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
243a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11 && !defined(MACOSX)
244a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	num = rc = i = j = 0;	/* compiler warnings */
245a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	ui = 0;
246a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	r = w = None;
247a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	list = NULL;
248a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return;
249a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
250a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
251a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_LOCK;
252a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* no need to trap error since rootwin */
253a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
254a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	num = (int) ui;
255a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
256a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! rc) {
257a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list_num = 0;
258a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_free = now;
259a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		last_snap = 0.0;
260a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		X_UNLOCK;
261a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
262a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
263a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
264a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	last_snap = now;
265a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (num > stack_list_len + blackouts) {
266a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		int n = 2*num;
267a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		free(stack_list);
268a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list = (winattr_t *) malloc(n*sizeof(winattr_t));
269a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list_len = n;
270a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
271a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	j = 0;
272a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<num; i++) {
273a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].win = list[i];
274a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].fetched = 0;
275a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].valid = 0;
276a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].time = now;
277a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		j++;
278a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
279a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<blackouts; i++) {
280a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].win = get_boff() + 1;
281a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].fetched = 1;
282a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].valid = 1;
283a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].x = blackr[i].x1;
284a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].y = blackr[i].y1;
285a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].width  = blackr[i].x2 - blackr[i].x1;
286a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].height = blackr[i].y2 - blackr[i].y1;
287a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].time = now;
288a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].map_state = IsViewable;
289a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].rx = -1;
290a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[j].ry = -1;
291a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		j++;
292a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
293a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (0) fprintf(stderr, "blackr: %d %dx%d+%d+%d\n", i,
294a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	stack_list[j-1].width, stack_list[j-1].height,
295a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	stack_list[j-1].x, stack_list[j-1].y);
296a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
297a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
298a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	stack_list_num = num + blackouts;
299a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (debug_wireframe > 1) {
300a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fprintf(stderr, "snapshot_stack_list: num=%d len=%d\n",
301a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    stack_list_num, stack_list_len);
302a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
303a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
304a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XFree_wr(list);
305a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_UNLOCK;
306a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
307a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
308a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
309a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_boff(void) {
310a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (macosx_console) {
311a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0x1000000;
312a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
313a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
314a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
315a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
316a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
317a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint get_bwin(void) {
318a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 10;
319a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
320a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
321a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid update_stack_list(void) {
322a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int k;
323a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	double now;
324a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XWindowAttributes attr;
325a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int boff, bwin;
326a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
327a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! stack_list) {
328a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
329a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
330a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! stack_list_num) {
331a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
332a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
333a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
334a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	dtime0(&now);
335a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
336a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	boff = get_boff();
337a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	bwin = get_bwin();
338a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
339a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_LOCK;
340a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (k=0; k < stack_list_num; k++) {
341a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		Window win = stack_list[k].win;
342a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (win != None && boff <= (int) win && (int) win < boff + bwin) {
343a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			;	/* special, blackout */
344a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else if (!valid_window(win, &attr, 1)) {
345a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].valid = 0;
346a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
347a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].valid = 1;
348a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].x = attr.x;
349a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].y = attr.y;
350a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].width = attr.width;
351a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].height = attr.height;
352a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].border_width = attr.border_width;
353a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].depth = attr.depth;
354a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].class = attr.class;
355a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].backing_store = attr.backing_store;
356a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].map_state = attr.map_state;
357a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
358a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* root_x, root_y not used for stack_list usage: */
359a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].rx = -1;
360a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			stack_list[k].ry = -1;
361a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
362a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[k].fetched = 1;
363a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		stack_list[k].time = now;
364a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
365a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_UNLOCK;
366a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatif (0) fprintf(stderr, "update_stack_list[%d]: %.4f  %.4f\n", stack_list_num, now - x11vnc_start, dtime(&now));
367a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
368a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
369a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow query_pointer(Window start) {
370a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rx, ry;
371a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !NO_X11
372a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window r, c;	/* compiler warnings */
373a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int wx, wy;
374a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int mask;
375a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
376a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
377a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef MACOSX
378a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (macosx_console) {
379a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		macosx_get_cursor_pos(&rx, &ry);
380a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
381a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
382a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
383a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(None)
384a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
385a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
386a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!start) { rx = ry = 0; }
387a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return None;
388a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
389a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (start == None) {
390a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		start = rootwin;
391a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
392a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (XQueryPointer_wr(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
393a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return c;
394a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
395a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return None;
396a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
397a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
398a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
399a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
400a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatunsigned int mask_state(void) {
401a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
402a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(0)
403a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return 0;
404a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
405a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window r, c;
406a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rx, ry, wx, wy;
407a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int mask;
408a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
409a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(0)
410a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
411a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (XQueryPointer_wr(dpy, rootwin, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
412a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return mask;
413a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
414a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
415a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
416a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
417a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
418a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
419a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint pick_windowid(unsigned long *num) {
420a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char line[512];
421a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int ok = 0, n = 0, msec = 10, secmax = 15;
422a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	FILE *p;
423a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
424a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(0)
425a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
426a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (use_dpy) {
427a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		set_env("DISPLAY", use_dpy);
428a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
429a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	/* id */
430a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (no_external_cmds || !cmd_ok("id")) {
431a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLogEnable(1);
432a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("cannot run external commands in -nocmds mode:\n");
433a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("   \"%s\"\n", "xwininfo");
434a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("   exiting.\n");
435a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clean_up_exit(1);
436a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
437a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	close_exec_fds();
438a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	p = popen("xwininfo", "r");
439a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
440a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! p) {
441a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return 0;
442a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
443a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
444a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr, "\n");
445a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr, "  Please select the window for x11vnc to poll\n");
446a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr, "  by clicking the mouse in that window.\n");
447a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	fprintf(stderr, "\n");
448a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
449a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	while (msec * n++ < 1000 * secmax) {
450a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		unsigned long tmp;
451a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		char *q;
452a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		fd_set set;
453a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		struct timeval tv;
454a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
455a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (screen && screen->clientHead) {
456a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			/* they may be doing the pointer-pick thru vnc: */
457a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			int nfds;
458a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			tv.tv_sec = 0;
459a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			tv.tv_usec = msec * 1000;
460a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			FD_ZERO(&set);
461a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			FD_SET(fileno(p), &set);
462a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
463a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			nfds = select(fileno(p)+1, &set, NULL, NULL, &tv);
464a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
465a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (nfds == 0 || nfds < 0) {
466a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				/*
467a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				 * select timedout or error.
468a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				 * note this rfbPE takes about 30ms too:
469a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				 */
470a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbPE(-1);
471a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				XFlush_wr(dpy);
472a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				continue;
473a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
474a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
475a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
476a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (fgets(line, 512, p) == NULL) {
477a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
478a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
479a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		q = strstr(line, " id: 0x");
480a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (q) {
481a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			q += 5;
482a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (sscanf(q, "0x%lx ", &tmp) == 1) {
483a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				ok = 1;
484a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				*num = tmp;
485a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				fprintf(stderr, "  Picked: 0x%lx\n\n", tmp);
486a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				break;
487a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
488a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
489a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
490a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	pclose(p);
491a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return ok;
492a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
493a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
494a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatWindow descend_pointer(int depth, Window start, char *name_info, int len) {
495a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if NO_X11
496a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(None)
497a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!depth || !start || !name_info || !len) {}
498a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return None;
499a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else
500a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window r, c, clast = None;
501a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int i, rx, ry, wx, wy;
502a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int written = 0, filled = 0;
503a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	char *store = NULL;
504a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	unsigned int m;
505a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static XClassHint *classhint = NULL;
506a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static char *nm_cache = NULL;
507a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static int nm_cache_len = 0;
508a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	static Window prev_start = None;
509a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
510a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	RAWFB_RET(None)
511a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
512a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! classhint) {
513a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		classhint = XAllocClassHint();
514a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
515a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
516a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (! nm_cache) {
517a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nm_cache = (char *) malloc(1024);
518a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nm_cache_len = 1024;
519a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nm_cache[0] = '\0';
520a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
521a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (name_info && nm_cache_len < len) {
522a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (nm_cache) {
523a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			free(nm_cache);
524a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
525a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nm_cache_len = 2*len;
526a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		nm_cache = (char *) malloc(nm_cache_len);
527a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
528a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
529a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (name_info) {
530a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (start != None && start == prev_start) {
531a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			store = NULL;
532a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			strncpy(name_info, nm_cache, len);
533a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
534a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			store = name_info;
535a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			name_info[0] = '\0';
536a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
537a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
538a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
539a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (start != None) {
540a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		c = start;
541a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (name_info) {
542a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			prev_start = start;
543a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
544a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
545a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		c = rootwin;
546a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
547a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
548a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	for (i=0; i<depth; i++) {
549a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		clast = c;
550a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (store && ! filled) {
551a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *name;
552a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (XFetchName(dpy, clast, &name) && name != NULL) {
553a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int l = strlen(name);
554a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (written + l+2 < len) {
555a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					strcat(store, "^^");
556a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					written += 2;
557a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					strcat(store, name);
558a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					written += l;
559a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
560a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					filled = 1;
561a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
562a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				XFree_wr(name);
563a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
564a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
565a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (store && classhint && ! filled) {
566a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			classhint->res_name = NULL;
567a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			classhint->res_class = NULL;
568a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (XGetClassHint(dpy, clast, classhint)) {
569a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				int l = 0;
570a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (classhint->res_class) {
571a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					l += strlen(classhint->res_class);
572a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
573a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (classhint->res_name) {
574a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					l += strlen(classhint->res_name);
575a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
576a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (written + l+4 < len) {
577a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					strcat(store, "##");
578a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (classhint->res_class) {
579a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						strcat(store,
580a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						    classhint->res_class);
581a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
582a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					strcat(store, "++");
583a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					if (classhint->res_name) {
584a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						strcat(store,
585a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat						    classhint->res_name);
586a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					}
587a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					written += l+4;
588a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				} else {
589a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					filled = 1;
590a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
591a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (classhint->res_class) {
592a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					XFree_wr(classhint->res_class);
593a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
594a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				if (classhint->res_name) {
595a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat					XFree_wr(classhint->res_name);
596a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				}
597a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
598a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
599a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) {
600a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
601a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
602a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! c) {
603a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			break;
604a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
605a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
606a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (start != None && name_info) {
607a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		strncpy(nm_cache, name_info, nm_cache_len);
608a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
609a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
610a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	return clast;
611a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif	/* NO_X11 */
612a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
613a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
614a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid id_cmd(char *cmd) {
615a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int rc, dx = 0, dy = 0, dw = 0, dh = 0;
616a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int x0, y0, w0, h0;
617a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int x, y, w, h, do_move = 0, do_resize = 0;
618a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int disp_x = DisplayWidth(dpy, scr);
619a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	int disp_y = DisplayHeight(dpy, scr);
620a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window win = subwin;
621a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XWindowAttributes attr;
622a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XErrorHandler old_handler = NULL;
623a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	Window twin;
624a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
625a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!cmd || !strcmp(cmd, "")) {
626a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
627a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
628a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(cmd, "win=") == cmd) {
629a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (! scan_hexdec(cmd + strlen("win="), &win)) {
630a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("id_cmd: incorrect win= hex/dec number: %s\n", cmd);
631a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			return;
632a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		} else {
633a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			char *q = strchr(cmd, ':');
634a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (!q) {
635a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				rfbLog("id_cmd: incorrect win=...: hex/dec number: %s\n", cmd);
636a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				return;
637a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
638a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			rfbLog("id_cmd:%s set window id to 0x%lx\n", cmd, win);
639a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			cmd = q+1;
640a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
641a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
642a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!win) {
643a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s not in sub-window mode or no win=0xNNNN.\n", cmd);
644a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
645a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
646a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#if !NO_X11
647a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_LOCK;
648a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (!valid_window(win, &attr, 1)) {
649a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		X_UNLOCK;
650a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		return;
651a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
652a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	w0 = w = attr.width;
653a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	h0 = h = attr.height;
654a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	old_handler = XSetErrorHandler(trap_xerror);
655a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
656a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XTranslateCoordinates(dpy, win, rootwin, 0, 0, &x, &y, &twin);
657a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	x0 = x;
658a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	y0 = y;
659a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (strstr(cmd, "move:") == cmd) {
660a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sscanf(cmd, "move:%d%d", &dx, &dy) == 2) {
661a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			x = x + dx;
662a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			y = y + dy;
663a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_move = 1;
664a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
665a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(cmd, "resize:") == cmd) {
666a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (sscanf(cmd, "resize:%d%d", &dw, &dh) == 2) {
667a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = w + dw;
668a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = h + dh;
669a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_move = 1;
670a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_resize = 1;
671a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
672a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(cmd, "geom:") == cmd) {
673a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (parse_geom(cmd+strlen("geom:"), &w, &h, &x, &y, disp_x, disp_y)) {
674a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_move = 1;
675a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			do_resize = 1;
676a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (w <= 0) {
677a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				w = w0;
678a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
679a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (h <= 0) {
680a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				h = h0;
681a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
682a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			if (scaling && getenv("X11VNC_APPSHARE_ACTIVE")) {
683a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				x /= scale_fac_x;
684a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat				y /= scale_fac_y;
685a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			}
686a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
687a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "raise")) {
688a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = XRaiseWindow(dpy, win);
689a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
690a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "lower")) {
691a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = XLowerWindow(dpy, win);
692a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
693a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "map")) {
694a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc= XMapRaised(dpy, win);
695a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
696a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "unmap")) {
697a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc= XUnmapWindow(dpy, win);
698a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
699a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "iconify")) {
700a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc= XIconifyWindow(dpy, win, scr);
701a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
702a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(cmd, "wm_name:") == cmd) {
703a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc= XStoreName(dpy, win, cmd+strlen("wm_name:"));
704a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
705a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (strstr(cmd, "icon_name:") == cmd) {
706a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc= XSetIconName(dpy, win, cmd+strlen("icon_name:"));
707a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
708a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else if (!strcmp(cmd, "wm_delete")) {
709a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		XClientMessageEvent ev;
710a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		memset(&ev, 0, sizeof(ev));
711a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.type = ClientMessage;
712a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.send_event = True;
713a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.display = dpy;
714a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.window = win;
715a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.message_type = XInternAtom(dpy, "WM_PROTOCOLS", False);
716a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.format = 32;
717a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		ev.data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
718a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = XSendEvent(dpy, win, False, 0, (XEvent *) &ev);
719a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d\n", cmd, rc);
720a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	} else {
721a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s unrecognized command.\n", cmd);
722a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
723a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (do_move || do_resize) {
724a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (w >= disp_x) {
725a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = disp_x - 4;
726a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
727a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (h >= disp_y) {
728a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = disp_y - 4;
729a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
730a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (w < 1) {
731a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			w = 1;
732a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
733a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (h < 1) {
734a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			h = 1;
735a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
736a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (x + w > disp_x) {
737a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			x = disp_x - w - 1;
738a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
739a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (y + h > disp_y) {
740a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			y = disp_y - h - 1;
741a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
742a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (x < 0) {
743a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			x = 1;
744a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
745a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		if (y < 0) {
746a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat			y = 1;
747a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		}
748a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc = 0;
749a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc += XMoveWindow(dpy, win, x, y);
750a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		off_x = x;
751a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		off_y = y;
752a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
753a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rc += XResizeWindow(dpy, win, w, h);
754a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
755a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s rc=%d dx=%d dy=%d dw=%d dh=%d %dx%d+%d+%d -> %dx%d+%d+%d\n",
756a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		    cmd, rc, dx, dy, dw, dh, w0, h0, x0, y0, w, h, x, h);
757a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
758a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSync(dpy, False);
759a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	XSetErrorHandler(old_handler);
760a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (trapped_xerror) {
761a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s trapped_xerror.\n", cmd);
762a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
763a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	trapped_xerror = 0;
764a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	if (do_resize) {
765a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		rfbLog("id_cmd:%s calling check_xrandr_event.\n", cmd);
766a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat		check_xrandr_event("id_cmd");
767a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	}
768a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat	X_UNLOCK;
769a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif
770a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat}
771a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat
772