1 /*
2    Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
3    All rights reserved.
4 
5 This file is part of x11vnc.
6 
7 x11vnc is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or (at
10 your option) any later version.
11 
12 x11vnc is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with x11vnc; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
20 or see <http://www.gnu.org/licenses/>.
21 
22 In addition, as a special exception, Karl J. Runge
23 gives permission to link the code of its release of x11vnc with the
24 OpenSSL project's "OpenSSL" library (or with modified versions of it
25 that use the same license as the "OpenSSL" library), and distribute
26 the linked executables.  You must obey the GNU General Public License
27 in all respects for all of the code used other than "OpenSSL".  If you
28 modify this file, you may extend this exception to your version of the
29 file, but you are not obligated to do so.  If you do not wish to do
30 so, 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 
43 int xfixes_present = 0;
44 int xfixes_first_initialized = 0;
45 int use_xfixes = 1;
46 int got_xfixes_cursor_notify = 0;
47 int cursor_changes = 0;
48 int alpha_threshold = 240;
49 double alpha_frac = 0.33;
50 int alpha_remove = 0;
51 int alpha_blend = 1;
52 int alt_arrow = 1;
53 
54 
55 void first_cursor(void);
56 void setup_cursors_and_push(void);
57 void initialize_xfixes(void);
58 int known_cursors_mode(char *s);
59 void initialize_cursors_mode(void);
60 int get_which_cursor(void);
61 void restore_cursor_shape_updates(rfbScreenInfoPtr s);
62 void disable_cursor_shape_updates(rfbScreenInfoPtr s);
63 int cursor_shape_updates_clients(rfbScreenInfoPtr s);
64 int cursor_pos_updates_clients(rfbScreenInfoPtr s);
65 void cursor_position(int x, int y);
66 void set_no_cursor(void);
67 void set_warrow_cursor(void);
68 int set_cursor(int x, int y, int which);
69 int check_x11_pointer(void);
70 int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
71 unsigned long get_cursor_serial(int mode);
72 
73 
74 typedef struct win_str_info {
75 	char *wm_name;
76 	char *res_name;
77 	char *res_class;
78 } win_str_info_t;
79 
80 typedef 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 
90 static void curs_copy(cursor_info_t *dest, cursor_info_t *src);
91 static void setup_cursors(void);
92 static void set_rfb_cursor(int which);
93 static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo);
94 static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
95     int xhot, int yhot, int Bpp);
96 static int get_exact_cursor(int init);
97 static 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  */
curs_copy(cursor_info_t * dest,cursor_info_t * src)104 static 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 */
137 static char* curs_empty_data =
138 "  "
139 "  ";
140 
141 static char* curs_empty_mask =
142 "  "
143 "  ";
144 static cursor_info_t cur_empty = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
145 
146 /* dot cursor */
147 static char* curs_dot_data =
148 "  "
149 " x";
150 
151 static char* curs_dot_mask =
152 "  "
153 " x";
154 static cursor_info_t cur_dot = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
155 
156 
157 /* main cursor */
158 static 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 
178 static 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 "                  ";
197 static cursor_info_t cur_arrow = {NULL, NULL, 18, 18, 0, 0, 1, NULL};
198 
199 static 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 
219 static 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 "                  ";
238 static cursor_info_t cur_arrow2 = {NULL, NULL, 18, 18, 0, 0, 0, NULL};
239 
240 static 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 
258 static 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 
276 static cursor_info_t cur_arrow3 = {NULL, NULL, 16, 16, 0, 0, 1, NULL};
277 
278 static 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 
296 static 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 
314 static cursor_info_t cur_arrow4 = {NULL, NULL, 16, 16, 0, 0, 0, NULL};
315 
316 static 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 
333 static 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 
350 static cursor_info_t cur_arrow5 = {NULL, NULL, 15, 15, 0, 0, 1, NULL};
351 
352 static 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 
369 static 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 
386 static cursor_info_t cur_arrow6 = {NULL, NULL, 15, 15, 0, 0, 0, NULL};
387 
388 int 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  */
393 static 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 
413 static 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 "                  ";
432 static cursor_info_t cur_root = {NULL, NULL, 18, 18, 8, 8, 1, NULL};
433 
434 static 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 
452 static 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 
470 static cursor_info_t cur_fleur = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
471 
472 static 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 
486 static 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    ";
499 static cursor_info_t cur_plus = {NULL, NULL, 12, 12, 5, 6, 1, NULL};
500 
501 static 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 
519 static 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   ";
536 static cursor_info_t cur_xterm = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
537 
538 enum 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
572 static cursor_info_t *cursors[CURS_MAX];
573 
first_cursor(void)574 void 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 
setup_cursors(void)589 static 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 
setup_cursors_and_push(void)874 void 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  */
tree_descend_cursor(int * depth,Window * w,win_str_info_t * winfo)885 static 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 
initialize_xfixes(void)990 void 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 
pixels2curs(unsigned long * pixels,int w,int h,int xhot,int yhot,int Bpp)1006 static 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 
1278 static unsigned long last_cursor = 0;
1279 static int last_index = 0;
1280 static time_t curs_times[CURS_MAX];
1281 static unsigned long curs_index[CURS_MAX];
1282 
get_cursor_serial(int mode)1283 unsigned 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 
get_exact_cursor(int init)1293 static 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 
store_cursor(int serial,unsigned long * data,int w,int h,int cbpp,int xhot,int yhot)1368 int 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
1375 fprintf(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 
known_cursors_mode(char * s)1467 int 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 
initialize_cursors_mode(void)1485 void 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 
get_which_cursor(void)1527 int 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 
set_cursor_was_changed(rfbScreenInfoPtr s)1657 static 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 */
1675 static 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 
restore_cursor_shape_updates(rfbScreenInfoPtr s)1690 void 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 
disable_cursor_shape_updates(rfbScreenInfoPtr s)1726 void 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 
cursor_shape_updates_clients(rfbScreenInfoPtr s)1772 int 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 
cursor_noshape_updates_clients(rfbScreenInfoPtr s)1790 int 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 
cursor_pos_updates_clients(rfbScreenInfoPtr s)1808 int 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  */
cursor_position(int x,int y)1831 void 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 
set_rfb_cursor(int which)1904 static 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 
set_no_cursor(void)1921 void set_no_cursor(void) {
1922 	set_rfb_cursor(CURS_EMPTY);
1923 }
1924 
set_warrow_cursor(void)1925 void set_warrow_cursor(void) {
1926 	set_rfb_cursor(CURS_WARROW);
1927 }
1928 
set_cursor(int x,int y,int which)1929 int 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  */
check_x11_pointer(void)1951 int 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 
1988 if (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