Home | History | Annotate | Download | only in x11vnc
      1 /*
      2    Copyright (C) 2002-2010 Karl J. Runge <runge (at) 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  */
    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 
    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 
    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 
    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  */
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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  */
   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 
   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 
   1921 void set_no_cursor(void) {
   1922 	set_rfb_cursor(CURS_EMPTY);
   1923 }
   1924 
   1925 void set_warrow_cursor(void) {
   1926 	set_rfb_cursor(CURS_WARROW);
   1927 }
   1928 
   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  */
   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