1/*
2   Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3   All rights reserved.
4
5This file is part of x11vnc.
6
7x11vnc is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or (at
10your option) any later version.
11
12x11vnc is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with x11vnc; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20or see <http://www.gnu.org/licenses/>.
21
22In addition, as a special exception, Karl J. Runge
23gives permission to link the code of its release of x11vnc with the
24OpenSSL project's "OpenSSL" library (or with modified versions of it
25that use the same license as the "OpenSSL" library), and distribute
26the linked executables.  You must obey the GNU General Public License
27in all respects for all of the code used other than "OpenSSL".  If you
28modify this file, you may extend this exception to your version of the
29file, but you are not obligated to do so.  If you do not wish to do
30so, delete this exception statement from your version.
31*/
32
33/* -- cursor.c -- */
34
35#include "x11vnc.h"
36#include "xwrappers.h"
37#include "cleanup.h"
38#include "screen.h"
39#include "scan.h"
40#include "unixpw.h"
41#include "macosx.h"
42
43int xfixes_present = 0;
44int xfixes_first_initialized = 0;
45int use_xfixes = 1;
46int got_xfixes_cursor_notify = 0;
47int cursor_changes = 0;
48int alpha_threshold = 240;
49double alpha_frac = 0.33;
50int alpha_remove = 0;
51int alpha_blend = 1;
52int alt_arrow = 1;
53
54
55void first_cursor(void);
56void setup_cursors_and_push(void);
57void initialize_xfixes(void);
58int known_cursors_mode(char *s);
59void initialize_cursors_mode(void);
60int get_which_cursor(void);
61void restore_cursor_shape_updates(rfbScreenInfoPtr s);
62void disable_cursor_shape_updates(rfbScreenInfoPtr s);
63int cursor_shape_updates_clients(rfbScreenInfoPtr s);
64int cursor_pos_updates_clients(rfbScreenInfoPtr s);
65void cursor_position(int x, int y);
66void set_no_cursor(void);
67void set_warrow_cursor(void);
68int set_cursor(int x, int y, int which);
69int check_x11_pointer(void);
70int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
71unsigned long get_cursor_serial(int mode);
72
73
74typedef struct win_str_info {
75	char *wm_name;
76	char *res_name;
77	char *res_class;
78} win_str_info_t;
79
80typedef struct cursor_info {
81	char *data;	/* data and mask pointers */
82	char *mask;
83	int wx, wy;	/* size of cursor */
84	int sx, sy;	/* shift to its centering point */
85	int reverse;	/* swap black and white */
86	rfbCursorPtr rfb;
87} cursor_info_t;
88
89
90static void curs_copy(cursor_info_t *dest, cursor_info_t *src);
91static void setup_cursors(void);
92static void set_rfb_cursor(int which);
93static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo);
94static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
95    int xhot, int yhot, int Bpp);
96static int get_exact_cursor(int init);
97static void set_cursor_was_changed(rfbScreenInfoPtr s);
98
99
100/*
101 * Here begins a bit of a mess to experiment with multiple cursors
102 * drawn on the remote background ...
103 */
104static void curs_copy(cursor_info_t *dest, cursor_info_t *src) {
105	if (src->data != NULL) {
106		dest->data = strdup(src->data);
107	} else {
108		dest->data = NULL;
109	}
110	if (src->mask != NULL) {
111		dest->mask = strdup(src->mask);
112	} else {
113		dest->mask = NULL;
114	}
115	dest->wx = src->wx;
116	dest->wy = src->wy;
117	dest->sx = src->sx;
118	dest->sy = src->sy;
119	dest->reverse = src->reverse;
120	dest->rfb = src->rfb;
121
122	if (rotating && rotating_cursors && dest->data != NULL) {
123		int tx, ty;
124		rotate_curs(dest->data, src->data, src->wx, src->wy, 1);
125		rotate_curs(dest->mask, src->mask, src->wx, src->wy, 1);
126		rotate_coords(dest->sx, dest->sy, &tx, &ty, src->wx, src->wy);
127		dest->sx = tx;
128		dest->sy = ty;
129		if (! rotating_same) {
130			dest->wx = src->wy;
131			dest->wy = src->wx;
132		}
133	}
134}
135
136/* empty cursor */
137static char* curs_empty_data =
138"  "
139"  ";
140
141static char* curs_empty_mask =
142"  "
143"  ";
144static cursor_info_t cur_empty = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
145
146/* dot cursor */
147static char* curs_dot_data =
148"  "
149" x";
150
151static char* curs_dot_mask =
152"  "
153" x";
154static cursor_info_t cur_dot = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
155
156
157/* main cursor */
158static char* curs_arrow_data =
159"                  "
160" x                "
161" xx               "
162" xxx              "
163" xxxx             "
164" xxxxx            "
165" xxxxxx           "
166" xxxxxxx          "
167" xxxxxxxx         "
168" xxxxx            "
169" xx xx            "
170" x   xx           "
171"     xx           "
172"      xx          "
173"      xx          "
174"                  "
175"                  "
176"                  ";
177
178static char* curs_arrow_mask =
179"xx                "
180"xxx               "
181"xxxx              "
182"xxxxx             "
183"xxxxxx            "
184"xxxxxxx           "
185"xxxxxxxx          "
186"xxxxxxxxx         "
187"xxxxxxxxxx        "
188"xxxxxxxxxx        "
189"xxxxxxx           "
190"xxx xxxx          "
191"xx  xxxx          "
192"     xxxx         "
193"     xxxx         "
194"      xx          "
195"                  "
196"                  ";
197static cursor_info_t cur_arrow = {NULL, NULL, 18, 18, 0, 0, 1, NULL};
198
199static char* curs_arrow2_data =
200"                  "
201" x                "
202" xx               "
203" xxx              "
204" xxxx             "
205" xxxxx            "
206" xxxxxx           "
207" xxxxxxx          "
208" xxxxxxxx         "
209" xxxxx            "
210" xx xx            "
211" x   xx           "
212"     xx           "
213"      xx          "
214"      xx          "
215"                  "
216"                  "
217"                  ";
218
219static char* curs_arrow2_mask =
220"xx                "
221"xxx               "
222"xxxx              "
223"xxxxx             "
224"xxxxxx            "
225"xxxxxxx           "
226"xxxxxxxx          "
227"xxxxxxxxx         "
228"xxxxxxxxxx        "
229"xxxxxxxxxx        "
230"xxxxxxx           "
231"xxx xxxx          "
232"xx  xxxx          "
233"     xxxx         "
234"     xxxx         "
235"      xx          "
236"                  "
237"                  ";
238static cursor_info_t cur_arrow2 = {NULL, NULL, 18, 18, 0, 0, 0, NULL};
239
240static char* curs_arrow3_data =
241"                "
242" xx             "
243" xxxx           "
244"  xxxxx         "
245"  xxxxxxx       "
246"   xxxxxxxx     "
247"   xxxxxxxxxx   "
248"    xxxxx       "
249"    xxxxx       "
250"     xx  x      "
251"     xx   x     "
252"      x    x    "
253"      x     x   "
254"             x  "
255"              x "
256"                ";
257
258static char* curs_arrow3_mask =
259"xxx             "
260"xxxxx           "
261"xxxxxxx         "
262" xxxxxxxx       "
263" xxxxxxxxxx     "
264"  xxxxxxxxxxxx  "
265"  xxxxxxxxxxxx  "
266"   xxxxxxxxxxx  "
267"   xxxxxxx      "
268"    xxxxxxx     "
269"    xxxx xxx    "
270"     xxx  xxx   "
271"     xxx   xxx  "
272"     xxx    xxx "
273"             xxx"
274"              xx";
275
276static cursor_info_t cur_arrow3 = {NULL, NULL, 16, 16, 0, 0, 1, NULL};
277
278static char* curs_arrow4_data =
279"                "
280" xx             "
281" xxxx           "
282"  xxxxx         "
283"  xxxxxxx       "
284"   xxxxxxxx     "
285"   xxxxxxxxxx   "
286"    xxxxx       "
287"    xxxxx       "
288"     xx  x      "
289"     xx   x     "
290"      x    x    "
291"      x     x   "
292"             x  "
293"              x "
294"                ";
295
296static char* curs_arrow4_mask =
297"xxx             "
298"xxxxx           "
299"xxxxxxx         "
300" xxxxxxxx       "
301" xxxxxxxxxx     "
302"  xxxxxxxxxxxx  "
303"  xxxxxxxxxxxx  "
304"   xxxxxxxxxxx  "
305"   xxxxxxx      "
306"    xxxxxxx     "
307"    xxxx xxx    "
308"     xxx  xxx   "
309"     xxx   xxx  "
310"     xxx    xxx "
311"             xxx"
312"              xx";
313
314static cursor_info_t cur_arrow4 = {NULL, NULL, 16, 16, 0, 0, 0, NULL};
315
316static char* curs_arrow5_data =
317"x              "
318" xx            "
319" xxxx          "
320"  xxxxx        "
321"  xxxxxxx      "
322"   xxx         "
323"   xx x        "
324"    x  x       "
325"    x   x      "
326"         x     "
327"          x    "
328"           x   "
329"            x  "
330"             x "
331"              x";
332
333static char* curs_arrow5_mask =
334"xx             "
335"xxxx           "
336" xxxxx         "
337" xxxxxxx       "
338"  xxxxxxxx     "
339"  xxxxxxxx     "
340"   xxxxx       "
341"   xxxxxx      "
342"    xx xxx     "
343"     x  xxx    "
344"         xxx   "
345"          xxx  "
346"           xxx "
347"            xxx"
348"             xx";
349
350static cursor_info_t cur_arrow5 = {NULL, NULL, 15, 15, 0, 0, 1, NULL};
351
352static char* curs_arrow6_data =
353"x              "
354" xx            "
355" xxxx          "
356"  xxxxx        "
357"  xxxxxxx      "
358"   xxx         "
359"   xx x        "
360"    x  x       "
361"    x   x      "
362"         x     "
363"          x    "
364"           x   "
365"            x  "
366"             x "
367"              x";
368
369static char* curs_arrow6_mask =
370"xx             "
371"xxxx           "
372" xxxxx         "
373" xxxxxxx       "
374"  xxxxxxxx     "
375"  xxxxxxxx     "
376"   xxxxx       "
377"   xxxxxx      "
378"    xx xxx     "
379"     x  xxx    "
380"         xxx   "
381"          xxx  "
382"           xxx "
383"            xxx"
384"             xx";
385
386static cursor_info_t cur_arrow6 = {NULL, NULL, 15, 15, 0, 0, 0, NULL};
387
388int alt_arrow_max = 6;
389/*
390 * It turns out we can at least detect mouse is on the root window so
391 * show it (under -cursor X) with this familiar cursor...
392 */
393static char* curs_root_data =
394"                  "
395"                  "
396"  xxx        xxx  "
397"  xxxx      xxxx  "
398"  xxxxx    xxxxx  "
399"   xxxxx  xxxxx   "
400"    xxxxxxxxxx    "
401"     xxxxxxxx     "
402"      xxxxxx      "
403"      xxxxxx      "
404"     xxxxxxxx     "
405"    xxxxxxxxxx    "
406"   xxxxx  xxxxx   "
407"  xxxxx    xxxxx  "
408"  xxxx      xxxx  "
409"  xxx        xxx  "
410"                  "
411"                  ";
412
413static char* curs_root_mask =
414"                  "
415" xxxx        xxxx "
416" xxxxx      xxxxx "
417" xxxxxx    xxxxxx "
418" xxxxxxx  xxxxxxx "
419"  xxxxxxxxxxxxxx  "
420"   xxxxxxxxxxxx   "
421"    xxxxxxxxxx    "
422"     xxxxxxxx     "
423"     xxxxxxxx     "
424"    xxxxxxxxxx    "
425"   xxxxxxxxxxxx   "
426"  xxxxxxxxxxxxxx  "
427" xxxxxxx  xxxxxxx "
428" xxxxxx    xxxxxx "
429" xxxxx      xxxxx "
430" xxxx        xxxx "
431"                  ";
432static cursor_info_t cur_root = {NULL, NULL, 18, 18, 8, 8, 1, NULL};
433
434static char* curs_fleur_data =
435"                "
436"       xx       "
437"      xxxx      "
438"     xxxxxx     "
439"       xx       "
440"   x   xx   x   "
441"  xx   xx   xx  "
442" xxxxxxxxxxxxxx "
443" xxxxxxxxxxxxxx "
444"  xx   xx   xx  "
445"   x   xx   x   "
446"       xx       "
447"     xxxxxx     "
448"      xxxx      "
449"       xx       "
450"                ";
451
452static char* curs_fleur_mask =
453"      xxxx      "
454"      xxxxx     "
455"     xxxxxx     "
456"    xxxxxxxx    "
457"   x xxxxxx x   "
458"  xxx xxxx xxx  "
459"xxxxxxxxxxxxxxxx"
460"xxxxxxxxxxxxxxxx"
461"xxxxxxxxxxxxxxxx"
462"xxxxxxxxxxxxxxxx"
463"  xxx xxxx xxx  "
464"   x xxxxxx x   "
465"    xxxxxxxx    "
466"     xxxxxx     "
467"      xxxx      "
468"      xxxx      ";
469
470static cursor_info_t cur_fleur = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
471
472static char* curs_plus_data =
473"            "
474"     xx     "
475"     xx     "
476"     xx     "
477"     xx     "
478" xxxxxxxxxx "
479" xxxxxxxxxx "
480"     xx     "
481"     xx     "
482"     xx     "
483"     xx     "
484"            ";
485
486static char* curs_plus_mask =
487"    xxxx    "
488"    xxxx    "
489"    xxxx    "
490"    xxxx    "
491"xxxxxxxxxxxx"
492"xxxxxxxxxxxx"
493"xxxxxxxxxxxx"
494"xxxxxxxxxxxx"
495"    xxxx    "
496"    xxxx    "
497"    xxxx    "
498"    xxxx    ";
499static cursor_info_t cur_plus = {NULL, NULL, 12, 12, 5, 6, 1, NULL};
500
501static char* curs_xterm_data =
502"                "
503"     xxx xxx    "
504"       xxx      "
505"        x       "
506"        x       "
507"        x       "
508"        x       "
509"        x       "
510"        x       "
511"        x       "
512"        x       "
513"        x       "
514"        x       "
515"       xxx      "
516"     xxx xxx    "
517"                ";
518
519static char* curs_xterm_mask =
520"    xxxx xxxx   "
521"    xxxxxxxxx   "
522"    xxxxxxxxx   "
523"      xxxxx     "
524"       xxx      "
525"       xxx      "
526"       xxx      "
527"       xxx      "
528"       xxx      "
529"       xxx      "
530"       xxx      "
531"       xxx      "
532"      xxxxx     "
533"    xxxxxxxxx   "
534"    xxxxxxxxx   "
535"    xxxx xxxx   ";
536static cursor_info_t cur_xterm = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
537
538enum cursor_names {
539	CURS_EMPTY = 0,
540	CURS_DOT,
541
542	CURS_ARROW,
543	CURS_WARROW,
544	CURS_ROOT,
545	CURS_WM,
546	CURS_TERM,
547	CURS_PLUS,
548
549	CURS_DYN1,
550	CURS_DYN2,
551	CURS_DYN3,
552	CURS_DYN4,
553	CURS_DYN5,
554	CURS_DYN6,
555	CURS_DYN7,
556	CURS_DYN8,
557	CURS_DYN9,
558	CURS_DYN10,
559	CURS_DYN11,
560	CURS_DYN12,
561	CURS_DYN13,
562	CURS_DYN14,
563	CURS_DYN15,
564	CURS_DYN16
565};
566
567#define CURS_DYN_MIN CURS_DYN1
568#define CURS_DYN_MAX CURS_DYN16
569#define CURS_DYN_NUM (CURS_DYN_MAX - CURS_DYN_MIN + 1)
570
571#define CURS_MAX 32
572static cursor_info_t *cursors[CURS_MAX];
573
574void first_cursor(void) {
575	if (! screen) {
576		return;
577	}
578	if (! show_cursor) {
579		LOCK(screen->cursorMutex);
580		screen->cursor = NULL;
581		UNLOCK(screen->cursorMutex);
582	} else {
583		got_xfixes_cursor_notify++;
584		set_rfb_cursor(get_which_cursor());
585		set_cursor_was_changed(screen);
586	}
587}
588
589static void setup_cursors(void) {
590	rfbCursorPtr rfb_curs;
591	char *scale = NULL;
592	int i, j, n = 0;
593	int w_in = 0, h_in = 0;
594	static int first = 1;
595
596	if (verbose || use_threads) {
597		rfbLog("setting up %d cursors...\n", CURS_MAX);
598	}
599
600	if (first) {
601		for (i=0; i<CURS_MAX; i++) {
602			cursors[i] = NULL;
603		}
604	}
605	first = 0;
606
607	if (screen) {
608		LOCK(screen->cursorMutex);
609		screen->cursor = NULL;
610	}
611
612	for (i=0; i<CURS_MAX; i++) {
613		cursor_info_t *ci;
614		if (cursors[i]) {
615			/* clear out any existing ones: */
616			ci = cursors[i];
617			if (ci->rfb) {
618				/* this is the rfbCursor part: */
619				if (ci->rfb->richSource) {
620					free(ci->rfb->richSource);
621					ci->rfb->richSource = NULL;
622				}
623				if (ci->rfb->source) {
624					free(ci->rfb->source);
625					ci->rfb->source = NULL;
626				}
627				if (ci->rfb->mask) {
628					free(ci->rfb->mask);
629					ci->rfb->mask = NULL;
630				}
631				free(ci->rfb);
632				ci->rfb = NULL;
633			}
634			if (ci->data) {
635				free(ci->data);
636				ci->data = NULL;
637			}
638			if (ci->mask) {
639				free(ci->mask);
640				ci->mask = NULL;
641			}
642			free(ci);
643			ci = NULL;
644		}
645
646		/* create new struct: */
647		ci = (cursor_info_t *) malloc(sizeof(cursor_info_t));
648		ci->data = NULL;
649		ci->mask = NULL;
650		ci->wx = 0;
651		ci->wy = 0;
652		ci->sx = 0;
653		ci->sy = 0;
654		ci->reverse = 0;
655		ci->rfb = NULL;
656		cursors[i] = ci;
657	}
658
659	/* clear any xfixes cursor cache (no freeing is done) */
660	get_exact_cursor(1);
661
662	/* manually fill in the data+masks: */
663	cur_empty.data	= curs_empty_data;
664	cur_empty.mask	= curs_empty_mask;
665
666	cur_dot.data	= curs_dot_data;
667	cur_dot.mask	= curs_dot_mask;
668
669	cur_arrow.data	= curs_arrow_data;
670	cur_arrow.mask	= curs_arrow_mask;
671	cur_arrow2.data	= curs_arrow2_data;
672	cur_arrow2.mask	= curs_arrow2_mask;
673	cur_arrow3.data	= curs_arrow3_data;
674	cur_arrow3.mask	= curs_arrow3_mask;
675	cur_arrow4.data	= curs_arrow4_data;
676	cur_arrow4.mask	= curs_arrow4_mask;
677	cur_arrow5.data	= curs_arrow5_data;
678	cur_arrow5.mask	= curs_arrow5_mask;
679	cur_arrow6.data	= curs_arrow6_data;
680	cur_arrow6.mask	= curs_arrow6_mask;
681
682	cur_root.data	= curs_root_data;
683	cur_root.mask	= curs_root_mask;
684
685	cur_plus.data	= curs_plus_data;
686	cur_plus.mask	= curs_plus_mask;
687
688	cur_fleur.data	= curs_fleur_data;
689	cur_fleur.mask	= curs_fleur_mask;
690
691	cur_xterm.data	= curs_xterm_data;
692	cur_xterm.mask	= curs_xterm_mask;
693
694	curs_copy(cursors[CURS_EMPTY], &cur_empty);	n++;
695	curs_copy(cursors[CURS_DOT],   &cur_dot);	n++;
696
697	if (alt_arrow < 1 || alt_arrow > alt_arrow_max) {
698		alt_arrow = 1;
699	}
700	if (alt_arrow == 1) {
701		curs_copy(cursors[CURS_ARROW], &cur_arrow);	n++;
702	} else if (alt_arrow == 2) {
703		curs_copy(cursors[CURS_ARROW], &cur_arrow2);	n++;
704	} else if (alt_arrow == 3) {
705		curs_copy(cursors[CURS_ARROW], &cur_arrow3);	n++;
706	} else if (alt_arrow == 4) {
707		curs_copy(cursors[CURS_ARROW], &cur_arrow4);	n++;
708	} else if (alt_arrow == 5) {
709		curs_copy(cursors[CURS_ARROW], &cur_arrow5);	n++;
710	} else if (alt_arrow == 6) {
711		curs_copy(cursors[CURS_ARROW], &cur_arrow6);	n++;
712	} else {
713		alt_arrow = 1;
714		curs_copy(cursors[CURS_ARROW], &cur_arrow);	n++;
715	}
716	curs_copy(cursors[CURS_WARROW], &cur_arrow2);	n++;
717
718	curs_copy(cursors[CURS_ROOT], &cur_root);	n++;
719	curs_copy(cursors[CURS_WM],   &cur_fleur);	n++;
720	curs_copy(cursors[CURS_TERM], &cur_xterm);	n++;
721	curs_copy(cursors[CURS_PLUS], &cur_plus);	n++;
722
723	if (scale_cursor_str) {
724		scale = scale_cursor_str;
725	} else if (scaling && scale_str) {
726		scale = scale_str;
727	}
728	if (scale && sscanf(scale, "%dx%d", &i, &j) == 2) {
729		if (wdpy_x > 0) {
730			w_in = wdpy_x;
731			h_in = wdpy_y;
732		} else {
733			w_in = dpy_x;
734			h_in = dpy_y;
735		}
736	}
737
738	/* scale = NULL zeroes everything */
739	parse_scale_string(scale, &scale_cursor_fac_x, &scale_cursor_fac_y, &scaling_cursor,
740	    &scaling_cursor_blend, &j, &j, &scaling_cursor_interpolate,
741	    &scale_cursor_numer, &scale_cursor_denom, w_in, h_in);
742
743	for (i=0; i<n; i++) {
744		/* create rfbCursors for the special cursors: */
745
746		cursor_info_t *ci = cursors[i];
747
748		if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
749			int w, h, x, y, k;
750			unsigned long *pixels;
751
752			w = ci->wx;
753			h = ci->wy;
754
755			pixels = (unsigned long *) malloc(w * h
756			    * sizeof(unsigned long));
757
758			k = 0;
759			for (y=0; y<h; y++) {
760				for (x=0; x<w; x++) {
761					char d = ci->data[k];
762					char m = ci->mask[k];
763					unsigned long *p;
764
765					p = pixels + k;
766
767					/* set alpha on */
768					*p = 0xff000000;
769
770					if (d == ' ' && m == ' ') {
771						/* alpha off */
772						*p = 0x00000000;
773					} else if (d != ' ') {
774						/* body */
775						if (ci->reverse) {
776							*p |= 0x00000000;
777						} else {
778							*p |= 0x00ffffff;
779						}
780					} else if (m != ' ') {
781						/* edge */
782						if (ci->reverse) {
783							*p |= 0x00ffffff;
784						} else {
785							*p |= 0x00000000;
786						}
787					}
788					k++;
789				}
790			}
791
792			rfb_curs = pixels2curs(pixels, w, h, ci->sx, ci->sy,
793			    bpp/8);
794
795			free(pixels);
796
797		} else {
798
799			/* standard X cursor */
800			rfb_curs = rfbMakeXCursor(ci->wx, ci->wy,
801			    ci->data, ci->mask);
802
803			if (ci->reverse) {
804				rfb_curs->foreRed   = 0x0000;
805				rfb_curs->foreGreen = 0x0000;
806				rfb_curs->foreBlue  = 0x0000;
807				rfb_curs->backRed   = 0xffff;
808				rfb_curs->backGreen = 0xffff;
809				rfb_curs->backBlue  = 0xffff;
810			}
811			rfb_curs->alphaSource = NULL;
812
813			rfb_curs->xhot = ci->sx;
814			rfb_curs->yhot = ci->sy;
815			rfb_curs->cleanup = FALSE;
816			rfb_curs->cleanupSource = FALSE;
817			rfb_curs->cleanupMask = FALSE;
818			rfb_curs->cleanupRichSource = FALSE;
819
820			if (bpp == 8 && indexed_color) {
821				/*
822				 * use richsource in PseudoColor for better
823				 * looking cursors (i.e. two-color).
824				 */
825				int x, y, k = 0, bw;
826				int black = 0, white = 1;
827				char d, m;
828
829				if (dpy) {	/* raw_fb hack */
830					black = BlackPixel(dpy, scr);
831					white = WhitePixel(dpy, scr);
832				}
833
834				rfb_curs->richSource = (unsigned char *)
835				    calloc(ci->wx * ci->wy, 1);
836
837				for (y = 0; y < ci->wy; y++) {
838				    for (x = 0; x < ci->wx; x++) {
839					d = *(ci->data + k);
840					m = *(ci->mask + k);
841					if (d == ' ' && m == ' ') {
842						k++;
843						continue;
844					} else if (m != ' ' && d == ' ') {
845						bw = black;
846					} else {
847						bw = white;
848					}
849					if (ci->reverse) {
850						if (bw == black) {
851							bw = white;
852						} else {
853							bw = black;
854						}
855					}
856					*(rfb_curs->richSource+k) =
857					    (unsigned char) bw;
858					k++;
859				    }
860				}
861			}
862		}
863		ci->rfb = rfb_curs;
864	}
865	if (screen) {
866		UNLOCK(screen->cursorMutex);
867	}
868	if (verbose) {
869		rfbLog("  done.\n");
870	}
871	rfbLog("\n");
872}
873
874void setup_cursors_and_push(void) {
875	setup_cursors();
876	first_cursor();
877}
878
879/*
880 * Descends window tree at pointer until the window cursor matches the current
881 * cursor.  So far only used to detect if mouse is on root background or not.
882 * (returns 0 in that case, 1 otherwise).
883 *
884 */
885static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
886#if NO_X11
887	RAWFB_RET_VOID
888	if (!depth || !w || !winfo) {}
889	return;
890#else
891	Window r, c;
892	int i, rx, ry, wx, wy;
893	unsigned int mask;
894	Window wins[10];
895	int descend, maxtries = 10;
896	char *name, *s = multiple_cursors_mode;
897	static XClassHint *classhint = NULL;
898	int nm_info = 1;
899	XErrorHandler old_handler;
900
901	RAWFB_RET_VOID
902
903	if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
904		nm_info = 0;
905	}
906
907	*(winfo->wm_name)   = '\0';
908	*(winfo->res_name)  = '\0';
909	*(winfo->res_class) = '\0';
910
911	for (i=0; i < maxtries; i++) {
912		wins[i] = None;
913	}
914
915	/* some times a window can go away before we get to it */
916	trapped_xerror = 0;
917	old_handler = XSetErrorHandler(trap_xerror);
918
919	c = window;
920	descend = -1;
921
922	while (c) {
923		wins[++descend] = c;
924		if (descend >= maxtries - 1) {
925			break;
926		}
927		if ( XTestCompareCurrentCursorWithWindow_wr(dpy, c) ) {
928			break;
929		}
930		/* TBD: query_pointer() */
931		XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
932	}
933
934	if (nm_info) {
935		int got_wm_name = 0, got_res_name = 0, got_res_class = 0;
936
937		if (! classhint) {
938			classhint = XAllocClassHint();
939		}
940
941		for (i = descend; i >=0; i--) {
942			c = wins[i];
943			if (! c) {
944				continue;
945			}
946
947			if (! got_wm_name && XFetchName(dpy, c, &name)) {
948				if (name) {
949					if (*name != '\0') {
950						strcpy(winfo->wm_name, name);
951						got_wm_name = 1;
952					}
953					XFree_wr(name);
954				}
955			}
956			if (classhint && (! got_res_name || ! got_res_class)) {
957			    if (XGetClassHint(dpy, c, classhint)) {
958				char *p;
959				p = classhint->res_name;
960				if (p) {
961					if (*p != '\0' && ! got_res_name) {
962						strcpy(winfo->res_name, p);
963						got_res_name = 1;
964					}
965					XFree_wr(p);
966					classhint->res_name = NULL;
967				}
968				p = classhint->res_class;
969				if (p) {
970					if (*p != '\0' && ! got_res_class) {
971						strcpy(winfo->res_class, p);
972						got_res_class = 1;
973					}
974					XFree_wr(p);
975					classhint->res_class = NULL;
976				}
977			    }
978			}
979		}
980	}
981
982	XSetErrorHandler(old_handler);
983	trapped_xerror = 0;
984
985	*depth = descend;
986	*w = wins[descend];
987#endif	/* NO_X11 */
988}
989
990void initialize_xfixes(void) {
991#if LIBVNCSERVER_HAVE_LIBXFIXES
992	if (xfixes_present) {
993		X_LOCK;
994		if (use_xfixes) {
995			XFixesSelectCursorInput(dpy, rootwin,
996				XFixesDisplayCursorNotifyMask);
997		} else {
998			XFixesSelectCursorInput(dpy, rootwin, 0);
999		}
1000		X_UNLOCK;
1001		xfixes_first_initialized = 1;
1002	}
1003#endif
1004}
1005
1006static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
1007    int xhot, int yhot, int Bpp) {
1008	rfbCursorPtr c;
1009	static unsigned long black = 0, white = 1;
1010	static int first = 1;
1011	char *bitmap, *rich, *alpha;
1012	char *pixels_new = NULL;
1013	int n_opaque, n_trans, n_alpha, len, histo[256];
1014	int send_alpha = 0, alpha_shift = 0, thresh;
1015	int i, x, y;
1016
1017	if (first && dpy) {	/* raw_fb hack */
1018		X_LOCK;
1019		black = BlackPixel(dpy, scr);
1020		white = WhitePixel(dpy, scr);
1021		X_UNLOCK;
1022		first = 0;
1023	}
1024
1025	if (cmap8to24 && cmap8to24_fb && depth <= 16) {
1026		if (Bpp <= 2) {
1027			Bpp = 4;
1028		}
1029	}
1030
1031	if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
1032		int W, H;
1033		char *pixels_use = (char *) pixels;
1034		unsigned int *pixels32 = NULL;
1035
1036		W = w;
1037		H = h;
1038
1039		w = scale_round(W, scale_cursor_fac_x);
1040		h = scale_round(H, scale_cursor_fac_y);
1041
1042		pixels_new = (char *) malloc(4*w*h);
1043
1044		if (sizeof(unsigned long) == 8) {
1045			int i, j, k = 0;
1046			/*
1047			 * to avoid 64bpp code in scale_rect() we knock
1048			 * down to unsigned int on 64bit machines:
1049			 */
1050			pixels32 = (unsigned int*) malloc(4*W*H);
1051			for (j=0; j<H; j++) {
1052			    for (i=0; i<W; i++) {
1053				*(pixels32+k) = 0xffffffff & (*(pixels+k));
1054				k++;
1055			    }
1056			}
1057			pixels_use = (char *) pixels32;
1058		}
1059
1060		scale_rect(scale_cursor_fac_x, scale_cursor_fac_y, scaling_cursor_blend,
1061		    scaling_cursor_interpolate,
1062		    4, pixels_use, 4*W, pixels_new, 4*w,
1063		    W, H, w, h, 0, 0, W, H, 0);
1064
1065		if (sizeof(unsigned long) == 8) {
1066			int i, j, k = 0;
1067			unsigned long *pixels64;
1068			unsigned int* source = (unsigned int*) pixels_new;
1069			/*
1070			 * now knock it back up to unsigned long:
1071			 */
1072			pixels64 = (unsigned long*) malloc(8*w*h);
1073			for (j=0; j<h; j++) {
1074			    for (i=0; i<w; i++) {
1075				*(pixels64+k) = (unsigned long) (*(source+k));
1076				k++;
1077			    }
1078			}
1079			free(pixels_new);
1080			pixels_new = (char *) pixels64;
1081			if (pixels32) {
1082				free(pixels32);
1083				pixels32 = NULL;
1084			}
1085		}
1086
1087		pixels = (unsigned long *) pixels_new;
1088
1089		xhot = scale_round(xhot, scale_cursor_fac_x);
1090		yhot = scale_round(yhot, scale_cursor_fac_y);
1091	}
1092
1093	len = w * h;
1094	/* for bitmap data */
1095	bitmap = (char *) malloc(len+1);
1096	bitmap[len] = '\0';
1097
1098	/* for rich cursor pixel data */
1099	rich  = (char *)calloc(Bpp*len, 1);
1100	alpha = (char *)calloc(1*len, 1);
1101
1102	n_opaque = 0;
1103	n_trans = 0;
1104	n_alpha = 0;
1105	for (i=0; i<256; i++) {
1106		histo[i] = 0;
1107	}
1108
1109	i = 0;
1110	for (y = 0; y < h; y++) {
1111		for (x = 0; x < w; x++) {
1112			unsigned long a;
1113
1114			a = 0xff000000 & (*(pixels+i));
1115			a = a >> 24;	/* alpha channel */
1116			if (a > 0) {
1117				n_alpha++;
1118			}
1119			histo[a]++;
1120			if (a < (unsigned int) alpha_threshold) {
1121				n_trans++;
1122			} else {
1123				n_opaque++;
1124			}
1125			i++;
1126		}
1127	}
1128	if (alpha_blend) {
1129		send_alpha = 0;
1130		if (Bpp == 4) {
1131			send_alpha = 1;
1132		}
1133		alpha_shift = 24;
1134		if (main_red_shift == 24 || main_green_shift == 24 ||
1135		    main_blue_shift == 24)  {
1136			alpha_shift = 0;	/* XXX correct? */
1137		}
1138	}
1139	if (n_opaque >= alpha_frac * n_alpha) {
1140		thresh = alpha_threshold;
1141	} else {
1142		n_opaque = 0;
1143		for (i=255; i>=0; i--) {
1144			n_opaque += histo[i];
1145			thresh = i;
1146			if (n_opaque >= alpha_frac * n_alpha) {
1147				break;
1148			}
1149		}
1150	}
1151
1152	i = 0;
1153	for (y = 0; y < h; y++) {
1154		for (x = 0; x < w; x++) {
1155			unsigned long r, g, b, a;
1156			unsigned int ui;
1157			char *p;
1158
1159			a = 0xff000000 & (*(pixels+i));
1160			a = a >> 24;	/* alpha channel */
1161
1162			if (a < (unsigned int) thresh) {
1163				bitmap[i] = ' ';
1164			} else {
1165				bitmap[i] = 'x';
1166			}
1167
1168			r = 0x00ff0000 & (*(pixels+i));
1169			g = 0x0000ff00 & (*(pixels+i));
1170			b = 0x000000ff & (*(pixels+i));
1171			r = r >> 16;	/* red */
1172			g = g >> 8;	/* green */
1173			b = b >> 0;	/* blue */
1174
1175			if (alpha_remove && a != 0) {
1176				r = (255 * r) / a;
1177				g = (255 * g) / a;
1178				b = (255 * b) / a;
1179				if (r > 255) r = 255;
1180				if (g > 255) g = 255;
1181				if (b > 255) b = 255;
1182			}
1183
1184			if (indexed_color) {
1185				/*
1186				 * Choose black or white for
1187				 * PseudoColor case.
1188				 */
1189				int value = (r+g+b)/3;
1190				if (value > 127) {
1191					ui = white;
1192				} else {
1193					ui = black;
1194				}
1195			} else {
1196				/*
1197				 * Otherwise map the RGB data onto
1198				 * the framebuffer format:
1199				 */
1200				r = (main_red_max   * r)/255;
1201				g = (main_green_max * g)/255;
1202				b = (main_blue_max  * b)/255;
1203				ui = 0;
1204				ui |= (r << main_red_shift);
1205				ui |= (g << main_green_shift);
1206				ui |= (b << main_blue_shift);
1207				if (send_alpha) {
1208					ui |= (a << alpha_shift);
1209				}
1210			}
1211
1212			/* insert value into rich source: */
1213			p = rich + Bpp*i;
1214
1215			if (Bpp == 1) {
1216				*((unsigned char *)p)
1217				= (unsigned char) ui;
1218			} else if (Bpp == 2) {
1219				*((unsigned short *)p)
1220				= (unsigned short) ui;
1221			} else if (Bpp == 3) {
1222				*((unsigned char *)p)
1223				= (unsigned char) ((ui & 0x0000ff) >> 0);
1224				*((unsigned char *)(p+1))
1225				= (unsigned char) ((ui & 0x00ff00) >> 8);
1226				*((unsigned char *)(p+2))
1227				= (unsigned char) ((ui & 0xff0000) >> 16);
1228			} else if (Bpp == 4) {
1229				*((unsigned int *)p)
1230				= (unsigned int) ui;
1231			}
1232
1233			/* insert alpha value into alpha source: */
1234			p = alpha + i;
1235			*((unsigned char *)p) = (unsigned char) a;
1236
1237			i++;
1238		}
1239	}
1240
1241	/* create the cursor with the bitmap: */
1242	c = rfbMakeXCursor(w, h, bitmap, bitmap);
1243	free(bitmap);
1244
1245	if (pixels_new) {
1246		free(pixels_new);
1247	}
1248
1249	/* set up the cursor parameters: */
1250	c->xhot = xhot;
1251	c->yhot = yhot;
1252	c->cleanup = FALSE;
1253	c->cleanupSource = FALSE;
1254	c->cleanupMask = FALSE;
1255	c->cleanupRichSource = FALSE;
1256	c->richSource = (unsigned char *) rich;
1257
1258	/* zeroes mean interpolate the rich cursor somehow and use B+W */
1259	c->foreRed   = 0;
1260	c->foreGreen = 0;
1261	c->foreBlue  = 0;
1262	c->backRed   = 0;
1263	c->backGreen = 0;
1264	c->backBlue  = 0;
1265
1266	c->source = NULL;
1267
1268	if (alpha_blend && !indexed_color) {
1269		c->alphaSource = (unsigned char *) alpha;
1270		c->alphaPreMultiplied = TRUE;
1271	} else {
1272		free(alpha);
1273		c->alphaSource = NULL;
1274	}
1275	return c;
1276}
1277
1278static unsigned long last_cursor = 0;
1279static int last_index = 0;
1280static time_t curs_times[CURS_MAX];
1281static unsigned long curs_index[CURS_MAX];
1282
1283unsigned long get_cursor_serial(int mode) {
1284	if (mode == 0) {
1285		return last_cursor;
1286	} else if (mode == 1) {
1287		return (unsigned long) last_index;
1288	} else {
1289		return (unsigned long) last_index;
1290	}
1291}
1292
1293static int get_exact_cursor(int init) {
1294	int which = CURS_ARROW;
1295
1296	if (init) {
1297		/* zero out our cache (cursors are not freed) */
1298		int i;
1299		for (i=0; i<CURS_MAX; i++) {
1300			curs_times[i] = 0;
1301			curs_index[i] = 0;
1302		}
1303		last_cursor = 0;
1304		last_index = 0;
1305		return -1;
1306	}
1307
1308#ifdef MACOSX
1309	if (macosx_console) {
1310		return macosx_get_cursor();
1311	}
1312#endif
1313
1314	if (rawfb_vnc_reflect) {
1315		int last_idx = (int) get_cursor_serial(1);
1316		if (last_idx) {
1317			which = last_idx;
1318		}
1319		return which;
1320	}
1321	if (xfixes_present && dpy) {
1322#if LIBVNCSERVER_HAVE_LIBXFIXES
1323		int last_idx = (int) get_cursor_serial(1);
1324		XFixesCursorImage *xfc;
1325
1326		if (last_idx) {
1327			which = last_idx;
1328		}
1329		if (! xfixes_first_initialized) {
1330			return which;
1331		}
1332
1333		X_LOCK;
1334		if (! got_xfixes_cursor_notify && xfixes_base_event_type) {
1335			/* try again for XFixesCursorNotify event */
1336			XEvent xev;
1337			if (XCheckTypedEvent(dpy, xfixes_base_event_type +
1338			    XFixesCursorNotify, &xev)) {
1339				got_xfixes_cursor_notify++;
1340			}
1341		}
1342		if (! got_xfixes_cursor_notify) {
1343			/* evidently no cursor change, just return last one */
1344			X_UNLOCK;
1345			return which;
1346		}
1347		got_xfixes_cursor_notify = 0;
1348
1349		/* retrieve the cursor info + pixels from server: */
1350		xfc = XFixesGetCursorImage(dpy);
1351		X_UNLOCK;
1352		if (! xfc) {
1353			/* failure. */
1354			return which;
1355		}
1356
1357		which = store_cursor(xfc->cursor_serial, xfc->pixels,
1358		    xfc->width, xfc->height, 32, xfc->xhot, xfc->yhot);
1359
1360		X_LOCK;
1361		XFree_wr(xfc);
1362		X_UNLOCK;
1363#endif
1364	}
1365	return(which);
1366}
1367
1368int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp,
1369    int xhot, int yhot) {
1370	int which = CURS_ARROW;
1371	int use, oldest, i;
1372	time_t oldtime, now;
1373
1374#if 0
1375fprintf(stderr, "sc: %d  %d/%d %d - %d %d\n", serial, w, h, cbpp, xhot, yhot);
1376#endif
1377
1378	oldest = CURS_DYN_MIN;
1379	if (screen && screen->cursor == cursors[oldest]->rfb) {
1380		oldest++;
1381	}
1382	oldtime = curs_times[oldest];
1383	now = time(NULL);
1384	for (i = CURS_DYN_MIN; i <= CURS_DYN_MAX; i++) {
1385		if (screen && screen->cursor == cursors[i]->rfb) {
1386			;
1387		} else if (curs_times[i] < oldtime) {
1388			/* watch for oldest one to overwrite */
1389			oldest = i;
1390			oldtime = curs_times[i];
1391		}
1392		if (serial == (int) curs_index[i]) {
1393			/*
1394			 * got a hit with an existing cursor,
1395			 * use that one.
1396			 */
1397#ifdef MACOSX
1398			if (now > curs_times[i] + 1) {
1399				continue;
1400			}
1401#endif
1402			last_cursor = curs_index[i];
1403			curs_times[i] = now;
1404			last_index = i;
1405			return last_index;
1406		}
1407	}
1408
1409	/* we need to create the cursor and overwrite oldest */
1410	use = oldest;
1411	if (cursors[use]->rfb) {
1412		/* clean up oldest if it exists */
1413		if (cursors[use]->rfb->richSource) {
1414			free(cursors[use]->rfb->richSource);
1415			cursors[use]->rfb->richSource = NULL;
1416		}
1417		if (cursors[use]->rfb->alphaSource) {
1418			free(cursors[use]->rfb->alphaSource);
1419			cursors[use]->rfb->alphaSource = NULL;
1420		}
1421		if (cursors[use]->rfb->source) {
1422			free(cursors[use]->rfb->source);
1423			cursors[use]->rfb->source = NULL;
1424		}
1425		if (cursors[use]->rfb->mask) {
1426			free(cursors[use]->rfb->mask);
1427			cursors[use]->rfb->mask = NULL;
1428		}
1429		free(cursors[use]->rfb);
1430		cursors[use]->rfb = NULL;
1431	}
1432
1433	if (rotating && rotating_cursors) {
1434		char *dst;
1435		int tx, ty;
1436
1437		dst = (char *) malloc(w * h * cbpp/8);
1438		rotate_curs(dst, (char *) data, w, h, cbpp/8);
1439
1440		memcpy(data, dst, w * h * cbpp/8);
1441		free(dst);
1442
1443		rotate_coords(xhot, yhot, &tx, &ty, w, h);
1444		xhot = tx;
1445		yhot = ty;
1446		if (! rotating_same) {
1447			int tmp = w;
1448			w = h;
1449			h = tmp;
1450		}
1451	}
1452
1453	/* place cursor into our collection */
1454	cursors[use]->rfb = pixels2curs(data, w, h, xhot, yhot, bpp/8);
1455
1456	/* update time and serial index: */
1457	curs_times[use] = now;
1458	curs_index[use] = serial;
1459	last_index = use;
1460	last_cursor = serial;
1461
1462	which = last_index;
1463
1464	return which;
1465}
1466
1467int known_cursors_mode(char *s) {
1468/*
1469 * default:	see initialize_cursors_mode() for default behavior.
1470 * arrow:	unchanging white arrow.
1471 * Xn*:		show X on root background.  Optional n sets treedepth.
1472 * some:	do the heuristics for root, wm, term detection.
1473 * most:	if display have overlay or xfixes, show all cursors,
1474 *		otherwise do the same as "some"
1475 * none:	show no cursor.
1476 */
1477	if (strcmp(s, "default") && strcmp(s, "arrow") && *s != 'X' &&
1478	    strcmp(s, "some") && strcmp(s, "most") && strcmp(s, "none")) {
1479		return 0;
1480	} else {
1481		return 1;
1482	}
1483}
1484
1485void initialize_cursors_mode(void) {
1486	char *s = multiple_cursors_mode;
1487	if (!s || !known_cursors_mode(s)) {
1488		rfbLog("unknown cursors mode: %s\n", s);
1489		rfbLog("resetting cursors mode to \"default\"\n");
1490		if (multiple_cursors_mode) free(multiple_cursors_mode);
1491		multiple_cursors_mode = strdup("default");
1492		s = multiple_cursors_mode;
1493	}
1494	if (!strcmp(s, "none")) {
1495		show_cursor = 0;
1496	} else {
1497		/* we do NOT set show_cursor = 1, let the caller do that */
1498	}
1499
1500	show_multiple_cursors = 0;
1501	if (show_cursor) {
1502		if (!strcmp(s, "default")) {
1503			if(multiple_cursors_mode) free(multiple_cursors_mode);
1504			multiple_cursors_mode = strdup("X");
1505			s = multiple_cursors_mode;
1506		}
1507		if (*s == 'X' || !strcmp(s, "some") || !strcmp(s, "most")) {
1508			show_multiple_cursors = 1;
1509		} else {
1510			show_multiple_cursors = 0;
1511			/* hmmm, some bug going back to arrow mode.. */
1512			set_rfb_cursor(CURS_ARROW);
1513		}
1514		if (screen) {
1515			set_cursor_was_changed(screen);
1516		}
1517	} else {
1518		if (screen) {
1519			LOCK(screen->cursorMutex);
1520			screen->cursor = NULL;
1521			UNLOCK(screen->cursorMutex);
1522			set_cursor_was_changed(screen);
1523		}
1524	}
1525}
1526
1527int get_which_cursor(void) {
1528	int which = CURS_ARROW;
1529	int db = 0;
1530
1531	if (show_multiple_cursors) {
1532		int depth = 0, rint;
1533		static win_str_info_t winfo;
1534		static int first = 1, depth_cutoff = -1;
1535		Window win = None;
1536		XErrorHandler old_handler;
1537		int mode = 0;
1538
1539		if (drag_in_progress || button_mask) {
1540			/* XXX not exactly what we want for menus */
1541			if (! cursor_drag_changes) {
1542				return -1;
1543			}
1544		}
1545
1546		if (!strcmp(multiple_cursors_mode, "arrow")) {
1547			/* should not happen... */
1548			return CURS_ARROW;
1549		} else if (!strcmp(multiple_cursors_mode, "default")) {
1550			mode = 0;
1551		} else if (!strcmp(multiple_cursors_mode, "X")) {
1552			mode = 1;
1553		} else if (!strcmp(multiple_cursors_mode, "some")) {
1554			mode = 2;
1555		} else if (!strcmp(multiple_cursors_mode, "most")) {
1556			mode = 3;
1557		}
1558
1559		if (rawfb_vnc_reflect && mode > -1) {
1560			rint = get_exact_cursor(0);
1561			return rint;
1562		}
1563		if (mode == 3) {
1564			if ((xfixes_present && use_xfixes) || macosx_console) {
1565				if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
1566				rint = get_exact_cursor(0);
1567				return rint;
1568			}
1569		}
1570
1571		if (depth_cutoff < 0) {
1572			int din;
1573			if (sscanf(multiple_cursors_mode, "X%d", &din) == 1) {
1574				depth_cutoff = din;
1575			} else {
1576				depth_cutoff = 0;
1577			}
1578		}
1579
1580		if (first) {
1581			winfo.wm_name   = (char *) malloc(1024);
1582			winfo.res_name  = (char *) malloc(1024);
1583			winfo.res_class = (char *) malloc(1024);
1584		}
1585		first = 0;
1586
1587		X_LOCK;
1588		tree_descend_cursor(&depth, &win, &winfo);
1589		X_UNLOCK;
1590
1591		if (depth <= depth_cutoff && !subwin) {
1592			which = CURS_ROOT;
1593
1594		} else if (mode == 2 || mode == 3) {
1595			int which0 = which;
1596
1597			/* apply crude heuristics to choose a cursor... */
1598			if (win && dpy) {
1599				int ratio = 10, x, y;
1600				unsigned int w, h, bw, d;
1601				Window r;
1602
1603#if !NO_X11
1604				trapped_xerror = 0;
1605				X_LOCK;
1606				old_handler = XSetErrorHandler(trap_xerror);
1607
1608				/* "narrow" windows are WM */
1609				if (XGetGeometry(dpy, win, &r, &x, &y, &w, &h,
1610				    &bw, &d)) {
1611					if (w > ratio * h || h > ratio * w) {
1612						which = CURS_WM;
1613					}
1614				}
1615				XSetErrorHandler(old_handler);
1616				X_UNLOCK;
1617				trapped_xerror = 0;
1618#else
1619				if (!r || !d || !bw || !h || !w || !y || !x || !ratio || !old_handler) {}
1620#endif	/* NO_X11 */
1621			}
1622			if (which == which0) {
1623				/* the string "term" means I-beam. */
1624				char *name, *class;
1625				lowercase(winfo.res_name);
1626				lowercase(winfo.res_class);
1627				name  = winfo.res_name;
1628				class = winfo.res_class;
1629				if (strstr(name, "term")) {
1630					which = CURS_TERM;
1631				} else if (strstr(class, "term")) {
1632					which = CURS_TERM;
1633				} else if (strstr(name,  "text")) {
1634					which = CURS_TERM;
1635				} else if (strstr(class, "text")) {
1636					which = CURS_TERM;
1637				} else if (strstr(name,  "onsole")) {
1638					which = CURS_TERM;
1639				} else if (strstr(class, "onsole")) {
1640					which = CURS_TERM;
1641				} else if (strstr(name,  "cmdtool")) {
1642					which = CURS_TERM;
1643				} else if (strstr(class, "cmdtool")) {
1644					which = CURS_TERM;
1645				} else if (strstr(name,  "shelltool")) {
1646					which = CURS_TERM;
1647				} else if (strstr(class, "shelltool")) {
1648					which = CURS_TERM;
1649				}
1650			}
1651		}
1652	}
1653	if (db) fprintf(stderr, "get_which_cursor which: %d\n", which);
1654	return which;
1655}
1656
1657static void set_cursor_was_changed(rfbScreenInfoPtr s) {
1658	rfbClientIteratorPtr iter;
1659	rfbClientPtr cl;
1660
1661	if (! s) {
1662		return;
1663	}
1664	iter = rfbGetClientIterator(s);
1665	LOCK(screen->cursorMutex);
1666	while( (cl = rfbClientIteratorNext(iter)) ) {
1667		cl->cursorWasChanged = TRUE;
1668	}
1669	UNLOCK(screen->cursorMutex);
1670	rfbReleaseClientIterator(iter);
1671}
1672
1673#if 0
1674/* not yet used */
1675static void set_cursor_was_moved(rfbScreenInfoPtr s) {
1676	rfbClientIteratorPtr iter;
1677	rfbClientPtr cl;
1678
1679	if (! s) {
1680		return;
1681	}
1682	iter = rfbGetClientIterator(s);
1683	while( (cl = rfbClientIteratorNext(iter)) ) {
1684		cl->cursorWasMoved = TRUE;
1685	}
1686	rfbReleaseClientIterator(iter);
1687}
1688#endif
1689
1690void restore_cursor_shape_updates(rfbScreenInfoPtr s) {
1691	rfbClientIteratorPtr iter;
1692	rfbClientPtr cl;
1693	int count = 0;
1694
1695	if (! s || ! s->clientHead) {
1696		return;
1697	}
1698	iter = rfbGetClientIterator(s);
1699	while( (cl = rfbClientIteratorNext(iter)) ) {
1700		int changed = 0;
1701		ClientData *cd = (ClientData *) cl->clientData;
1702
1703		if (! cd) {
1704			continue;
1705		}
1706		if (cd->had_cursor_shape_updates) {
1707			rfbLog("restoring enableCursorShapeUpdates for client"
1708			    " 0x%x\n", cl);
1709			cl->enableCursorShapeUpdates = TRUE;
1710			changed = 1;
1711		}
1712		if (cd->had_cursor_pos_updates) {
1713			rfbLog("restoring enableCursorPosUpdates for client"
1714			    " 0x%x\n", cl);
1715			cl->enableCursorPosUpdates = TRUE;
1716			changed = 1;
1717		}
1718		if (changed) {
1719			cl->cursorWasChanged = TRUE;
1720			count++;
1721		}
1722	}
1723	rfbReleaseClientIterator(iter);
1724}
1725
1726void disable_cursor_shape_updates(rfbScreenInfoPtr s) {
1727	rfbClientIteratorPtr iter;
1728	rfbClientPtr cl;
1729	static int changed = 0;
1730	int count = 0;
1731
1732	if (! s || ! s->clientHead) {
1733		return;
1734	}
1735	if (unixpw_in_progress) return;
1736
1737	iter = rfbGetClientIterator(s);
1738	while( (cl = rfbClientIteratorNext(iter)) ) {
1739		ClientData *cd;
1740		cd = (ClientData *) cl->clientData;
1741
1742		if (cl->enableCursorShapeUpdates) {
1743			if (cd) {
1744				cd->had_cursor_shape_updates = 1;
1745			}
1746			count++;
1747			if (debug_pointer) {
1748				rfbLog("%s disable HCSU\n", cl->host);
1749			}
1750		}
1751		if (cl->enableCursorPosUpdates) {
1752			if (cd) {
1753				cd->had_cursor_pos_updates = 1;
1754			}
1755			count++;
1756			if (debug_pointer) {
1757				rfbLog("%s disable HCPU\n", cl->host);
1758			}
1759		}
1760
1761		cl->enableCursorShapeUpdates = FALSE;
1762		cl->enableCursorPosUpdates = FALSE;
1763		cl->cursorWasChanged = FALSE;
1764	}
1765	rfbReleaseClientIterator(iter);
1766
1767	if (count) {
1768		changed = 1;
1769	}
1770}
1771
1772int cursor_shape_updates_clients(rfbScreenInfoPtr s) {
1773	rfbClientIteratorPtr iter;
1774	rfbClientPtr cl;
1775	int count = 0;
1776
1777	if (! s) {
1778		return 0;
1779	}
1780	iter = rfbGetClientIterator(s);
1781	while( (cl = rfbClientIteratorNext(iter)) ) {
1782		if (cl->enableCursorShapeUpdates) {
1783			count++;
1784		}
1785	}
1786	rfbReleaseClientIterator(iter);
1787	return count;
1788}
1789
1790int cursor_noshape_updates_clients(rfbScreenInfoPtr s) {
1791	rfbClientIteratorPtr iter;
1792	rfbClientPtr cl;
1793	int count = 0;
1794
1795	if (! s) {
1796		return 0;
1797	}
1798	iter = rfbGetClientIterator(s);
1799	while( (cl = rfbClientIteratorNext(iter)) ) {
1800		if (!cl->enableCursorShapeUpdates) {
1801			count++;
1802		}
1803	}
1804	rfbReleaseClientIterator(iter);
1805	return count;
1806}
1807
1808int cursor_pos_updates_clients(rfbScreenInfoPtr s) {
1809	rfbClientIteratorPtr iter;
1810	rfbClientPtr cl;
1811	int count = 0;
1812
1813	if (! s) {
1814		return 0;
1815	}
1816	iter = rfbGetClientIterator(s);
1817	while( (cl = rfbClientIteratorNext(iter)) ) {
1818		if (cl->enableCursorPosUpdates) {
1819			count++;
1820		}
1821	}
1822	rfbReleaseClientIterator(iter);
1823	return count;
1824}
1825
1826/*
1827 * Record rfb cursor position screen->cursorX, etc (a la defaultPtrAddEvent())
1828 * Then set up for sending rfbCursorPosUpdates back
1829 * to clients that understand them.  This seems to be TightVNC specific.
1830 */
1831void cursor_position(int x, int y) {
1832	rfbClientIteratorPtr iter;
1833	rfbClientPtr cl;
1834	int cnt = 0, nonCursorPosUpdates_clients = 0;
1835	int x_in = x, y_in = y;
1836
1837	/* x and y are current positions of X11 pointer on the X11 display */
1838	if (!screen) {
1839		return;
1840	}
1841
1842	if (scaling) {
1843		x = ((double) x / dpy_x) * scaled_x;
1844		x = nfix(x, scaled_x);
1845		y = ((double) y / dpy_y) * scaled_y;
1846		y = nfix(y, scaled_y);
1847	}
1848
1849	if (clipshift) {
1850		if (x < 0) x = 0;
1851		if (y < 0) y = 0;
1852		if (x >= dpy_x) x = dpy_x-1;
1853		if (y >= dpy_y) y = dpy_y-1;
1854	}
1855
1856	if (x == screen->cursorX && y == screen->cursorY) {
1857		return;
1858	}
1859
1860	LOCK(screen->cursorMutex);
1861	screen->cursorX = x;
1862	screen->cursorY = y;
1863	UNLOCK(screen->cursorMutex);
1864
1865	iter = rfbGetClientIterator(screen);
1866	while( (cl = rfbClientIteratorNext(iter)) ) {
1867		if (! cl->enableCursorPosUpdates) {
1868			nonCursorPosUpdates_clients++;
1869			continue;
1870		}
1871		if (! cursor_pos_updates) {
1872			continue;
1873		}
1874		if (cl == last_pointer_client) {
1875			/*
1876			 * special case if this client was the last one to
1877			 * send a pointer position.
1878			 */
1879			if (x_in == cursor_x && y_in == cursor_y) {
1880				cl->cursorWasMoved = FALSE;
1881			} else {
1882				/* an X11 app evidently warped the pointer */
1883				if (debug_pointer) {
1884					rfbLog("cursor_position: warp "
1885					    "detected dx=%3d dy=%3d\n",
1886					    cursor_x - x, cursor_y - y);
1887				}
1888				cl->cursorWasMoved = TRUE;
1889				cnt++;
1890			}
1891		} else {
1892			cl->cursorWasMoved = TRUE;
1893			cnt++;
1894		}
1895	}
1896	rfbReleaseClientIterator(iter);
1897
1898	if (debug_pointer && cnt) {
1899		rfbLog("cursor_position: sent position x=%3d y=%3d to %d"
1900		    " clients\n", x, y, cnt);
1901	}
1902}
1903
1904static void set_rfb_cursor(int which) {
1905
1906	if (! show_cursor) {
1907		return;
1908	}
1909	if (! screen) {
1910		return;
1911	}
1912
1913	if (!cursors[which] || !cursors[which]->rfb) {
1914		rfbLog("non-existent cursor: which=%d\n", which);
1915		return;
1916	} else {
1917		rfbSetCursor(screen, cursors[which]->rfb);
1918	}
1919}
1920
1921void set_no_cursor(void) {
1922	set_rfb_cursor(CURS_EMPTY);
1923}
1924
1925void set_warrow_cursor(void) {
1926	set_rfb_cursor(CURS_WARROW);
1927}
1928
1929int set_cursor(int x, int y, int which) {
1930	static int last = -1;
1931	int changed_cursor = 0;
1932
1933	if (x || y) {} /* unused vars warning: */
1934
1935	if (which < 0) {
1936		which = last;
1937	}
1938	if (last < 0 || which != last) {
1939		set_rfb_cursor(which);
1940		changed_cursor = 1;
1941	}
1942	last = which;
1943
1944	return changed_cursor;
1945}
1946
1947/*
1948 * routine called periodically to update cursor aspects, this catches
1949 * warps and cursor shape changes.
1950 */
1951int check_x11_pointer(void) {
1952	Window root_w, child_w;
1953	rfbBool ret = 0;
1954	int root_x, root_y, win_x, win_y;
1955	int x, y, rint;
1956	unsigned int mask;
1957
1958	if (unixpw_in_progress) return 0;
1959
1960#ifdef MACOSX
1961	if (macosx_console) {
1962		ret = macosx_get_cursor_pos(&root_x, &root_y);
1963	} else {
1964		RAWFB_RET(0)
1965	}
1966#else
1967
1968	RAWFB_RET(0)
1969
1970#   if NO_X11
1971	return 0;
1972#   endif
1973
1974#endif
1975
1976
1977#if ! NO_X11
1978	if (dpy) {
1979		X_LOCK;
1980		ret = XQueryPointer_wr(dpy, rootwin, &root_w, &child_w, &root_x, &root_y,
1981		    &win_x, &win_y, &mask);
1982		X_UNLOCK;
1983	}
1984#else
1985	if (!mask || !win_y || !win_x || !child_w || !root_w) {}
1986#endif	/* NO_X11 */
1987
1988if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
1989	if (! ret) {
1990		return 0;
1991	}
1992	if (debug_pointer) {
1993		static int last_x = -1, last_y = -1;
1994		if (root_x != last_x || root_y != last_y) {
1995			rfbLog("XQueryPointer:     x:%4d, y:%4d)\n",
1996			    root_x, root_y);
1997		}
1998		last_x = root_x;
1999		last_y = root_y;
2000	}
2001
2002	/* offset subtracted since XQueryPointer relative to rootwin */
2003	x = root_x - off_x - coff_x;
2004	y = root_y - off_y - coff_y;
2005
2006	if (clipshift) {
2007		static int cnt = 0;
2008		if (x < 0 || y < 0 || x >= dpy_x || y >= dpy_y)  {
2009			if (cnt++ % 4 != 0) {
2010				if (debug_pointer) {
2011					rfbLog("Skipping cursor_position() outside our clipshift\n");
2012				}
2013				return 0;
2014			}
2015		}
2016	}
2017
2018	/* record the cursor position in the rfb screen */
2019	cursor_position(x, y);
2020
2021	/* change the cursor shape if necessary */
2022	rint = set_cursor(x, y, get_which_cursor());
2023	return rint;
2024}
2025
2026