summaryrefslogtreecommitdiffstats
path: root/x11vnc/cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/cursor.c')
-rw-r--r--x11vnc/cursor.c2025
1 files changed, 0 insertions, 2025 deletions
diff --git a/x11vnc/cursor.c b/x11vnc/cursor.c
deleted file mode 100644
index 3d613a6..0000000
--- a/x11vnc/cursor.c
+++ /dev/null
@@ -1,2025 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- cursor.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "cleanup.h"
-#include "screen.h"
-#include "scan.h"
-#include "unixpw.h"
-#include "macosx.h"
-
-int xfixes_present = 0;
-int xfixes_first_initialized = 0;
-int use_xfixes = 1;
-int got_xfixes_cursor_notify = 0;
-int cursor_changes = 0;
-int alpha_threshold = 240;
-double alpha_frac = 0.33;
-int alpha_remove = 0;
-int alpha_blend = 1;
-int alt_arrow = 1;
-
-
-void first_cursor(void);
-void setup_cursors_and_push(void);
-void initialize_xfixes(void);
-int known_cursors_mode(char *s);
-void initialize_cursors_mode(void);
-int get_which_cursor(void);
-void restore_cursor_shape_updates(rfbScreenInfoPtr s);
-void disable_cursor_shape_updates(rfbScreenInfoPtr s);
-int cursor_shape_updates_clients(rfbScreenInfoPtr s);
-int cursor_pos_updates_clients(rfbScreenInfoPtr s);
-void cursor_position(int x, int y);
-void set_no_cursor(void);
-void set_warrow_cursor(void);
-int set_cursor(int x, int y, int which);
-int check_x11_pointer(void);
-int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
-unsigned long get_cursor_serial(int mode);
-
-
-typedef struct win_str_info {
- char *wm_name;
- char *res_name;
- char *res_class;
-} win_str_info_t;
-
-typedef struct cursor_info {
- char *data; /* data and mask pointers */
- char *mask;
- int wx, wy; /* size of cursor */
- int sx, sy; /* shift to its centering point */
- int reverse; /* swap black and white */
- rfbCursorPtr rfb;
-} cursor_info_t;
-
-
-static void curs_copy(cursor_info_t *dest, cursor_info_t *src);
-static void setup_cursors(void);
-static void set_rfb_cursor(int which);
-static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo);
-static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
- int xhot, int yhot, int Bpp);
-static int get_exact_cursor(int init);
-static void set_cursor_was_changed(rfbScreenInfoPtr s);
-
-
-/*
- * Here begins a bit of a mess to experiment with multiple cursors
- * drawn on the remote background ...
- */
-static void curs_copy(cursor_info_t *dest, cursor_info_t *src) {
- if (src->data != NULL) {
- dest->data = strdup(src->data);
- } else {
- dest->data = NULL;
- }
- if (src->mask != NULL) {
- dest->mask = strdup(src->mask);
- } else {
- dest->mask = NULL;
- }
- dest->wx = src->wx;
- dest->wy = src->wy;
- dest->sx = src->sx;
- dest->sy = src->sy;
- dest->reverse = src->reverse;
- dest->rfb = src->rfb;
-
- if (rotating && rotating_cursors && dest->data != NULL) {
- int tx, ty;
- rotate_curs(dest->data, src->data, src->wx, src->wy, 1);
- rotate_curs(dest->mask, src->mask, src->wx, src->wy, 1);
- rotate_coords(dest->sx, dest->sy, &tx, &ty, src->wx, src->wy);
- dest->sx = tx;
- dest->sy = ty;
- if (! rotating_same) {
- dest->wx = src->wy;
- dest->wy = src->wx;
- }
- }
-}
-
-/* empty cursor */
-static char* curs_empty_data =
-" "
-" ";
-
-static char* curs_empty_mask =
-" "
-" ";
-static cursor_info_t cur_empty = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
-
-/* dot cursor */
-static char* curs_dot_data =
-" "
-" x";
-
-static char* curs_dot_mask =
-" "
-" x";
-static cursor_info_t cur_dot = {NULL, NULL, 2, 2, 0, 0, 0, NULL};
-
-
-/* main cursor */
-static char* curs_arrow_data =
-" "
-" x "
-" xx "
-" xxx "
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xx xx "
-" x xx "
-" xx "
-" xx "
-" xx "
-" "
-" "
-" ";
-
-static char* curs_arrow_mask =
-"xx "
-"xxx "
-"xxxx "
-"xxxxx "
-"xxxxxx "
-"xxxxxxx "
-"xxxxxxxx "
-"xxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxx "
-"xxx xxxx "
-"xx xxxx "
-" xxxx "
-" xxxx "
-" xx "
-" "
-" ";
-static cursor_info_t cur_arrow = {NULL, NULL, 18, 18, 0, 0, 1, NULL};
-
-static char* curs_arrow2_data =
-" "
-" x "
-" xx "
-" xxx "
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xx xx "
-" x xx "
-" xx "
-" xx "
-" xx "
-" "
-" "
-" ";
-
-static char* curs_arrow2_mask =
-"xx "
-"xxx "
-"xxxx "
-"xxxxx "
-"xxxxxx "
-"xxxxxxx "
-"xxxxxxxx "
-"xxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxxxxx "
-"xxxxxxx "
-"xxx xxxx "
-"xx xxxx "
-" xxxx "
-" xxxx "
-" xx "
-" "
-" ";
-static cursor_info_t cur_arrow2 = {NULL, NULL, 18, 18, 0, 0, 0, NULL};
-
-static char* curs_arrow3_data =
-" "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx "
-" xxxxx "
-" xx x "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" ";
-
-static char* curs_arrow3_mask =
-"xxx "
-"xxxxx "
-"xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxx "
-" xxxxxxx "
-" xxxxxxx "
-" xxxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow3 = {NULL, NULL, 16, 16, 0, 0, 1, NULL};
-
-static char* curs_arrow4_data =
-" "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx "
-" xxxxx "
-" xx x "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" ";
-
-static char* curs_arrow4_mask =
-"xxx "
-"xxxxx "
-"xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxx "
-" xxxxxxx "
-" xxxxxxx "
-" xxxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow4 = {NULL, NULL, 16, 16, 0, 0, 0, NULL};
-
-static char* curs_arrow5_data =
-"x "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxx "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x";
-
-static char* curs_arrow5_mask =
-"xx "
-"xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xxxxxx "
-" xx xxx "
-" x xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow5 = {NULL, NULL, 15, 15, 0, 0, 1, NULL};
-
-static char* curs_arrow6_data =
-"x "
-" xx "
-" xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxx "
-" xx x "
-" x x "
-" x x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x";
-
-static char* curs_arrow6_mask =
-"xx "
-"xxxx "
-" xxxxx "
-" xxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxx "
-" xxxxxx "
-" xx xxx "
-" x xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx"
-" xx";
-
-static cursor_info_t cur_arrow6 = {NULL, NULL, 15, 15, 0, 0, 0, NULL};
-
-int alt_arrow_max = 6;
-/*
- * It turns out we can at least detect mouse is on the root window so
- * show it (under -cursor X) with this familiar cursor...
- */
-static char* curs_root_data =
-" "
-" "
-" xxx xxx "
-" xxxx xxxx "
-" xxxxx xxxxx "
-" xxxxx xxxxx "
-" xxxxxxxxxx "
-" xxxxxxxx "
-" xxxxxx "
-" xxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxx xxxxx "
-" xxxxx xxxxx "
-" xxxx xxxx "
-" xxx xxx "
-" "
-" ";
-
-static char* curs_root_mask =
-" "
-" xxxx xxxx "
-" xxxxx xxxxx "
-" xxxxxx xxxxxx "
-" xxxxxxx xxxxxxx "
-" xxxxxxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxx "
-" xxxxxxxx "
-" xxxxxxxxxx "
-" xxxxxxxxxxxx "
-" xxxxxxxxxxxxxx "
-" xxxxxxx xxxxxxx "
-" xxxxxx xxxxxx "
-" xxxxx xxxxx "
-" xxxx xxxx "
-" ";
-static cursor_info_t cur_root = {NULL, NULL, 18, 18, 8, 8, 1, NULL};
-
-static char* curs_fleur_data =
-" "
-" xx "
-" xxxx "
-" xxxxxx "
-" xx "
-" x xx x "
-" xx xx xx "
-" xxxxxxxxxxxxxx "
-" xxxxxxxxxxxxxx "
-" xx xx xx "
-" x xx x "
-" xx "
-" xxxxxx "
-" xxxx "
-" xx "
-" ";
-
-static char* curs_fleur_mask =
-" xxxx "
-" xxxxx "
-" xxxxxx "
-" xxxxxxxx "
-" x xxxxxx x "
-" xxx xxxx xxx "
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-"xxxxxxxxxxxxxxxx"
-" xxx xxxx xxx "
-" x xxxxxx x "
-" xxxxxxxx "
-" xxxxxx "
-" xxxx "
-" xxxx ";
-
-static cursor_info_t cur_fleur = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
-
-static char* curs_plus_data =
-" "
-" xx "
-" xx "
-" xx "
-" xx "
-" xxxxxxxxxx "
-" xxxxxxxxxx "
-" xx "
-" xx "
-" xx "
-" xx "
-" ";
-
-static char* curs_plus_mask =
-" xxxx "
-" xxxx "
-" xxxx "
-" xxxx "
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-"xxxxxxxxxxxx"
-" xxxx "
-" xxxx "
-" xxxx "
-" xxxx ";
-static cursor_info_t cur_plus = {NULL, NULL, 12, 12, 5, 6, 1, NULL};
-
-static char* curs_xterm_data =
-" "
-" xxx xxx "
-" xxx "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" x "
-" xxx "
-" xxx xxx "
-" ";
-
-static char* curs_xterm_mask =
-" xxxx xxxx "
-" xxxxxxxxx "
-" xxxxxxxxx "
-" xxxxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxx "
-" xxxxx "
-" xxxxxxxxx "
-" xxxxxxxxx "
-" xxxx xxxx ";
-static cursor_info_t cur_xterm = {NULL, NULL, 16, 16, 8, 8, 1, NULL};
-
-enum cursor_names {
- CURS_EMPTY = 0,
- CURS_DOT,
-
- CURS_ARROW,
- CURS_WARROW,
- CURS_ROOT,
- CURS_WM,
- CURS_TERM,
- CURS_PLUS,
-
- CURS_DYN1,
- CURS_DYN2,
- CURS_DYN3,
- CURS_DYN4,
- CURS_DYN5,
- CURS_DYN6,
- CURS_DYN7,
- CURS_DYN8,
- CURS_DYN9,
- CURS_DYN10,
- CURS_DYN11,
- CURS_DYN12,
- CURS_DYN13,
- CURS_DYN14,
- CURS_DYN15,
- CURS_DYN16
-};
-
-#define CURS_DYN_MIN CURS_DYN1
-#define CURS_DYN_MAX CURS_DYN16
-#define CURS_DYN_NUM (CURS_DYN_MAX - CURS_DYN_MIN + 1)
-
-#define CURS_MAX 32
-static cursor_info_t *cursors[CURS_MAX];
-
-void first_cursor(void) {
- if (! screen) {
- return;
- }
- if (! show_cursor) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- UNLOCK(screen->cursorMutex);
- } else {
- got_xfixes_cursor_notify++;
- set_rfb_cursor(get_which_cursor());
- set_cursor_was_changed(screen);
- }
-}
-
-static void setup_cursors(void) {
- rfbCursorPtr rfb_curs;
- char *scale = NULL;
- int i, j, n = 0;
- int w_in = 0, h_in = 0;
- static int first = 1;
-
- if (verbose || use_threads) {
- rfbLog("setting up %d cursors...\n", CURS_MAX);
- }
-
- if (first) {
- for (i=0; i<CURS_MAX; i++) {
- cursors[i] = NULL;
- }
- }
- first = 0;
-
- if (screen) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- }
-
- for (i=0; i<CURS_MAX; i++) {
- cursor_info_t *ci;
- if (cursors[i]) {
- /* clear out any existing ones: */
- ci = cursors[i];
- if (ci->rfb) {
- /* this is the rfbCursor part: */
- if (ci->rfb->richSource) {
- free(ci->rfb->richSource);
- ci->rfb->richSource = NULL;
- }
- if (ci->rfb->source) {
- free(ci->rfb->source);
- ci->rfb->source = NULL;
- }
- if (ci->rfb->mask) {
- free(ci->rfb->mask);
- ci->rfb->mask = NULL;
- }
- free(ci->rfb);
- ci->rfb = NULL;
- }
- if (ci->data) {
- free(ci->data);
- ci->data = NULL;
- }
- if (ci->mask) {
- free(ci->mask);
- ci->mask = NULL;
- }
- free(ci);
- ci = NULL;
- }
-
- /* create new struct: */
- ci = (cursor_info_t *) malloc(sizeof(cursor_info_t));
- ci->data = NULL;
- ci->mask = NULL;
- ci->wx = 0;
- ci->wy = 0;
- ci->sx = 0;
- ci->sy = 0;
- ci->reverse = 0;
- ci->rfb = NULL;
- cursors[i] = ci;
- }
-
- /* clear any xfixes cursor cache (no freeing is done) */
- get_exact_cursor(1);
-
- /* manually fill in the data+masks: */
- cur_empty.data = curs_empty_data;
- cur_empty.mask = curs_empty_mask;
-
- cur_dot.data = curs_dot_data;
- cur_dot.mask = curs_dot_mask;
-
- cur_arrow.data = curs_arrow_data;
- cur_arrow.mask = curs_arrow_mask;
- cur_arrow2.data = curs_arrow2_data;
- cur_arrow2.mask = curs_arrow2_mask;
- cur_arrow3.data = curs_arrow3_data;
- cur_arrow3.mask = curs_arrow3_mask;
- cur_arrow4.data = curs_arrow4_data;
- cur_arrow4.mask = curs_arrow4_mask;
- cur_arrow5.data = curs_arrow5_data;
- cur_arrow5.mask = curs_arrow5_mask;
- cur_arrow6.data = curs_arrow6_data;
- cur_arrow6.mask = curs_arrow6_mask;
-
- cur_root.data = curs_root_data;
- cur_root.mask = curs_root_mask;
-
- cur_plus.data = curs_plus_data;
- cur_plus.mask = curs_plus_mask;
-
- cur_fleur.data = curs_fleur_data;
- cur_fleur.mask = curs_fleur_mask;
-
- cur_xterm.data = curs_xterm_data;
- cur_xterm.mask = curs_xterm_mask;
-
- curs_copy(cursors[CURS_EMPTY], &cur_empty); n++;
- curs_copy(cursors[CURS_DOT], &cur_dot); n++;
-
- if (alt_arrow < 1 || alt_arrow > alt_arrow_max) {
- alt_arrow = 1;
- }
- if (alt_arrow == 1) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow); n++;
- } else if (alt_arrow == 2) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow2); n++;
- } else if (alt_arrow == 3) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow3); n++;
- } else if (alt_arrow == 4) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow4); n++;
- } else if (alt_arrow == 5) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow5); n++;
- } else if (alt_arrow == 6) {
- curs_copy(cursors[CURS_ARROW], &cur_arrow6); n++;
- } else {
- alt_arrow = 1;
- curs_copy(cursors[CURS_ARROW], &cur_arrow); n++;
- }
- curs_copy(cursors[CURS_WARROW], &cur_arrow2); n++;
-
- curs_copy(cursors[CURS_ROOT], &cur_root); n++;
- curs_copy(cursors[CURS_WM], &cur_fleur); n++;
- curs_copy(cursors[CURS_TERM], &cur_xterm); n++;
- curs_copy(cursors[CURS_PLUS], &cur_plus); n++;
-
- if (scale_cursor_str) {
- scale = scale_cursor_str;
- } else if (scaling && scale_str) {
- scale = scale_str;
- }
- if (scale && sscanf(scale, "%dx%d", &i, &j) == 2) {
- if (wdpy_x > 0) {
- w_in = wdpy_x;
- h_in = wdpy_y;
- } else {
- w_in = dpy_x;
- h_in = dpy_y;
- }
- }
-
- /* scale = NULL zeroes everything */
- parse_scale_string(scale, &scale_cursor_fac_x, &scale_cursor_fac_y, &scaling_cursor,
- &scaling_cursor_blend, &j, &j, &scaling_cursor_interpolate,
- &scale_cursor_numer, &scale_cursor_denom, w_in, h_in);
-
- for (i=0; i<n; i++) {
- /* create rfbCursors for the special cursors: */
-
- cursor_info_t *ci = cursors[i];
-
- if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
- int w, h, x, y, k;
- unsigned long *pixels;
-
- w = ci->wx;
- h = ci->wy;
-
- pixels = (unsigned long *) malloc(w * h
- * sizeof(unsigned long));
-
- k = 0;
- for (y=0; y<h; y++) {
- for (x=0; x<w; x++) {
- char d = ci->data[k];
- char m = ci->mask[k];
- unsigned long *p;
-
- p = pixels + k;
-
- /* set alpha on */
- *p = 0xff000000;
-
- if (d == ' ' && m == ' ') {
- /* alpha off */
- *p = 0x00000000;
- } else if (d != ' ') {
- /* body */
- if (ci->reverse) {
- *p |= 0x00000000;
- } else {
- *p |= 0x00ffffff;
- }
- } else if (m != ' ') {
- /* edge */
- if (ci->reverse) {
- *p |= 0x00ffffff;
- } else {
- *p |= 0x00000000;
- }
- }
- k++;
- }
- }
-
- rfb_curs = pixels2curs(pixels, w, h, ci->sx, ci->sy,
- bpp/8);
-
- free(pixels);
-
- } else {
-
- /* standard X cursor */
- rfb_curs = rfbMakeXCursor(ci->wx, ci->wy,
- ci->data, ci->mask);
-
- if (ci->reverse) {
- rfb_curs->foreRed = 0x0000;
- rfb_curs->foreGreen = 0x0000;
- rfb_curs->foreBlue = 0x0000;
- rfb_curs->backRed = 0xffff;
- rfb_curs->backGreen = 0xffff;
- rfb_curs->backBlue = 0xffff;
- }
- rfb_curs->alphaSource = NULL;
-
- rfb_curs->xhot = ci->sx;
- rfb_curs->yhot = ci->sy;
- rfb_curs->cleanup = FALSE;
- rfb_curs->cleanupSource = FALSE;
- rfb_curs->cleanupMask = FALSE;
- rfb_curs->cleanupRichSource = FALSE;
-
- if (bpp == 8 && indexed_color) {
- /*
- * use richsource in PseudoColor for better
- * looking cursors (i.e. two-color).
- */
- int x, y, k = 0, bw;
- int black = 0, white = 1;
- char d, m;
-
- if (dpy) { /* raw_fb hack */
- black = BlackPixel(dpy, scr);
- white = WhitePixel(dpy, scr);
- }
-
- rfb_curs->richSource = (unsigned char *)
- calloc(ci->wx * ci->wy, 1);
-
- for (y = 0; y < ci->wy; y++) {
- for (x = 0; x < ci->wx; x++) {
- d = *(ci->data + k);
- m = *(ci->mask + k);
- if (d == ' ' && m == ' ') {
- k++;
- continue;
- } else if (m != ' ' && d == ' ') {
- bw = black;
- } else {
- bw = white;
- }
- if (ci->reverse) {
- if (bw == black) {
- bw = white;
- } else {
- bw = black;
- }
- }
- *(rfb_curs->richSource+k) =
- (unsigned char) bw;
- k++;
- }
- }
- }
- }
- ci->rfb = rfb_curs;
- }
- if (screen) {
- UNLOCK(screen->cursorMutex);
- }
- if (verbose) {
- rfbLog(" done.\n");
- }
- rfbLog("\n");
-}
-
-void setup_cursors_and_push(void) {
- setup_cursors();
- first_cursor();
-}
-
-/*
- * Descends window tree at pointer until the window cursor matches the current
- * cursor. So far only used to detect if mouse is on root background or not.
- * (returns 0 in that case, 1 otherwise).
- *
- */
-static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!depth || !w || !winfo) {}
- return;
-#else
- Window r, c;
- int i, rx, ry, wx, wy;
- unsigned int mask;
- Window wins[10];
- int descend, maxtries = 10;
- char *name, *s = multiple_cursors_mode;
- static XClassHint *classhint = NULL;
- int nm_info = 1;
- XErrorHandler old_handler;
-
- RAWFB_RET_VOID
-
- if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
- nm_info = 0;
- }
-
- *(winfo->wm_name) = '\0';
- *(winfo->res_name) = '\0';
- *(winfo->res_class) = '\0';
-
- for (i=0; i < maxtries; i++) {
- wins[i] = None;
- }
-
- /* some times a window can go away before we get to it */
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
-
- c = window;
- descend = -1;
-
- while (c) {
- wins[++descend] = c;
- if (descend >= maxtries - 1) {
- break;
- }
- if ( XTestCompareCurrentCursorWithWindow_wr(dpy, c) ) {
- break;
- }
- /* TBD: query_pointer() */
- XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
- }
-
- if (nm_info) {
- int got_wm_name = 0, got_res_name = 0, got_res_class = 0;
-
- if (! classhint) {
- classhint = XAllocClassHint();
- }
-
- for (i = descend; i >=0; i--) {
- c = wins[i];
- if (! c) {
- continue;
- }
-
- if (! got_wm_name && XFetchName(dpy, c, &name)) {
- if (name) {
- if (*name != '\0') {
- strcpy(winfo->wm_name, name);
- got_wm_name = 1;
- }
- XFree_wr(name);
- }
- }
- if (classhint && (! got_res_name || ! got_res_class)) {
- if (XGetClassHint(dpy, c, classhint)) {
- char *p;
- p = classhint->res_name;
- if (p) {
- if (*p != '\0' && ! got_res_name) {
- strcpy(winfo->res_name, p);
- got_res_name = 1;
- }
- XFree_wr(p);
- classhint->res_name = NULL;
- }
- p = classhint->res_class;
- if (p) {
- if (*p != '\0' && ! got_res_class) {
- strcpy(winfo->res_class, p);
- got_res_class = 1;
- }
- XFree_wr(p);
- classhint->res_class = NULL;
- }
- }
- }
- }
- }
-
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
-
- *depth = descend;
- *w = wins[descend];
-#endif /* NO_X11 */
-}
-
-void initialize_xfixes(void) {
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- if (xfixes_present) {
- X_LOCK;
- if (use_xfixes) {
- XFixesSelectCursorInput(dpy, rootwin,
- XFixesDisplayCursorNotifyMask);
- } else {
- XFixesSelectCursorInput(dpy, rootwin, 0);
- }
- X_UNLOCK;
- xfixes_first_initialized = 1;
- }
-#endif
-}
-
-static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
- int xhot, int yhot, int Bpp) {
- rfbCursorPtr c;
- static unsigned long black = 0, white = 1;
- static int first = 1;
- char *bitmap, *rich, *alpha;
- char *pixels_new = NULL;
- int n_opaque, n_trans, n_alpha, len, histo[256];
- int send_alpha = 0, alpha_shift = 0, thresh;
- int i, x, y;
-
- if (first && dpy) { /* raw_fb hack */
- X_LOCK;
- black = BlackPixel(dpy, scr);
- white = WhitePixel(dpy, scr);
- X_UNLOCK;
- first = 0;
- }
-
- if (cmap8to24 && cmap8to24_fb && depth <= 16) {
- if (Bpp <= 2) {
- Bpp = 4;
- }
- }
-
- if (scaling_cursor && (scale_cursor_fac_x != 1.0 || scale_cursor_fac_y != 1.0)) {
- int W, H;
- char *pixels_use = (char *) pixels;
- unsigned int *pixels32 = NULL;
-
- W = w;
- H = h;
-
- w = scale_round(W, scale_cursor_fac_x);
- h = scale_round(H, scale_cursor_fac_y);
-
- pixels_new = (char *) malloc(4*w*h);
-
- if (sizeof(unsigned long) == 8) {
- int i, j, k = 0;
- /*
- * to avoid 64bpp code in scale_rect() we knock
- * down to unsigned int on 64bit machines:
- */
- pixels32 = (unsigned int*) malloc(4*W*H);
- for (j=0; j<H; j++) {
- for (i=0; i<W; i++) {
- *(pixels32+k) = 0xffffffff & (*(pixels+k));
- k++;
- }
- }
- pixels_use = (char *) pixels32;
- }
-
- scale_rect(scale_cursor_fac_x, scale_cursor_fac_y, scaling_cursor_blend,
- scaling_cursor_interpolate,
- 4, pixels_use, 4*W, pixels_new, 4*w,
- W, H, w, h, 0, 0, W, H, 0);
-
- if (sizeof(unsigned long) == 8) {
- int i, j, k = 0;
- unsigned long *pixels64;
- unsigned int* source = (unsigned int*) pixels_new;
- /*
- * now knock it back up to unsigned long:
- */
- pixels64 = (unsigned long*) malloc(8*w*h);
- for (j=0; j<h; j++) {
- for (i=0; i<w; i++) {
- *(pixels64+k) = (unsigned long) (*(source+k));
- k++;
- }
- }
- free(pixels_new);
- pixels_new = (char *) pixels64;
- if (pixels32) {
- free(pixels32);
- pixels32 = NULL;
- }
- }
-
- pixels = (unsigned long *) pixels_new;
-
- xhot = scale_round(xhot, scale_cursor_fac_x);
- yhot = scale_round(yhot, scale_cursor_fac_y);
- }
-
- len = w * h;
- /* for bitmap data */
- bitmap = (char *) malloc(len+1);
- bitmap[len] = '\0';
-
- /* for rich cursor pixel data */
- rich = (char *)calloc(Bpp*len, 1);
- alpha = (char *)calloc(1*len, 1);
-
- n_opaque = 0;
- n_trans = 0;
- n_alpha = 0;
- for (i=0; i<256; i++) {
- histo[i] = 0;
- }
-
- i = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- unsigned long a;
-
- a = 0xff000000 & (*(pixels+i));
- a = a >> 24; /* alpha channel */
- if (a > 0) {
- n_alpha++;
- }
- histo[a]++;
- if (a < (unsigned int) alpha_threshold) {
- n_trans++;
- } else {
- n_opaque++;
- }
- i++;
- }
- }
- if (alpha_blend) {
- send_alpha = 0;
- if (Bpp == 4) {
- send_alpha = 1;
- }
- alpha_shift = 24;
- if (main_red_shift == 24 || main_green_shift == 24 ||
- main_blue_shift == 24) {
- alpha_shift = 0; /* XXX correct? */
- }
- }
- if (n_opaque >= alpha_frac * n_alpha) {
- thresh = alpha_threshold;
- } else {
- n_opaque = 0;
- for (i=255; i>=0; i--) {
- n_opaque += histo[i];
- thresh = i;
- if (n_opaque >= alpha_frac * n_alpha) {
- break;
- }
- }
- }
-
- i = 0;
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- unsigned long r, g, b, a;
- unsigned int ui;
- char *p;
-
- a = 0xff000000 & (*(pixels+i));
- a = a >> 24; /* alpha channel */
-
- if (a < (unsigned int) thresh) {
- bitmap[i] = ' ';
- } else {
- bitmap[i] = 'x';
- }
-
- r = 0x00ff0000 & (*(pixels+i));
- g = 0x0000ff00 & (*(pixels+i));
- b = 0x000000ff & (*(pixels+i));
- r = r >> 16; /* red */
- g = g >> 8; /* green */
- b = b >> 0; /* blue */
-
- if (alpha_remove && a != 0) {
- r = (255 * r) / a;
- g = (255 * g) / a;
- b = (255 * b) / a;
- if (r > 255) r = 255;
- if (g > 255) g = 255;
- if (b > 255) b = 255;
- }
-
- if (indexed_color) {
- /*
- * Choose black or white for
- * PseudoColor case.
- */
- int value = (r+g+b)/3;
- if (value > 127) {
- ui = white;
- } else {
- ui = black;
- }
- } else {
- /*
- * Otherwise map the RGB data onto
- * the framebuffer format:
- */
- r = (main_red_max * r)/255;
- g = (main_green_max * g)/255;
- b = (main_blue_max * b)/255;
- ui = 0;
- ui |= (r << main_red_shift);
- ui |= (g << main_green_shift);
- ui |= (b << main_blue_shift);
- if (send_alpha) {
- ui |= (a << alpha_shift);
- }
- }
-
- /* insert value into rich source: */
- p = rich + Bpp*i;
-
- if (Bpp == 1) {
- *((unsigned char *)p)
- = (unsigned char) ui;
- } else if (Bpp == 2) {
- *((unsigned short *)p)
- = (unsigned short) ui;
- } else if (Bpp == 3) {
- *((unsigned char *)p)
- = (unsigned char) ((ui & 0x0000ff) >> 0);
- *((unsigned char *)(p+1))
- = (unsigned char) ((ui & 0x00ff00) >> 8);
- *((unsigned char *)(p+2))
- = (unsigned char) ((ui & 0xff0000) >> 16);
- } else if (Bpp == 4) {
- *((unsigned int *)p)
- = (unsigned int) ui;
- }
-
- /* insert alpha value into alpha source: */
- p = alpha + i;
- *((unsigned char *)p) = (unsigned char) a;
-
- i++;
- }
- }
-
- /* create the cursor with the bitmap: */
- c = rfbMakeXCursor(w, h, bitmap, bitmap);
- free(bitmap);
-
- if (pixels_new) {
- free(pixels_new);
- }
-
- /* set up the cursor parameters: */
- c->xhot = xhot;
- c->yhot = yhot;
- c->cleanup = FALSE;
- c->cleanupSource = FALSE;
- c->cleanupMask = FALSE;
- c->cleanupRichSource = FALSE;
- c->richSource = (unsigned char *) rich;
-
- /* zeroes mean interpolate the rich cursor somehow and use B+W */
- c->foreRed = 0;
- c->foreGreen = 0;
- c->foreBlue = 0;
- c->backRed = 0;
- c->backGreen = 0;
- c->backBlue = 0;
-
- c->source = NULL;
-
- if (alpha_blend && !indexed_color) {
- c->alphaSource = (unsigned char *) alpha;
- c->alphaPreMultiplied = TRUE;
- } else {
- free(alpha);
- c->alphaSource = NULL;
- }
- return c;
-}
-
-static unsigned long last_cursor = 0;
-static int last_index = 0;
-static time_t curs_times[CURS_MAX];
-static unsigned long curs_index[CURS_MAX];
-
-unsigned long get_cursor_serial(int mode) {
- if (mode == 0) {
- return last_cursor;
- } else if (mode == 1) {
- return (unsigned long) last_index;
- } else {
- return (unsigned long) last_index;
- }
-}
-
-static int get_exact_cursor(int init) {
- int which = CURS_ARROW;
-
- if (init) {
- /* zero out our cache (cursors are not freed) */
- int i;
- for (i=0; i<CURS_MAX; i++) {
- curs_times[i] = 0;
- curs_index[i] = 0;
- }
- last_cursor = 0;
- last_index = 0;
- return -1;
- }
-
-#ifdef MACOSX
- if (macosx_console) {
- return macosx_get_cursor();
- }
-#endif
-
- if (rawfb_vnc_reflect) {
- int last_idx = (int) get_cursor_serial(1);
- if (last_idx) {
- which = last_idx;
- }
- return which;
- }
- if (xfixes_present && dpy) {
-#if LIBVNCSERVER_HAVE_LIBXFIXES
- int last_idx = (int) get_cursor_serial(1);
- XFixesCursorImage *xfc;
-
- if (last_idx) {
- which = last_idx;
- }
- if (! xfixes_first_initialized) {
- return which;
- }
-
- X_LOCK;
- if (! got_xfixes_cursor_notify && xfixes_base_event_type) {
- /* try again for XFixesCursorNotify event */
- XEvent xev;
- if (XCheckTypedEvent(dpy, xfixes_base_event_type +
- XFixesCursorNotify, &xev)) {
- got_xfixes_cursor_notify++;
- }
- }
- if (! got_xfixes_cursor_notify) {
- /* evidently no cursor change, just return last one */
- X_UNLOCK;
- return which;
- }
- got_xfixes_cursor_notify = 0;
-
- /* retrieve the cursor info + pixels from server: */
- xfc = XFixesGetCursorImage(dpy);
- X_UNLOCK;
- if (! xfc) {
- /* failure. */
- return which;
- }
-
- which = store_cursor(xfc->cursor_serial, xfc->pixels,
- xfc->width, xfc->height, 32, xfc->xhot, xfc->yhot);
-
- X_LOCK;
- XFree_wr(xfc);
- X_UNLOCK;
-#endif
- }
- return(which);
-}
-
-int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp,
- int xhot, int yhot) {
- int which = CURS_ARROW;
- int use, oldest, i;
- time_t oldtime, now;
-
-#if 0
-fprintf(stderr, "sc: %d %d/%d %d - %d %d\n", serial, w, h, cbpp, xhot, yhot);
-#endif
-
- oldest = CURS_DYN_MIN;
- if (screen && screen->cursor == cursors[oldest]->rfb) {
- oldest++;
- }
- oldtime = curs_times[oldest];
- now = time(NULL);
- for (i = CURS_DYN_MIN; i <= CURS_DYN_MAX; i++) {
- if (screen && screen->cursor == cursors[i]->rfb) {
- ;
- } else if (curs_times[i] < oldtime) {
- /* watch for oldest one to overwrite */
- oldest = i;
- oldtime = curs_times[i];
- }
- if (serial == (int) curs_index[i]) {
- /*
- * got a hit with an existing cursor,
- * use that one.
- */
-#ifdef MACOSX
- if (now > curs_times[i] + 1) {
- continue;
- }
-#endif
- last_cursor = curs_index[i];
- curs_times[i] = now;
- last_index = i;
- return last_index;
- }
- }
-
- /* we need to create the cursor and overwrite oldest */
- use = oldest;
- if (cursors[use]->rfb) {
- /* clean up oldest if it exists */
- if (cursors[use]->rfb->richSource) {
- free(cursors[use]->rfb->richSource);
- cursors[use]->rfb->richSource = NULL;
- }
- if (cursors[use]->rfb->alphaSource) {
- free(cursors[use]->rfb->alphaSource);
- cursors[use]->rfb->alphaSource = NULL;
- }
- if (cursors[use]->rfb->source) {
- free(cursors[use]->rfb->source);
- cursors[use]->rfb->source = NULL;
- }
- if (cursors[use]->rfb->mask) {
- free(cursors[use]->rfb->mask);
- cursors[use]->rfb->mask = NULL;
- }
- free(cursors[use]->rfb);
- cursors[use]->rfb = NULL;
- }
-
- if (rotating && rotating_cursors) {
- char *dst;
- int tx, ty;
-
- dst = (char *) malloc(w * h * cbpp/8);
- rotate_curs(dst, (char *) data, w, h, cbpp/8);
-
- memcpy(data, dst, w * h * cbpp/8);
- free(dst);
-
- rotate_coords(xhot, yhot, &tx, &ty, w, h);
- xhot = tx;
- yhot = ty;
- if (! rotating_same) {
- int tmp = w;
- w = h;
- h = tmp;
- }
- }
-
- /* place cursor into our collection */
- cursors[use]->rfb = pixels2curs(data, w, h, xhot, yhot, bpp/8);
-
- /* update time and serial index: */
- curs_times[use] = now;
- curs_index[use] = serial;
- last_index = use;
- last_cursor = serial;
-
- which = last_index;
-
- return which;
-}
-
-int known_cursors_mode(char *s) {
-/*
- * default: see initialize_cursors_mode() for default behavior.
- * arrow: unchanging white arrow.
- * Xn*: show X on root background. Optional n sets treedepth.
- * some: do the heuristics for root, wm, term detection.
- * most: if display have overlay or xfixes, show all cursors,
- * otherwise do the same as "some"
- * none: show no cursor.
- */
- if (strcmp(s, "default") && strcmp(s, "arrow") && *s != 'X' &&
- strcmp(s, "some") && strcmp(s, "most") && strcmp(s, "none")) {
- return 0;
- } else {
- return 1;
- }
-}
-
-void initialize_cursors_mode(void) {
- char *s = multiple_cursors_mode;
- if (!s || !known_cursors_mode(s)) {
- rfbLog("unknown cursors mode: %s\n", s);
- rfbLog("resetting cursors mode to \"default\"\n");
- if (multiple_cursors_mode) free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("default");
- s = multiple_cursors_mode;
- }
- if (!strcmp(s, "none")) {
- show_cursor = 0;
- } else {
- /* we do NOT set show_cursor = 1, let the caller do that */
- }
-
- show_multiple_cursors = 0;
- if (show_cursor) {
- if (!strcmp(s, "default")) {
- if(multiple_cursors_mode) free(multiple_cursors_mode);
- multiple_cursors_mode = strdup("X");
- s = multiple_cursors_mode;
- }
- if (*s == 'X' || !strcmp(s, "some") || !strcmp(s, "most")) {
- show_multiple_cursors = 1;
- } else {
- show_multiple_cursors = 0;
- /* hmmm, some bug going back to arrow mode.. */
- set_rfb_cursor(CURS_ARROW);
- }
- if (screen) {
- set_cursor_was_changed(screen);
- }
- } else {
- if (screen) {
- LOCK(screen->cursorMutex);
- screen->cursor = NULL;
- UNLOCK(screen->cursorMutex);
- set_cursor_was_changed(screen);
- }
- }
-}
-
-int get_which_cursor(void) {
- int which = CURS_ARROW;
- int db = 0;
-
- if (show_multiple_cursors) {
- int depth = 0, rint;
- static win_str_info_t winfo;
- static int first = 1, depth_cutoff = -1;
- Window win = None;
- XErrorHandler old_handler;
- int mode = 0;
-
- if (drag_in_progress || button_mask) {
- /* XXX not exactly what we want for menus */
- if (! cursor_drag_changes) {
- return -1;
- }
- }
-
- if (!strcmp(multiple_cursors_mode, "arrow")) {
- /* should not happen... */
- return CURS_ARROW;
- } else if (!strcmp(multiple_cursors_mode, "default")) {
- mode = 0;
- } else if (!strcmp(multiple_cursors_mode, "X")) {
- mode = 1;
- } else if (!strcmp(multiple_cursors_mode, "some")) {
- mode = 2;
- } else if (!strcmp(multiple_cursors_mode, "most")) {
- mode = 3;
- }
-
- if (rawfb_vnc_reflect && mode > -1) {
- rint = get_exact_cursor(0);
- return rint;
- }
- if (mode == 3) {
- if ((xfixes_present && use_xfixes) || macosx_console) {
- if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
- rint = get_exact_cursor(0);
- return rint;
- }
- }
-
- if (depth_cutoff < 0) {
- int din;
- if (sscanf(multiple_cursors_mode, "X%d", &din) == 1) {
- depth_cutoff = din;
- } else {
- depth_cutoff = 0;
- }
- }
-
- if (first) {
- winfo.wm_name = (char *) malloc(1024);
- winfo.res_name = (char *) malloc(1024);
- winfo.res_class = (char *) malloc(1024);
- }
- first = 0;
-
- X_LOCK;
- tree_descend_cursor(&depth, &win, &winfo);
- X_UNLOCK;
-
- if (depth <= depth_cutoff && !subwin) {
- which = CURS_ROOT;
-
- } else if (mode == 2 || mode == 3) {
- int which0 = which;
-
- /* apply crude heuristics to choose a cursor... */
- if (win && dpy) {
- int ratio = 10, x, y;
- unsigned int w, h, bw, d;
- Window r;
-
-#if !NO_X11
- trapped_xerror = 0;
- X_LOCK;
- old_handler = XSetErrorHandler(trap_xerror);
-
- /* "narrow" windows are WM */
- if (XGetGeometry(dpy, win, &r, &x, &y, &w, &h,
- &bw, &d)) {
- if (w > ratio * h || h > ratio * w) {
- which = CURS_WM;
- }
- }
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- trapped_xerror = 0;
-#else
- if (!r || !d || !bw || !h || !w || !y || !x || !ratio || !old_handler) {}
-#endif /* NO_X11 */
- }
- if (which == which0) {
- /* the string "term" means I-beam. */
- char *name, *class;
- lowercase(winfo.res_name);
- lowercase(winfo.res_class);
- name = winfo.res_name;
- class = winfo.res_class;
- if (strstr(name, "term")) {
- which = CURS_TERM;
- } else if (strstr(class, "term")) {
- which = CURS_TERM;
- } else if (strstr(name, "text")) {
- which = CURS_TERM;
- } else if (strstr(class, "text")) {
- which = CURS_TERM;
- } else if (strstr(name, "onsole")) {
- which = CURS_TERM;
- } else if (strstr(class, "onsole")) {
- which = CURS_TERM;
- } else if (strstr(name, "cmdtool")) {
- which = CURS_TERM;
- } else if (strstr(class, "cmdtool")) {
- which = CURS_TERM;
- } else if (strstr(name, "shelltool")) {
- which = CURS_TERM;
- } else if (strstr(class, "shelltool")) {
- which = CURS_TERM;
- }
- }
- }
- }
- if (db) fprintf(stderr, "get_which_cursor which: %d\n", which);
- return which;
-}
-
-static void set_cursor_was_changed(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (! s) {
- return;
- }
- iter = rfbGetClientIterator(s);
- LOCK(screen->cursorMutex);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- cl->cursorWasChanged = TRUE;
- }
- UNLOCK(screen->cursorMutex);
- rfbReleaseClientIterator(iter);
-}
-
-#if 0
-/* not yet used */
-static void set_cursor_was_moved(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
-
- if (! s) {
- return;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- cl->cursorWasMoved = TRUE;
- }
- rfbReleaseClientIterator(iter);
-}
-#endif
-
-void restore_cursor_shape_updates(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s || ! s->clientHead) {
- return;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- int changed = 0;
- ClientData *cd = (ClientData *) cl->clientData;
-
- if (! cd) {
- continue;
- }
- if (cd->had_cursor_shape_updates) {
- rfbLog("restoring enableCursorShapeUpdates for client"
- " 0x%x\n", cl);
- cl->enableCursorShapeUpdates = TRUE;
- changed = 1;
- }
- if (cd->had_cursor_pos_updates) {
- rfbLog("restoring enableCursorPosUpdates for client"
- " 0x%x\n", cl);
- cl->enableCursorPosUpdates = TRUE;
- changed = 1;
- }
- if (changed) {
- cl->cursorWasChanged = TRUE;
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
-}
-
-void disable_cursor_shape_updates(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- static int changed = 0;
- int count = 0;
-
- if (! s || ! s->clientHead) {
- return;
- }
- if (unixpw_in_progress) return;
-
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- ClientData *cd;
- cd = (ClientData *) cl->clientData;
-
- if (cl->enableCursorShapeUpdates) {
- if (cd) {
- cd->had_cursor_shape_updates = 1;
- }
- count++;
- if (debug_pointer) {
- rfbLog("%s disable HCSU\n", cl->host);
- }
- }
- if (cl->enableCursorPosUpdates) {
- if (cd) {
- cd->had_cursor_pos_updates = 1;
- }
- count++;
- if (debug_pointer) {
- rfbLog("%s disable HCPU\n", cl->host);
- }
- }
-
- cl->enableCursorShapeUpdates = FALSE;
- cl->enableCursorPosUpdates = FALSE;
- cl->cursorWasChanged = FALSE;
- }
- rfbReleaseClientIterator(iter);
-
- if (count) {
- changed = 1;
- }
-}
-
-int cursor_shape_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->enableCursorShapeUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-int cursor_noshape_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (!cl->enableCursorShapeUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-int cursor_pos_updates_clients(rfbScreenInfoPtr s) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int count = 0;
-
- if (! s) {
- return 0;
- }
- iter = rfbGetClientIterator(s);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (cl->enableCursorPosUpdates) {
- count++;
- }
- }
- rfbReleaseClientIterator(iter);
- return count;
-}
-
-/*
- * Record rfb cursor position screen->cursorX, etc (a la defaultPtrAddEvent())
- * Then set up for sending rfbCursorPosUpdates back
- * to clients that understand them. This seems to be TightVNC specific.
- */
-void cursor_position(int x, int y) {
- rfbClientIteratorPtr iter;
- rfbClientPtr cl;
- int cnt = 0, nonCursorPosUpdates_clients = 0;
- int x_in = x, y_in = y;
-
- /* x and y are current positions of X11 pointer on the X11 display */
- if (!screen) {
- return;
- }
-
- if (scaling) {
- x = ((double) x / dpy_x) * scaled_x;
- x = nfix(x, scaled_x);
- y = ((double) y / dpy_y) * scaled_y;
- y = nfix(y, scaled_y);
- }
-
- if (clipshift) {
- if (x < 0) x = 0;
- if (y < 0) y = 0;
- if (x >= dpy_x) x = dpy_x-1;
- if (y >= dpy_y) y = dpy_y-1;
- }
-
- if (x == screen->cursorX && y == screen->cursorY) {
- return;
- }
-
- LOCK(screen->cursorMutex);
- screen->cursorX = x;
- screen->cursorY = y;
- UNLOCK(screen->cursorMutex);
-
- iter = rfbGetClientIterator(screen);
- while( (cl = rfbClientIteratorNext(iter)) ) {
- if (! cl->enableCursorPosUpdates) {
- nonCursorPosUpdates_clients++;
- continue;
- }
- if (! cursor_pos_updates) {
- continue;
- }
- if (cl == last_pointer_client) {
- /*
- * special case if this client was the last one to
- * send a pointer position.
- */
- if (x_in == cursor_x && y_in == cursor_y) {
- cl->cursorWasMoved = FALSE;
- } else {
- /* an X11 app evidently warped the pointer */
- if (debug_pointer) {
- rfbLog("cursor_position: warp "
- "detected dx=%3d dy=%3d\n",
- cursor_x - x, cursor_y - y);
- }
- cl->cursorWasMoved = TRUE;
- cnt++;
- }
- } else {
- cl->cursorWasMoved = TRUE;
- cnt++;
- }
- }
- rfbReleaseClientIterator(iter);
-
- if (debug_pointer && cnt) {
- rfbLog("cursor_position: sent position x=%3d y=%3d to %d"
- " clients\n", x, y, cnt);
- }
-}
-
-static void set_rfb_cursor(int which) {
-
- if (! show_cursor) {
- return;
- }
- if (! screen) {
- return;
- }
-
- if (!cursors[which] || !cursors[which]->rfb) {
- rfbLog("non-existent cursor: which=%d\n", which);
- return;
- } else {
- rfbSetCursor(screen, cursors[which]->rfb);
- }
-}
-
-void set_no_cursor(void) {
- set_rfb_cursor(CURS_EMPTY);
-}
-
-void set_warrow_cursor(void) {
- set_rfb_cursor(CURS_WARROW);
-}
-
-int set_cursor(int x, int y, int which) {
- static int last = -1;
- int changed_cursor = 0;
-
- if (x || y) {} /* unused vars warning: */
-
- if (which < 0) {
- which = last;
- }
- if (last < 0 || which != last) {
- set_rfb_cursor(which);
- changed_cursor = 1;
- }
- last = which;
-
- return changed_cursor;
-}
-
-/*
- * routine called periodically to update cursor aspects, this catches
- * warps and cursor shape changes.
- */
-int check_x11_pointer(void) {
- Window root_w, child_w;
- rfbBool ret = 0;
- int root_x, root_y, win_x, win_y;
- int x, y, rint;
- unsigned int mask;
-
- if (unixpw_in_progress) return 0;
-
-#ifdef MACOSX
- if (macosx_console) {
- ret = macosx_get_cursor_pos(&root_x, &root_y);
- } else {
- RAWFB_RET(0)
- }
-#else
-
- RAWFB_RET(0)
-
-# if NO_X11
- return 0;
-# endif
-
-#endif
-
-
-#if ! NO_X11
- if (dpy) {
- X_LOCK;
- ret = XQueryPointer_wr(dpy, rootwin, &root_w, &child_w, &root_x, &root_y,
- &win_x, &win_y, &mask);
- X_UNLOCK;
- }
-#else
- if (!mask || !win_y || !win_x || !child_w || !root_w) {}
-#endif /* NO_X11 */
-
-if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
- if (! ret) {
- return 0;
- }
- if (debug_pointer) {
- static int last_x = -1, last_y = -1;
- if (root_x != last_x || root_y != last_y) {
- rfbLog("XQueryPointer: x:%4d, y:%4d)\n",
- root_x, root_y);
- }
- last_x = root_x;
- last_y = root_y;
- }
-
- /* offset subtracted since XQueryPointer relative to rootwin */
- x = root_x - off_x - coff_x;
- y = root_y - off_y - coff_y;
-
- if (clipshift) {
- static int cnt = 0;
- if (x < 0 || y < 0 || x >= dpy_x || y >= dpy_y) {
- if (cnt++ % 4 != 0) {
- if (debug_pointer) {
- rfbLog("Skipping cursor_position() outside our clipshift\n");
- }
- return 0;
- }
- }
- }
-
- /* record the cursor position in the rfb screen */
- cursor_position(x, y);
-
- /* change the cursor shape if necessary */
- rint = set_cursor(x, y, get_which_cursor());
- return rint;
-}
-
OpenPOWER on IntegriCloud