x11vnc: Native Mac OS X support.

pull/1/head
runge 18 years ago
parent 5f9693d4a2
commit 4a83f87609

@ -1,3 +1,7 @@
2006-11-13 Karl Runge <runge@karlrunge.com>
* configure.ac: x11vnc warnings for no XTEST or SSL.
* prepare_x11vnc_dist.sh: to 0.8.4
2006-11-07 Karl Runge <runge@karlrunge.com>
* configure.ac: clean up -R linker case, add --without-macosx-native
* prepare_x11vnc_dist.sh: have "make rpm" work properly for

@ -126,7 +126,7 @@ elif test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(Xtst, XTestFakeKeyEvent,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_XTEST)], ,
[AC_DEFINE(HAVE_XTEST) HAVE_XTEST="true"], ,
$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS)
if test "x$with_xrecord" != "xno"; then
@ -216,6 +216,24 @@ and --x-libraries=DIR configure options or set the CPPFLAGS and LDFLAGS
environment variables to indicate where the X window system header files
and libraries may be found. On 64+32 bit machines you may need to point
to lib64 or lib32 directories to pick up the correct word size.
If you want to build x11vnc without X support (e.g. for -rawfb use only
or for native Mac OS X), specify the --without-x configure option.
==========================================================================
])
fi
if test "$PACKAGE_NAME" = "x11vnc" -a "x$HAVE_X" = "xtrue" -a "x$HAVE_XTEST" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
A working build environment for the XTEST extension was not found (libXtst).
An x11vnc built this way will be only barely usable. You will be able to
move the mouse but not click or type. There can also be deadlocks if an
application grabs the X server.
It is recommended that you install the necessary development packages
for XTEST (perhaps it is named something like libxtst-dev) and run
configure again.
==========================================================================
])
fi
@ -261,6 +279,19 @@ if test "x$with_ssl" != "xno"; then
fi
AC_SUBST(SSL_LIBS)
if test "$PACKAGE_NAME" = "x11vnc"; then
if test "x$HAVE_LIBSSL" != "xtrue"; then
AC_MSG_WARN([
==========================================================================
The openssl encryption library libssl.so was not found. An x11vnc built
this way will not support SSL encryption. To enable SSL install the
necessary development packages (perhaps it is named something like
libssl-dev) and run configure again.
==========================================================================
])
fi
fi
if test "x$with_v4l" != "xno"; then
AC_CHECK_HEADER(linux/videodev.h,
[AC_DEFINE(HAVE_LINUX_VIDEODEV_H)],,)

@ -1,6 +1,6 @@
#!/bin/bash
VERSION="0.8.3"
VERSION="0.8.4"
cd "$(dirname "$0")"

@ -434,7 +434,7 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list0, &nc0);
rc = XQueryTree_wr(dpy, win, &r, &parent, &list0, &nc0);
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
@ -460,7 +460,7 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win1, &r, &parent, &list1, &nc1);
rc = XQueryTree_wr(dpy, win1, &r, &parent, &list1, &nc1);
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
@ -479,11 +479,11 @@ if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
/* more? Which wm does this? */
}
if (nc1) {
XFree(list1);
XFree_wr(list1);
}
}
if (nc0) {
XFree(list0);
XFree_wr(list0);
}
}
X_UNLOCK;

@ -1,3 +1,6 @@
2006-11-13 Karl Runge <runge@karlrunge.com>
* x11vnc: Native Mac OS X support.
2006-11-07 Karl Runge <runge@karlrunge.com>
* ssl_vncviewer: vnc:// direct connect, add -x to ssh,
SSL_VNC_LISTEN variable for direct proxy.

@ -1,6 +1,11 @@
AM_CFLAGS = -I $(top_srcdir)
LDADD = ../libvncserver/libvncserver.a @WSOCKLIB@
if OSX
x11vnc_LDFLAGS = -framework ApplicationServices -framework Carbon -framework IOKit -framework Cocoa
x11vnc_CFLAGS = -ObjC
endif
SUBDIRS = misc
DIST_SUBDIRS = misc
@ -12,7 +17,7 @@ LD_CYGIPC=-lcygipc
endif
bin_PROGRAMS=x11vnc
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c linuxfb.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c uinput.c unixpw.c user.c userinput.c util.c v4l.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h linuxfb.h nox11.h nox11_funcs.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h uinput.h unixpw.h user.h userinput.h util.h v4l.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c linuxfb.c macosx.c macosxCG.c macosxCGP.c macosxCGS.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c uinput.c unixpw.c user.c userinput.c util.c v4l.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h linuxfb.h macosx.h macosxCG.h macosxCGP.h macosxCGS.h nox11.h nox11_funcs.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h uinput.h unixpw.h user.h userinput.h util.h v4l.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
if HAVE_X
INCLUDES=@X_CFLAGS@
x11vnc_LDADD=$(LDADD) @SSL_LIBS@ @CRYPT_LIBS@ @X_LIBS@ $(LD_CYGIPC)

File diff suppressed because it is too large Load Diff

@ -126,6 +126,18 @@ void clean_up_exit (int ret) {
ssl_helper_pid(0, 0); /* killall */
}
#ifdef MACOSX
if (client_connect_file) {
if (strstr(client_connect_file, "/tmp/x11vnc-macosx-channel.")
== client_connect_file) {
unlink(client_connect_file);
}
}
if (! dpy) {
macosxCG_fini();
}
#endif
if (! dpy) exit(ret); /* raw_rb hack */
/* X keyboard cleanups */

@ -16,6 +16,7 @@
#include "sslhelper.h"
#include "xwrappers.h"
#include "xevents.h"
#include "macosxCG.h"
/*
* routines for handling incoming, outgoing, etc connections
@ -746,6 +747,11 @@ void client_gone(rfbClientPtr client) {
rfbLog("viewer exited.\n");
clean_up_exit(0);
}
#ifdef MACOSX
if (! dpy && client_count == 0) {
macosxCG_refresh_callback_off();
}
#endif
}
/*
@ -1204,7 +1210,7 @@ static unsigned char t2x2_bits[] = {
ret = out;
XSelectInput(dpy, awin, 0);
XUnmapWindow(dpy, awin);
XFreeGC(dpy, gc);
XFree_wr(gc);
XDestroyWindow(dpy, awin);
XFlush_wr(dpy);
break;
@ -1773,13 +1779,13 @@ void read_vnc_connect_prop(int nomsg) {
/* too big */
rfbLog("warning: truncating large VNC_CONNECT"
" string > %d bytes.\n", VNC_CONNECT_MAX);
XFree(data);
XFree_wr(data);
break;
}
memcpy(vnc_connect_str+slen, data, dlen);
slen += dlen;
vnc_connect_str[slen] = '\0';
XFree(data);
XFree_wr(data);
}
} while (bytes_after > 0);
@ -1823,13 +1829,13 @@ void read_x11vnc_remote_prop(int nomsg) {
/* too big */
rfbLog("warning: truncating large X11VNC_REMOTE"
" string > %d bytes.\n", X11VNC_REMOTE_MAX);
XFree(data);
XFree_wr(data);
break;
}
memcpy(x11vnc_remote_str+slen, data, dlen);
slen += dlen;
x11vnc_remote_str[slen] = '\0';
XFree(data);
XFree_wr(data);
}
} while (bytes_after > 0);
@ -2101,6 +2107,11 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
*/
autorepeat(0, 0);
}
#ifdef MACOSX
if (! dpy && client_count == 1) {
macosxCG_refresh_callback_on();
}
#endif
if (use_solid_bg && client_count == 1) {
solid_bg(0);
}

@ -33,6 +33,8 @@ 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 {
@ -57,7 +59,7 @@ 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_xfixes_cursor(int init);
static int get_exact_cursor(int init);
static void set_cursor_was_changed(rfbScreenInfoPtr s);
@ -618,7 +620,7 @@ static void setup_cursors(void) {
}
/* clear any xfixes cursor cache (no freeing is done) */
get_xfixes_cursor(1);
get_exact_cursor(1);
/* manually fill in the data+masks: */
cur_empty.data = curs_empty_data;
@ -876,7 +878,7 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
break;
}
/* TBD: query_pointer() */
XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &mask);
}
if (nm_info) {
@ -898,7 +900,7 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
strcpy(winfo->wm_name, name);
got_wm_name = 1;
}
XFree(name);
XFree_wr(name);
}
}
if (classhint && (! got_res_name || ! got_res_class)) {
@ -910,7 +912,7 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
strcpy(winfo->res_name, p);
got_res_name = 1;
}
XFree(p);
XFree_wr(p);
classhint->res_name = NULL;
}
p = classhint->res_class;
@ -919,7 +921,7 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
strcpy(winfo->res_class, p);
got_res_class = 1;
}
XFree(p);
XFree_wr(p);
classhint->res_class = NULL;
}
}
@ -1215,11 +1217,20 @@ static rfbCursorPtr pixels2curs(unsigned long *pixels, int w, int h,
return c;
}
static int get_xfixes_cursor(int init) {
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];
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;
}
}
static int get_exact_cursor(int init) {
int which = CURS_ARROW;
if (init) {
@ -1234,12 +1245,21 @@ static int get_xfixes_cursor(int init) {
return -1;
}
#ifdef MACOSX
if (! dpy) {
return macosx_get_cursor();
}
#endif
if (xfixes_present && dpy) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
int use, oldest, i;
time_t oldtime, now;
int last_idx = (int) get_cursor_serial(1);
XFixesCursorImage *xfc;
if (last_idx) {
which = last_idx;
}
if (! got_xfixes_cursor_notify && xfixes_base_event_type) {
/* try again for XFixesCursorNotify event */
XEvent xev;
@ -1252,11 +1272,7 @@ static int get_xfixes_cursor(int init) {
}
if (! got_xfixes_cursor_notify) {
/* evidently no cursor change, just return last one */
if (last_index) {
return last_index;
} else {
return CURS_ARROW;
}
return which;
}
got_xfixes_cursor_notify = 0;
@ -1266,113 +1282,112 @@ static int get_xfixes_cursor(int init) {
X_UNLOCK;
if (! xfc) {
/* failure. */
return(which);
return which;
}
if (xfc->cursor_serial == last_cursor) {
/* same serial index: no change */
X_LOCK;
XFree(xfc);
X_UNLOCK;
if (last_index) {
return last_index;
} else {
return CURS_ARROW;
}
}
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;
oldest = CURS_DYN_MIN;
if (screen && screen->cursor == cursors[oldest]->rfb) {
oldest++;
#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];
}
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 (xfc->cursor_serial == curs_index[i]) {
/*
* got a hit with an existing cursor,
* use that one.
*/
last_cursor = curs_index[i];
curs_times[i] = now;
last_index = i;
X_LOCK;
XFree(xfc);
X_UNLOCK;
return last_index;
}
if (serial == curs_index[i]) {
/*
* got a hit with an existing cursor,
* use that one.
*/
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;
/* 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;
int w = xfc->width;
int h = xfc->height;
if (rotating && rotating_cursors) {
char *dst;
int tx, ty;
dst = (char *) malloc(w * h * 4);
rotate_curs(dst, (char *) xfc->pixels, w, h, 4);
dst = (char *) malloc(w * h * cbpp/8);
rotate_curs(dst, (char *) data, w, h, cbpp/8);
memcpy(xfc->pixels, dst, w * h * 4);
free(dst);
memcpy(data, dst, w * h * cbpp/8);
free(dst);
rotate_coords(xfc->xhot, xfc->yhot, &tx, &ty, w, h);
xfc->xhot = tx;
xfc->yhot = ty;
if (! rotating_same) {
xfc->width = h;
xfc->height = w;
}
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(xfc->pixels, xfc->width,
xfc->height, xfc->xhot, xfc->yhot, bpp/8);
/* 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] = xfc->cursor_serial;
last_index = use;
last_cursor = xfc->cursor_serial;
/* update time and serial index: */
curs_times[use] = now;
curs_index[use] = serial;
last_index = use;
last_cursor = serial;
which = last_index;
which = last_index;
X_LOCK;
XFree(xfc);
X_UNLOCK;
#endif
}
return(which);
return which;
}
int known_cursors_mode(char *s) {
@ -1465,9 +1480,15 @@ int get_which_cursor(void) {
mode = 3;
}
if (mode == 3 && xfixes_present && use_xfixes) {
if (db) fprintf(stderr, "get_which_cursor call get_xfixes_cursor\n");
return get_xfixes_cursor(0);
if (mode == 3) {
int try_macosx = 0;
#ifdef MACOSX
if (! dpy) try_macosx = 1;
#endif
if ((xfixes_present && use_xfixes) || try_macosx) {
if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
return get_exact_cursor(0);
}
}
if (depth_cutoff < 0) {
@ -1518,7 +1539,7 @@ int get_which_cursor(void) {
#endif /* NO_X11 */
}
if (which == which0) {
/* the string "term" mean I-beam. */
/* the string "term" means I-beam. */
char *name, *class;
lowercase(winfo.res_name);
lowercase(winfo.res_class);
@ -1821,22 +1842,39 @@ int set_cursor(int x, int y, int which) {
*/
int check_x11_pointer(void) {
Window root_w, child_w;
rfbBool ret;
rfbBool ret = 0;
int root_x, root_y, win_x, win_y;
int x, y;
unsigned int mask;
int macosx_rawfb_ret = 0;
if (unixpw_in_progress) return 0;
#ifdef MACOSX
if (macosx_rawfb_ret) {
RAWFB_RET(0)
}
if (dpy) {
;
} else {
ret = macosx_get_cursor_pos(&root_x, &root_y);
}
#else
RAWFB_RET(0)
#if NO_X11
return 0;
#else
#endif
#endif
if (unixpw_in_progress) return 0;
X_LOCK;
ret = XQueryPointer(dpy, rootwin, &root_w, &child_w, &root_x, &root_y,
&win_x, &win_y, &mask);
X_UNLOCK;
#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;
}
#endif /* NO_X11 */
if (! ret) {
return 0;
@ -1860,6 +1898,5 @@ int check_x11_pointer(void) {
/* change the cursor shape if necessary */
return set_cursor(x, y, get_which_cursor());
#endif /* NO_X11 */
}

@ -30,5 +30,7 @@ extern void set_no_cursor(void);
extern void set_warrow_cursor(void);
extern int set_cursor(int x, int y, int which);
extern int check_x11_pointer(void);
extern int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
extern unsigned long get_cursor_serial(int mode);
#endif /* _X11VNC_CURSOR_H */

@ -60,7 +60,7 @@ static Window tweak_tk_window_id(Window win) {
}
}
if (name != NULL) {
XFree(name);
XFree_wr(name);
}
return new;
#endif /* NO_X11 */
@ -256,6 +256,9 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
if (! dpy) {
rfbLog("gui: could not open x11vnc "
"display: %s\n", NONUL(x11vnc_xdisplay));
#ifdef MACOSX
goto macjump;
#endif
exit(1);
}
scr = DefaultScreen(dpy);
@ -263,6 +266,8 @@ if (0) fprintf(stderr, "run_gui: %s -- %d %d\n", gui_xdisplay, connect_to_x11vnc
initialize_vnc_connect_prop();
initialize_x11vnc_remote_prop();
}
macjump:
signal(SIGUSR1, sigusr1);
got_sigusr1 = 0;
@ -572,6 +577,10 @@ void do_gui(char *opts, int sleep) {
connect_to_x11vnc = 1;
}
#ifdef MACOSX
goto startit;
#endif
if (icon_mode && !got_gui_xdisplay) {
/* for tray mode, prefer the polled DISPLAY */
if (use_dpy) {
@ -620,6 +629,8 @@ void do_gui(char *opts, int sleep) {
}
XCloseDisplay_wr(test_dpy);
startit:
if (start_x11vnc) {
#if LIBVNCSERVER_HAVE_FORK

@ -2848,6 +2848,10 @@ void print_help(int mode) {
" You can also set the env. var X11VNC_UINPUT_DEBUG=1 or\n"
" higher to get debugging output for UINPUT mode.\n"
"\n"
"-macnodim For the native Mac OS X server, disable dimming. \n"
"-macnosleep For the native Mac OS X server, disable display sleep.\n"
"-macnosaver For the native Mac OS X server, disable screensaver.\n"
"\n"
"-gui [gui-opts] Start up a simple tcl/tk gui based on the the remote\n"
" control options -remote/-query described below.\n"
" Requires the \"wish\" program to be installed on the\n"
@ -3216,6 +3220,8 @@ void print_help(int mode) {
" height parameter to n.\n"
" desktop:str set -desktop name to str for new clients.\n"
" rfbport:n set -rfbport to n.\n"
" macnosaver enable -macnosaver mode.\n"
" macsaver disable -macnosaver mode.\n"
/* access */
" httpport:n set -httpport to n.\n"
" httpdir:dir set -httpdir to dir (and enable http).\n"
@ -3327,7 +3333,7 @@ void print_help(int mode) {
" debug_wireframe debug_scroll nodebug_scroll debug_scroll\n"
" debug_tiles dbt nodebug_tiles nodbt debug_tiles\n"
" debug_grabs nodebug_grabs debug_sel nodebug_sel dbg\n"
" nodbg noremote\n"
" nodbg macnosaver macsaver noremote\n"
"\n"
" aro= noop display vncdisplay desktopname guess_desktop\n"
" http_url auth xauth users rootshift clipshift\n"
@ -3665,7 +3671,7 @@ void nopassword_warning_msg(int gotloc) {
fprintf(stderr, "%s", str1);
fflush(stderr);
#if !PASSWD_REQUIRED
usleep(2500 * 1000);
usleep(1000 * 1000);
#endif
if (!quiet) {
fprintf(stderr, "%s", str2);

@ -129,7 +129,7 @@ void clear_modifiers(int init) {
kcount++;
}
}
XFree((void *) keymap);
XFree_wr((void *) keymap);
first = 0;
}
if (init) {
@ -458,7 +458,7 @@ int add_keysym(KeySym keysym) {
ret = kc;
break;
}
XFree(keymap);
XFree_wr(keymap);
return ret;
#endif /* NO_X11 */
}
@ -491,7 +491,7 @@ static void delete_keycode(KeyCode kc, int bequiet) {
kc, ksym, str ? str : "null");
}
XFree(keymap);
XFree_wr(keymap);
XFlush_wr(dpy);
#endif /* NO_X11 */
}
@ -994,7 +994,7 @@ void switch_to_xkb_if_better(void) {
}
n = k;
XFree(keymap);
XFree_wr(keymap);
if (missing_noxkb == 0 && syms_gt_4 >= 8) {
if (! raw_fb_str) {
rfbLog("XKEYBOARD: number of keysyms per keycode %d "
@ -2300,7 +2300,7 @@ void initialize_modtweak(void) {
iso_level3_code = XKeysymToKeycode(dpy, XK_ISO_Level3_Shift);
#endif
XFree ((void *) keymap);
XFree_wr ((void *) keymap);
X_UNLOCK;
#endif /* NO_X11 */
@ -2531,6 +2531,8 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
console_key_command(down, keysym, client);
} else if (pipeinput_int == PIPEINPUT_UINPUT) {
uinput_key_command(down, keysym, client);
} else if (pipeinput_int == PIPEINPUT_MACOSX) {
macosx_key_command(down, keysym, client);
}
if (pipeinput_fh == NULL) {
return;

@ -9,6 +9,7 @@
#include "allowed_input_t.h"
#include "uinput.h"
#include "keyboard.h"
#include "macosx.h"
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
@ -26,6 +27,11 @@ char *console_guess(char *str, int *fd) {
char *atparms = NULL, *file = NULL;
int do_input, have_uinput, tty = -1;
#ifdef MACOSX
return macosx_console_guess(str, fd);
#endif
if (strstr(in, "/dev/fb") == in) {
free(in);
in = (char *) malloc(strlen("console:") + strlen(str) + 1);

@ -0,0 +1,377 @@
/* -- macosx.c -- */
#include "rfb/rfbconfig.h"
#if (defined(__MACH__) && defined(__APPLE__) && defined(LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY))
#define DOMAC 1
#else
#define DOMAC 0
#endif
#include "x11vnc.h"
#include "cleanup.h"
#include "scan.h"
#include "screen.h"
#include "pointer.h"
#include "allowed_input_t.h"
#include "keyboard.h"
#include "cursor.h"
#include "macosxCG.h"
#include "macosxCGP.h"
#include "macosxCGS.h"
char *macosx_console_guess(char *str, int *fd);
void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client);
char *macosx_get_fb_addr(void);
int macosx_get_cursor(void);
int macosx_get_cursor_pos(int *, int *);
int macosx_valid_window(Window, XWindowAttributes*);
Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return);
#if (! DOMAC)
void macosx_event_loop(void) {
return;
}
char *macosx_console_guess(char *str, int *fd) {
return NULL;
}
void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
return;
}
void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
return;
}
char *macosx_get_fb_addr(void) {
return NULL;
}
int macosx_get_cursor(void) {
return 0;
}
int macosx_get_cursor_pos(int *x, int *y) {
return 0;
}
int macosx_valid_window(Window w, XWindowAttributes* a) {
return 0;
}
Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return) {
return (Status) 0;
}
int dragum(void) {return 1;}
#else
void macosx_event_loop(void) {
macosxCG_event_loop();
}
char *macosx_get_fb_addr(void) {
macosxCG_init();
return macosxCG_get_fb_addr();
}
char *macosx_console_guess(char *str, int *fd) {
char *q, *in = strdup(str);
char *atparms = NULL, *file = NULL;
macosxCG_init();
if (strstr(in, "console") != in) {
rfbLog("console_guess: unrecognized console/fb format: %s\n", str);
free(in);
return NULL;
}
*fd = -1;
q = strrchr(in, '@');
if (q) {
atparms = strdup(q+1);
*q = '\0';
}
q = strrchr(in, ':');
if (q) {
file = strdup(q+1);
*q = '\0';
}
if (! file || file[0] == '\0') {
file = strdup("/dev/null");
}
rfbLog("console_guess: file is %s\n", file);
if (! pipeinput_str) {
pipeinput_str = strdup("MACOSX");
initialize_pipeinput();
}
if (! atparms) {
int w, h, b, bps, dep;
unsigned long rm = 0, gm = 0, bm = 0;
w = macosxCG_CGDisplayPixelsWide();
h = macosxCG_CGDisplayPixelsHigh();
b = macosxCG_CGDisplayBitsPerPixel();
bps = macosxCG_CGDisplayBitsPerSample();
dep = macosxCG_CGDisplaySamplesPerPixel() * bps;
rm = (1 << bps) - 1;
gm = (1 << bps) - 1;
bm = (1 << bps) - 1;
rm = rm << 2 * bps;
gm = gm << 1 * bps;
bm = bm << 0 * bps;
if (b == 8 && rm == 0xff && gm == 0xff && bm == 0xff) {
/* I don't believe it... */
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
/* @66666x66666x32:0xffffffff:... */
atparms = (char *) malloc(200);
sprintf(atparms, "%dx%dx%d:%lx/%lx/%lx",
w, h, b, rm, gm, bm);
}
if (atparms) {
int gw, gh, gb;
if (sscanf(atparms, "%dx%dx%d", &gw, &gh, &gb) == 3) {
fb_x = gw;
fb_y = gh;
fb_b = gb;
}
}
if (! atparms) {
rfbLog("console_guess: could not get @ parameters.\n");
return NULL;
}
q = (char *) malloc(strlen("map:macosx:") + strlen(file) + 1 + strlen(atparms) + 1);
sprintf(q, "map:macosx:%s@%s", file, atparms);
return q;
}
void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
allowed_input_t input;
int rc;
if (0) fprintf(stderr, "macosx_pointer_command: %d %d - %d\n", x, y, mask);
if (mask >= 0) {
got_pointer_calls++;
}
if (view_only) {
return;
}
get_allowed_input(client, &input);
if (! input.motion || ! input.button) {
/* XXX fix me with last_x, last_y, etc. */
return;
}
if (mask >= 0) {
got_user_input++;
got_pointer_input++;
last_pointer_client = client;
last_pointer_time = time(NULL);
}
macosxCG_pointer_inject(mask, x, y);
cursor_x = x;
cursor_y = y;
/* record the x, y position for the rfb screen as well. */
cursor_position(x, y);
/* change the cursor shape if necessary */
rc = set_cursor(x, y, get_which_cursor());
cursor_changes += rc;
last_event = last_input = last_pointer_input = time(NULL);
}
void init_key_table(void) {
macosxCG_init_key_table();
}
void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
static int control = 0, alt = 0;
allowed_input_t input;
if (debug_keyboard) fprintf(stderr, "macosx_key_command: %d %s\n", (int) keysym, down ? "down" : "up");
if (view_only) {
return;
}
get_allowed_input(client, &input);
if (! input.keystroke) {
return;
}
init_key_table();
macosxCG_key_inject((int) down, (unsigned int) keysym);
}
int macosx_get_cursor_pos(int *x, int *y) {
macosxCG_get_cursor_pos(x, y);
return 1;
}
int macosx_get_cursor(void) {
return macosxCG_get_cursor();
}
typedef struct windat {
int win;
int x, y;
int width, height;
int level;
} windat_t;
extern int macwinmax;
extern windat_t macwins[];
int macosx_get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
Window *frame, Window *win) {
static int last_idx = -1;
int x1, x2, y1, y2;
int idx = -1, i, k;
macosxCGS_get_all_windows();
macosxCG_get_cursor_pos(px, py);
for (i = -1; i<macwinmax; i++) {
k = i;
if (i == -1) {
if (last_idx >= 0 && last_idx < macwinmax) {
k = last_idx;
} else {
last_idx = -1;
continue;
}
}
x1 = macwins[k].x;
x2 = macwins[k].x + macwins[k].width;
y1 = macwins[k].y;
y2 = macwins[k].y + macwins[k].height;
if (debug_wireframe) fprintf(stderr, "%d/%d: %d %d %d - %d %d %d\n", k, macwins[k].win, x1, *px, x2, y1, *py, y2);
if (x1 <= *px && *px < x2) {
if (y1 <= *py && *py < y2) {
idx = k;
break;
}
}
}
if (idx < 0) {
return 0;
}
*x = macwins[idx].x;
*y = macwins[idx].y;
*w = macwins[idx].width;
*h = macwins[idx].height;
*frame = (Window) macwins[idx].win;
if (win != NULL) {
*win = *frame;
}
last_idx = idx;
return 1;
}
int macosx_valid_window(Window w, XWindowAttributes* a) {
static int last_idx = -1;
int win = (int) w;
int i, k, idx = -1;
for (i = -1; i<macwinmax; i++) {
k = i;
if (i == -1) {
if (last_idx >= 0 && last_idx < macwinmax) {
k = last_idx;
} else {
last_idx = -1;
continue;
}
}
if (macwins[k].win == win) {
idx = k;
break;
}
}
if (idx < 0) {
return 0;
}
a->x = macwins[idx].x;
a->y = macwins[idx].y;
a->width = macwins[idx].width;
a->height = macwins[idx].height;
a->depth = depth;
a->border_width = 0;
a->backing_store = 0;
a->map_state = IsViewable;
last_idx = idx;
return 1;
}
#define QTMAX 2048
static Window cret[QTMAX];
extern int CGS_levelmax;
extern int CGS_levels[];
Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return) {
int i, n, k, swap;
int win1, win2;
*root_return = (Window) 0;
*parent_return = (Window) 0;
#if 0
fprintf(stderr, "macosx_xquerytree in.\n");
#endif
macosxCGS_get_all_windows();
#if 0
fprintf(stderr, "macosx_xquerytree got windows.\n");
#endif
n = 0;
for (k = 0; k < CGS_levelmax; k++) {
for (i = macwinmax - 1; i >= 0; i--) {
if (macwins[i].level == CGS_levels[k]) {
#if 0
fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n);
#endif
cret[n++] = (Window) macwins[i].win;
}
}
}
*children_return = cret;
*nchildren_return = (unsigned int) macwinmax;
return (Status) 1;
}
#endif /* LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY */

@ -0,0 +1,19 @@
#ifndef _X11VNC_MACOSX_H
#define _X11VNC_MACOSX_H
/* -- macosx.h -- */
extern char *macosx_console_guess(char *str, int *fd);
extern char *macosx_get_fb_addr(void);
extern void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
extern void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client);
extern void macosx_event_loop(void);
extern int macosx_get_cursor(void);
extern int macosx_get_cursor_pos(int *, int *);
extern int macosx_valid_window(Window, XWindowAttributes*);
extern Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
Window **children_return, unsigned int *nchildren_return);
#endif /* _X11VNC_MACOSX_H */

@ -0,0 +1,508 @@
/* -- macosxCG.c -- */
/*
* We need to keep this separate from nearly everything else, e.g. rfb.h
* and the other stuff, otherwise it does not work properly, mouse drags
* will not work!!
*/
#if (defined(__MACH__) && defined(__APPLE__))
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
void macosxCG_init(void);
void macosxCG_event_loop(void);
char *macosxCG_get_fb_addr(void);
int macosxCG_CGDisplayPixelsWide(void);
int macosxCG_CGDisplayPixelsHigh(void);
int macosxCG_CGDisplayBitsPerPixel(void);
int macosxCG_CGDisplayBitsPerSample(void);
int macosxCG_CGDisplaySamplesPerPixel(void);
int macosxCG_CGDisplayBytesPerRow(void);
void macosxCG_pointer_inject(int mask, int x, int y);
int macosxCG_get_cursor_pos(int *x, int *y);
int macosxCG_get_cursor(void);
void macosxCG_init_key_table(void);
void macosxCG_key_inject(int down, unsigned int keysym);
CGDirectDisplayID displayID = NULL;
extern int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
static void macosxCG_callback(CGRectCount n, const CGRect *rects, void *dum) {
int i, db = 0;
if (db) fprintf(stderr, "macosx_callback: n=%d\n", (int) n);
for (i=0; i < n; i++) {
if (db > 1) fprintf(stderr, " : %g %g - %g %g\n", rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
collect_macosx_damage( (int) rects[i].origin.x, (int) rects[i].origin.y,
(int) rects[i].size.width, (int) rects[i].size.height, 1);
}
}
int dragum(void) {
int x =200, y = 150, dy = 10, i;
CGPoint loc;
CGDirectDisplayID displayID2 = kCGDirectMainDisplay;
(void) GetMainDevice();
for (i=0; i< 50; i++) {
usleep(1000*100);
loc.x = x;
loc.y = y + i*dy;
CGPostMouseEvent(loc, TRUE, 1, TRUE);
}
CGPostMouseEvent(loc, TRUE, 1, FALSE);
usleep(4*1000*1000);
return 0;
}
static int callback_set = 0;
extern int nofb;
void macosxCG_refresh_callback_on(void) {
if (nofb) {
return;
}
if (! callback_set) {
if (1) fprintf(stderr, "macosxCG_callback: register\n");
CGRegisterScreenRefreshCallback(macosxCG_callback, NULL);
}
callback_set = 1;
}
void macosxCG_refresh_callback_off(void) {
if (callback_set) {
if (1) fprintf(stderr, "macosxCG_callback: unregister\n");
CGUnregisterScreenRefreshCallback(macosxCG_callback, NULL);
}
callback_set = 0;
}
extern int macosx_noscreensaver;
void macosxCG_init(void) {
if (displayID == NULL) {
fprintf(stderr, "macosxCG_init: initializing display.\n");
//dragum();
displayID = kCGDirectMainDisplay;
(void) GetMainDevice();
CGSetLocalEventsSuppressionInterval(0.0);
CGSetLocalEventsFilterDuringSupressionState(
kCGEventFilterMaskPermitAllEvents,
kCGEventSupressionStateSupressionInterval);
CGSetLocalEventsFilterDuringSupressionState(
kCGEventFilterMaskPermitAllEvents,
kCGEventSupressionStateRemoteMouseDrag);
macosxCGP_init_dimming();
if (macosx_noscreensaver) {
macosxCGP_screensaver_timer_on();
}
}
}
void macosxCG_fini(void) {
macosxCGP_dim_shutdown();
if (macosx_noscreensaver) {
macosxCGP_screensaver_timer_off();
}
macosxCG_refresh_callback_off();
}
extern int dpy_x, dpy_y;
extern int client_count;
extern void do_new_fb(int);
void macosxCG_event_loop(void) {
OSStatus rc;
rc = RunCurrentEventLoop(kEventDurationSecond/30);
if (client_count) {
macosxCG_refresh_callback_on();
} else {
macosxCG_refresh_callback_off();
}
if (dpy_x != (int) CGDisplayPixelsWide(displayID)) {
if (dpy_y != (int) CGDisplayPixelsHigh(displayID)) {
do_new_fb(1);
}
}
}
char *macosxCG_get_fb_addr(void) {
macosxCG_init();
return (char *) CGDisplayBaseAddress(displayID);
}
int macosxCG_CGDisplayPixelsWide(void) {
return (int) CGDisplayPixelsWide(displayID);
}
int macosxCG_CGDisplayPixelsHigh(void) {
return (int) CGDisplayPixelsHigh(displayID);
}
int macosxCG_CGDisplayBitsPerPixel(void) {
return (int) CGDisplayBitsPerPixel(displayID);
}
int macosxCG_CGDisplayBitsPerSample(void) {
return (int) CGDisplayBitsPerSample(displayID);
}
int macosxCG_CGDisplaySamplesPerPixel(void) {
return (int) CGDisplaySamplesPerPixel(displayID);
}
int macosxCG_CGDisplayBytesPerRow(void) {
return (int) CGDisplayBytesPerRow(displayID);;
}
typedef int CGSConnectionRef;
static CGSConnectionRef conn = 0;
extern CGError CGSNewConnection(void*, CGSConnectionRef*);
extern CGError CGSReleaseConnection(CGSConnectionRef);
extern CGError CGSGetGlobalCursorDataSize(CGSConnectionRef, int*);
extern CGError CGSGetGlobalCursorData(CGSConnectionRef, unsigned char*,
int*, int*, CGRect*, CGPoint*, int*, int*, int*);
extern CGError CGSGetCurrentCursorLocation(CGSConnectionRef, CGPoint*);
extern int CGSCurrentCursorSeed(void);
extern int CGSHardwareCursorActive();
static CGPoint current_cursor_pos(void) {
CGPoint pos;
pos.x = 0;
pos.y = 0;
if (! conn) {
if (CGSNewConnection(NULL, &conn) != kCGErrorSuccess) {
fprintf(stderr, "CGSNewConnection error\n");
}
}
if (CGSGetCurrentCursorLocation(conn, &pos) != kCGErrorSuccess) {
fprintf(stderr, "CGSGetCurrentCursorLocation error\n");
}
return pos;
}
int macosxCG_get_cursor_pos(int *x, int *y) {
CGPoint pos = current_cursor_pos();
*x = pos.x;
*y = pos.y;
return 1;
}
extern int get_cursor_serial(int);
extern int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp, int xhot, int yhot);
int macosxCG_get_cursor(void) {
int last_idx = (int) get_cursor_serial(1);
int which = 1;
static CGPoint pos, lastpos;
static foo = 0;
CGError err;
int datasize, masksize, row_bytes, cdepth, comps, bpcomp;
CGRect rect;
CGPoint hot;
unsigned char *data;
int res, cursor_seed;
if (last_idx) {
which = last_idx;
}
pos = current_cursor_pos();
if (cursor_seed == CGSCurrentCursorSeed()) {
return which;
}
if (! conn) {
if (CGSNewConnection(NULL, &conn) != kCGErrorSuccess) {
fprintf(stderr, "CGSNewConnection error\n");
return which;
}
}
if (CGSGetGlobalCursorDataSize(conn, &datasize) != kCGErrorSuccess) {
fprintf(stderr, "CGSGetGlobalCursorDataSize error\n");
return which;
}
data = (unsigned char*) malloc(datasize);
err = CGSGetGlobalCursorData(conn, data, &datasize, &row_bytes,
&rect, &hot, &cdepth, &comps, &bpcomp);
if (err != kCGErrorSuccess) {
fprintf(stderr, "CGSGetGlobalCursorData error\n");
return which;
}
if (cdepth == 24) {
cdepth = 32;
}
cursor_seed = CGSCurrentCursorSeed();
which = store_cursor(cursor_seed, (unsigned long*) data,
(int) rect.size.width, (int) rect.size.height, cdepth, (int) hot.x, (int) hot.y);
free(data);
return(which);
}
void macosxCG_pointer_inject(int mask, int x, int y) {
int swap23 = 1, rc;
int s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4;
CGPoint loc;
int wheel_distance = 10;
static int cnt = 0;
loc.x = x;
loc.y = y;
if (swap23) {
s2 = 2;
s3 = 1;
}
if ((cnt++ % 10) == 0) {
macosxCGP_undim();
}
if ((mask & (1 << s4))) {
CGPostScrollWheelEvent(1, wheel_distance);
}
if ((mask & (1 << s5))) {
CGPostScrollWheelEvent(1, -wheel_distance);
}
CGPostMouseEvent(loc, TRUE, 3,
(mask & (1 << s1)) ? TRUE : FALSE,
(mask & (1 << s2)) ? TRUE : FALSE,
(mask & (1 << s3)) ? TRUE : FALSE
);
}
#define keyTableSize 0xFFFF
#include <rfb/keysym.h>
static int USKeyCodes[] = {
/* The alphabet */
XK_A, 0, /* A */
XK_B, 11, /* B */
XK_C, 8, /* C */
XK_D, 2, /* D */
XK_E, 14, /* E */
XK_F, 3, /* F */
XK_G, 5, /* G */
XK_H, 4, /* H */
XK_I, 34, /* I */
XK_J, 38, /* J */
XK_K, 40, /* K */
XK_L, 37, /* L */
XK_M, 46, /* M */
XK_N, 45, /* N */
XK_O, 31, /* O */
XK_P, 35, /* P */
XK_Q, 12, /* Q */
XK_R, 15, /* R */
XK_S, 1, /* S */
XK_T, 17, /* T */
XK_U, 32, /* U */
XK_V, 9, /* V */
XK_W, 13, /* W */
XK_X, 7, /* X */
XK_Y, 16, /* Y */
XK_Z, 6, /* Z */
XK_a, 0, /* a */
XK_b, 11, /* b */
XK_c, 8, /* c */
XK_d, 2, /* d */
XK_e, 14, /* e */
XK_f, 3, /* f */
XK_g, 5, /* g */
XK_h, 4, /* h */
XK_i, 34, /* i */
XK_j, 38, /* j */
XK_k, 40, /* k */
XK_l, 37, /* l */
XK_m, 46, /* m */
XK_n, 45, /* n */
XK_o, 31, /* o */
XK_p, 35, /* p */
XK_q, 12, /* q */
XK_r, 15, /* r */
XK_s, 1, /* s */
XK_t, 17, /* t */
XK_u, 32, /* u */
XK_v, 9, /* v */
XK_w, 13, /* w */
XK_x, 7, /* x */
XK_y, 16, /* y */
XK_z, 6, /* z */
/* Numbers */
XK_0, 29, /* 0 */
XK_1, 18, /* 1 */
XK_2, 19, /* 2 */
XK_3, 20, /* 3 */
XK_4, 21, /* 4 */
XK_5, 23, /* 5 */
XK_6, 22, /* 6 */
XK_7, 26, /* 7 */
XK_8, 28, /* 8 */
XK_9, 25, /* 9 */
/* Symbols */
XK_exclam, 18, /* ! */
XK_at, 19, /* @ */
XK_numbersign, 20, /* # */
XK_dollar, 21, /* $ */
XK_percent, 23, /* % */
XK_asciicircum, 22, /* ^ */
XK_ampersand, 26, /* & */
XK_asterisk, 28, /* * */
XK_parenleft, 25, /* ( */
XK_parenright, 29, /* ) */
XK_minus, 27, /* - */
XK_underscore, 27, /* _ */
XK_equal, 24, /* = */
XK_plus, 24, /* + */
XK_grave, 50, /* ` */ /* XXX ? */
XK_asciitilde, 50, /* ~ */
XK_bracketleft, 33, /* [ */
XK_braceleft, 33, /* { */
XK_bracketright, 30, /* ] */
XK_braceright, 30, /* } */
XK_semicolon, 41, /* ; */
XK_colon, 41, /* : */
XK_apostrophe, 39, /* ' */
XK_quotedbl, 39, /* " */
XK_comma, 43, /* , */
XK_less, 43, /* < */
XK_period, 47, /* . */
XK_greater, 47, /* > */
XK_slash, 44, /* / */
XK_question, 44, /* ? */
XK_backslash, 42, /* \ */
XK_bar, 42, /* | */
// OS X Sends this (END OF MEDIUM) for Shift-Tab (with US Keyboard)
0x0019, 48, /* Tab */
XK_space, 49, /* Space */
};
static int SpecialKeyCodes[] = {
/* "Special" keys */
XK_Return, 36, /* Return */
XK_Delete, 117, /* Delete */
XK_Tab, 48, /* Tab */
XK_Escape, 53, /* Esc */
XK_Caps_Lock, 57, /* Caps Lock */
XK_Num_Lock, 71, /* Num Lock */
XK_Scroll_Lock, 107, /* Scroll Lock */
XK_Pause, 113, /* Pause */
XK_BackSpace, 51, /* Backspace */
XK_Insert, 114, /* Insert */
/* Cursor movement */
XK_Up, 126, /* Cursor Up */
XK_Down, 125, /* Cursor Down */
XK_Left, 123, /* Cursor Left */
XK_Right, 124, /* Cursor Right */
XK_Page_Up, 116, /* Page Up */
XK_Page_Down, 121, /* Page Down */
XK_Home, 115, /* Home */
XK_End, 119, /* End */
/* Numeric keypad */
XK_KP_0, 82, /* KP 0 */
XK_KP_1, 83, /* KP 1 */
XK_KP_2, 84, /* KP 2 */
XK_KP_3, 85, /* KP 3 */
XK_KP_4, 86, /* KP 4 */
XK_KP_5, 87, /* KP 5 */
XK_KP_6, 88, /* KP 6 */
XK_KP_7, 89, /* KP 7 */
XK_KP_8, 91, /* KP 8 */
XK_KP_9, 92, /* KP 9 */
XK_KP_Enter, 76, /* KP Enter */
XK_KP_Decimal, 65, /* KP . */
XK_KP_Add, 69, /* KP + */
XK_KP_Subtract, 78, /* KP - */
XK_KP_Multiply, 67, /* KP * */
XK_KP_Divide, 75, /* KP / */
/* Function keys */
XK_F1, 122, /* F1 */
XK_F2, 120, /* F2 */
XK_F3, 99, /* F3 */
XK_F4, 118, /* F4 */
XK_F5, 96, /* F5 */
XK_F6, 97, /* F6 */
XK_F7, 98, /* F7 */
XK_F8, 100, /* F8 */
XK_F9, 101, /* F9 */
XK_F10, 109, /* F10 */
XK_F11, 103, /* F11 */
XK_F12, 111, /* F12 */
/* Modifier keys */
XK_Alt_L, 55, /* Alt Left (-> Command) */
XK_Alt_R, 55, /* Alt Right (-> Command) */
XK_Shift_L, 56, /* Shift Left */
XK_Shift_R, 56, /* Shift Right */
XK_Meta_L, 58, /* Option Left (-> Option) */
XK_Meta_R, 58, /* Option Right (-> Option) */
XK_Super_L, 58, /* Option Left (-> Option) */
XK_Super_R, 58, /* Option Right (-> Option) */
XK_Control_L, 59, /* Ctrl Left */
XK_Control_R, 59, /* Ctrl Right */
};
CGKeyCode keyTable[keyTableSize];
unsigned char keyTableMods[keyTableSize];
void macosxCG_init_key_table(void) {
static int init = 0;
int i;
if (init) {
return;
}
init = 1;
for (i=0; i < keyTableSize; i++) {
keyTable[i] = 0xFFFF;
keyTableMods[i] = 0;
}
for (i=0; i< (sizeof(USKeyCodes) / sizeof(int)); i += 2) {
int j = USKeyCodes[i];
keyTable[(unsigned short) j] = (CGKeyCode) USKeyCodes[i+1];
}
for (i=0; i< (sizeof(SpecialKeyCodes) / sizeof(int)); i += 2) {
int j = SpecialKeyCodes[i];
keyTable[(unsigned short) j] = (CGKeyCode) SpecialKeyCodes[i+1];
}
}
void macosxCG_key_inject(int down, unsigned int keysym) {
static int control = 0, alt = 0;
int pressModsForKeys = FALSE;
CGKeyCode keyCode = keyTable[(unsigned short)keysym];
CGCharCode keyChar = 0;
UInt32 modsForKey = keyTableMods[keysym] << 8;
init_key_table();
if (keysym < 0xFF) {
keyChar = (CGCharCode) keysym;
}
if (keyCode == 0xFFFF) {
return;
}
macosxCGP_undim();
CGPostKeyboardEvent(keyChar, keyCode, down);
}
#endif /* __APPLE__ */

@ -0,0 +1,23 @@
#ifndef _X11VNC_MACOSXCG_H
#define _X11VNC_MACOSXCG_H
/* -- macosxCG.h -- */
extern void macosxCG_init(void);
extern void macosxCG_event_loop(void);
extern char *macosxCG_get_fb_addr(void);
extern int macosxCG_CGDisplayPixelsWide(void);
extern int macosxCG_CGDisplayPixelsHigh(void);
extern int macosxCG_CGDisplayBitsPerPixel(void);
extern int macosxCG_CGDisplayBitsPerSample(void);
extern int macosxCG_CGDisplaySamplesPerPixel(void);
extern void macosxCG_pointer_inject(int mask, int x, int y);
extern int macosxCG_get_cursor_pos(int *x, int *y);
extern int macosxCG_get_cursor(void);
extern void macosxCG_init_key_table(void);
extern void macosxCG_key_inject(int down, unsigned int keysym);
#endif /* _X11VNC_MACOSXCG_H */

@ -0,0 +1,186 @@
/* -- macosxCGP.c -- */
#if (defined(__MACH__) && defined(__APPLE__))
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
int macosxCGP_save_dim(void);
int macosxCGP_restore_dim(void);
int macosxCGP_save_sleep(void);
int macosxCGP_restore_sleep(void);
int macosxCGP_init_dimming(void);
int macosxCGP_undim(void);
int macosxCGP_dim_shutdown(void);
void macosxCGP_screensaver_timer_off(void);
void macosxCGP_screensaver_timer_on(void);
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/pwr_mgt/IOPM.h>
extern CGDirectDisplayID displayID;
static unsigned long dim_time;
static unsigned long sleep_time;
static int dim_time_saved = 0;
static int sleep_time_saved = 0;
static int initialized = 0;
static mach_port_t master_dev_port;
static io_connect_t power_mgt;
extern int client_count;
extern int macosx_nodimming;
extern int macosx_nosleep;
extern int macosx_noscreensaver;
static EventLoopTimerUPP sstimerUPP;
static EventLoopTimerRef sstimer;
void macosxCG_screensaver_timer(EventLoopTimerRef timer, void *data) {
if (0) fprintf(stderr, "macosxCG_screensaver_timer: %d\n", time(0));
if (macosx_nosleep && client_count) {
if (0) fprintf(stderr, "UpdateSystemActivity: %d\n", time(0));
UpdateSystemActivity(IdleActivity);
}
}
void macosxCGP_screensaver_timer_off(void) {
if (0) fprintf(stderr, "macosxCGP_screensaver_timer_off: %d\n", time(0));
RemoveEventLoopTimer(sstimer);
DisposeEventLoopTimerUPP(sstimerUPP);
}
void macosxCGP_screensaver_timer_on(void) {
if (0) fprintf(stderr, "macosxCGP_screensaver_timer_on: %d\n", time(0));
sstimerUPP = NewEventLoopTimerUPP(macosxCG_screensaver_timer);
InstallEventLoopTimer(GetMainEventLoop(), kEventDurationSecond * 30,
kEventDurationSecond * 30, sstimerUPP, NULL, &sstimer);
}
int macosxCGP_save_dim(void) {
if (IOPMGetAggressiveness(power_mgt, kPMMinutesToDim,
&dim_time) != kIOReturnSuccess) {
return 0;
}
dim_time_saved = 1;
return 1;
}
int macosxCGP_restore_dim(void) {
if (! dim_time_saved) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim,
dim_time) != kIOReturnSuccess) {
return 0;
}
dim_time_saved = 0;
dim_time = 0;
return 1;
}
int macosxCGP_save_sleep(void) {
if (IOPMGetAggressiveness(power_mgt, kPMMinutesToSleep,
&sleep_time) != kIOReturnSuccess) {
return 0;
}
sleep_time_saved = 1;
return 1;
}
int macosxCGP_restore_sleep(void) {
if (! sleep_time_saved) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep,
dim_time) != kIOReturnSuccess) {
return 0;
}
sleep_time_saved = 0;
sleep_time = 0;
return 1;
}
int macosxCGP_init_dimming(void) {
if (IOMasterPort(bootstrap_port, &master_dev_port) !=
kIOReturnSuccess) {
return 0;
}
if (!(power_mgt = IOPMFindPowerManagement(master_dev_port))) {
return 0;
}
if (macosx_nodimming) {
if (! macosxCGP_save_dim()) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim, 0)
!= kIOReturnSuccess) {
return 0;
}
}
if (macosx_nosleep) {
if (! macosxCGP_save_sleep()) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep, 0)
!= kIOReturnSuccess) {
return 0;
}
}
initialized = 1;
return 1;
}
int macosxCGP_undim(void) {
if (! initialized) {
return 0;
}
if (! macosx_nodimming) {
if (! macosxCGP_save_dim()) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToDim, 0)
!= kIOReturnSuccess) {
return 0;
}
if (! macosxCGP_restore_dim()) {
return 0;
}
}
if (! macosx_nosleep) {
if (! macosxCGP_save_sleep()) {
return 0;
}
if (IOPMSetAggressiveness(power_mgt, kPMMinutesToSleep, 0)
!= kIOReturnSuccess) {
return 0;
}
if (! macosxCGP_restore_sleep()) {
return 0;
}
}
return 1;
}
int macosxCGP_dim_shutdown(void) {
if (! initialized) {
return 0;
}
if (dim_time_saved) {
if (! macosxCGP_restore_dim()) {
return 0;
}
}
if (sleep_time_saved) {
if (! macosxCGP_restore_sleep()) {
return 0;
}
}
return 1;
}
#endif /* __APPLE__ */

@ -0,0 +1,17 @@
#ifndef _X11VNC_MACOSXCGP_H
#define _X11VNC_MACOSXCGP_H
/* -- macosxCGP.h -- */
extern int macosxCGP_save_dim(void);
extern int macosxCGP_restore_dim(void);
extern int macosxCGP_save_sleep(void);
extern int macosxCGP_restore_sleep(void);
extern int macosxCGP_init_dimming(void);
extern int macosxCGP_undim(void);
extern int macosxCGP_dim_shutdown(void);
extern void macosxCGP_screensaver_timer_off(void);
extern void macosxCGP_screensaver_timer_on(void);
#endif /* _X11VNC_MACOSXCGP_H */

@ -0,0 +1,156 @@
/* -- macosxCGS.c -- */
/*
* We need to keep this separate from nearly everything else, e.g. rfb.h
* and the other stuff, otherwise it does not work properly, mouse drags
* will not work!!
*/
#if (defined(__MACH__) && defined(__APPLE__))
#include <ApplicationServices/ApplicationServices.h>
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
extern CGDirectDisplayID displayID;
void macosxCGS_get_all_windows(void);
typedef CGError CGSError;
typedef long CGSWindowCount;
typedef void * CGSConnectionID;
typedef int CGSWindowID;
typedef CGSWindowID* CGSWindowIDList;
typedef CGWindowLevel CGSWindowLevel;
typedef NSRect CGSRect;
extern CGSConnectionID _CGSDefaultConnection ();
extern CGSError CGSGetOnScreenWindowList (CGSConnectionID cid,
CGSConnectionID owner, CGSWindowCount listCapacity,
CGSWindowIDList list, CGSWindowCount *listCount);
extern CGSError CGSGetScreenRectForWindow (CGSConnectionID cid,
CGSWindowID wid, CGSRect *rect);
extern CGWindowLevel CGSGetWindowLevel (CGSConnectionID cid,
CGSWindowID wid, CGSWindowLevel *level);
typedef enum _CGSWindowOrderingMode {
kCGSOrderAbove = 1, // Window is ordered above target.
kCGSOrderBelow = -1, // Window is ordered below target.
kCGSOrderOut = 0 // Window is removed from the on-screen window list.
} CGSWindowOrderingMode;
extern OSStatus CGSOrderWindow(const CGSConnectionID cid,
const CGSWindowID wid, CGSWindowOrderingMode place, CGSWindowID relativeToWindowID);
static CGSConnectionID cid = NULL;
int macwinmax = 0;
typedef struct windat {
int win;
int x, y;
int width, height;
int level;
} windat_t;
#define MAXWINDAT 2048
windat_t macwins[MAXWINDAT];
static CGSWindowID _wins[MAXWINDAT];
extern double dnow(void);
extern int dpy_x, dpy_y;
int CGS_levelmax;
int CGS_levels[16];
void macosxCGS_get_all_windows(void) {
static double last = 0.0;
static int first = 1;
double dt = 0.0, now = dnow();
int i, db = 0;
CGSWindowCount cap = (CGSWindowCount) MAXWINDAT;
CGSWindowCount cnt = 0;
CGSError err;
if (first) {
first = 0;
CGS_levelmax = 0;
CGS_levels[CGS_levelmax++] = (int) kCGDraggingWindowLevel; /* 500 */
if (0) CGS_levels[CGS_levelmax++] = (int) kCGHelpWindowLevel; /* 102 */
if (0) CGS_levels[CGS_levelmax++] = (int) kCGPopUpMenuWindowLevel; /* 101 */
CGS_levels[CGS_levelmax++] = (int) kCGMainMenuWindowLevelKey; /* 24 */
CGS_levels[CGS_levelmax++] = (int) kCGFloatingWindowLevel; /* 3 */
CGS_levels[CGS_levelmax++] = (int) kCGNormalWindowLevel; /* 0 */
}
if (cid == NULL) {
cid = _CGSDefaultConnection();
if (cid == NULL) {
return;
}
}
if (dt > 0.0 && now < last + dt) {
return;
}
err = CGSGetOnScreenWindowList(cid, NULL, cap, _wins, &cnt);
if (db) fprintf(stderr, "cnt: %d err: %d\n", cnt, err);
if (err != 0) {
return;
}
last = now;
macwinmax = 0;
for (i=0; i < (int) cnt; i++) {
CGSRect rect;
CGSWindowLevel level;
int j, keepit = 0;
err = CGSGetScreenRectForWindow(cid, _wins[i], &rect);
if (err != 0) {
continue;
}
if (rect.origin.x == 0 && rect.origin.y == 0) {
if (rect.size.width == dpy_x) {
if (rect.size.height == dpy_y) {
continue;
}
}
}
err = CGSGetWindowLevel(cid, _wins[i], &level);
if (err != 0) {
continue;
}
for (j=0; j<CGS_levelmax; j++) {
if ((int) level == CGS_levels[j]) {
keepit = 1;
break;
}
}
if (! keepit) {
continue;
}
macwins[macwinmax].level = (int) level;
macwins[macwinmax].win = (int) _wins[i];
macwins[macwinmax].x = (int) rect.origin.x;
macwins[macwinmax].y = (int) rect.origin.y;
macwins[macwinmax].width = (int) rect.size.width;
macwins[macwinmax].height = (int) rect.size.height;
if (db) fprintf(stderr, "i=%03d ID: %06d x: %03d y: %03d w: %03d h: %03d level: %d\n", i, _wins[i],
(int) rect.origin.x, (int) rect.origin.y,(int) rect.size.width, (int) rect.size.height, (int) level);
macwinmax++;
}
}
#endif /* __APPLE__ */

@ -0,0 +1,9 @@
#ifndef _X11VNC_MACOSXCGS_H
#define _X11VNC_MACOSXCGS_H
/* -- macosxCGS.h -- */
extern void macosxCGS_get_all_windows(void);
#endif /* _X11VNC_MACOSXCGS_H */

@ -129,6 +129,10 @@ int pipeinput_int = 0;
int pipeinput_cons_fd = -1;
char *pipeinput_cons_dev = NULL;
int macosx_nodimming = 0;
int macosx_nosleep = 0;
int macosx_noscreensaver = 0;
unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0;

@ -104,6 +104,10 @@ extern int pipeinput_int;
extern int pipeinput_cons_fd;
extern char *pipeinput_cons_dev;
extern int macosx_nodimming;
extern int macosx_nosleep;
extern int macosx_noscreensaver;
extern unsigned long subwin;
extern int subwin_wait_mapped;

@ -39,6 +39,7 @@
#define PIPEINPUT_VID 0x1
#define PIPEINPUT_CONSOLE 0x2
#define PIPEINPUT_UINPUT 0x3
#define PIPEINPUT_MACOSX 0x4
#define MAX_BUTTONS 5

@ -547,6 +547,8 @@ static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
console_pointer_command(mask, x, y, client);
} else if (pipeinput_int == PIPEINPUT_UINPUT) {
uinput_pointer_command(mask, x, y, client);
} else if (pipeinput_int == PIPEINPUT_MACOSX) {
macosx_pointer_command(mask, x, y, client);
}
if (pipeinput_fh == NULL) {
return;
@ -666,7 +668,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
if (! pipeinput_tee) {
if (! view_only || raw_fb) { /* raw_fb hack */
got_user_input++;
got_keyboard_input++;
got_pointer_input++;
last_pointer_client = client;
}
if (input.motion) {
@ -980,6 +982,9 @@ if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
pipeinput_int = PIPEINPUT_UINPUT;
initialize_uinput();
return;
} else if (strstr(p, "MACOSX") == p) {
pipeinput_int = PIPEINPUT_MACOSX;
return;
}
set_child_info();

@ -579,7 +579,7 @@ int remote_control_access_ok(void) {
rfbLog(" unknown-%d\n", i+1);
}
}
XFree(xha);
XFree_wr(xha);
return 0;
}
@ -3888,6 +3888,20 @@ char *process_remote_cmd(char *cmd, int stringonly) {
crash_debug = 0;
rfbLog("set crash_debug to: %d\n", crash_debug);
} else if (!strcmp(p, "macnosaver")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, macosx_noscreensaver); goto qry;
}
rfbLog("remote_cmd: turn on macnosaver.\n");
macosx_noscreensaver = 1;
} else if (!strcmp(p, "macsaver")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !macosx_noscreensaver); goto qry;
}
rfbLog("remote_cmd: turn off macnosaver.\n");
macosx_noscreensaver = 0;
} else if (strstr(p, "hack") == p) { /* skip-cmd-list */
COLON_CHECK("hack:")
if (query) {
@ -3994,7 +4008,6 @@ char *process_remote_cmd(char *cmd, int stringonly) {
" of the system tray.\n", id);
}
} else if (query) {
/* read-only variables that can only be queried: */

@ -12,6 +12,7 @@
#include "cleanup.h"
#include "unixpw.h"
#include "screen.h"
#include "macosx.h"
/*
* routines for scanning and reading the X11 display for changes, and
@ -2943,7 +2944,15 @@ int scan_for_updates(int count_only) {
}
if (use_xdamage) {
/* first pass collecting DAMAGE events: */
collect_xdamage(scan_count, 0);
#ifdef MACOSX
if (! dpy) {
macosx_event_loop();
collect_macosx_damage(-1, -1, -1, -1, 0);
} else
#endif
{
collect_xdamage(scan_count, 0);
}
}
}
@ -2967,7 +2976,14 @@ int scan_for_updates(int count_only) {
* the unchanged tiles are read in again).
*/
if (use_xdamage) {
collect_xdamage(scan_count, 1);
#ifdef MACOSX
if (! dpy) {
;
} else
#endif
{
collect_xdamage(scan_count, 1);
}
}
if (count_only) {
scan_in_progress = 0;

@ -21,6 +21,7 @@
#include "sslhelper.h"
#include "v4l.h"
#include "linuxfb.h"
#include "macosx.h"
void set_greyscale_colormap(void);
void set_hi240_colormap(void);
@ -618,7 +619,9 @@ void set_raw_fb_params(int restore) {
"use_solid_bg\n");
use_solid_bg = 0;
}
#ifndef MACOSX
multiple_cursors_mode = strdup("arrow");
#endif
}
if (using_shm) {
if (verbose) rfbLog(" rawfb: turning off using_shm\n");
@ -650,8 +653,14 @@ static void nofb_hook(rfbClientPtr cl) {
rfbLog("framebuffer requested in -nofb mode by client %s\n", cl->host);
/* ignore xrandr */
RAWFB_RET_VOID
fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
if (raw_fb && ! dpy) {
XImage raw;
fb = &raw;
fb->data = (char *)malloc(32);
} else {
fb = XGetImage_wr(dpy, window, 0, 0, dpy_x, dpy_y, AllPlanes, ZPixmap);
}
main_fb = fb->data;
rfb_fb = main_fb;
screen->frameBuffer = rfb_fb;
@ -809,6 +818,7 @@ XImage *initialize_raw_fb(int reset) {
static XImage ximage_struct; /* n.b.: not (XImage *) */
static XImage ximage_struct_snap;
int closedpy = 1, i, m, db = 0;
int do_macosx = 0;
static char *last_file = NULL;
static int last_mode = 0;
@ -855,6 +865,12 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
return NULL;
}
#ifdef MACOSX
if (raw_fb_addr != NULL && raw_fb_addr == macosx_get_fb_addr()) {
raw_fb_addr = NULL;
}
#endif
if (raw_fb_addr || raw_fb_seek) {
if (raw_fb_shm) {
@ -1129,6 +1145,13 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
q = strchr(str, ':');
q++;
if (strstr(q, "macosx:") == q) {
/* mmap:macosx:/dev/null@... */
q += strlen("macosx:");
do_macosx = 1;
do_mmap = 0;
}
last_file = strdup(q);
fd = raw_fb_fd;
@ -1159,7 +1182,15 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
}
if (do_mmap) {
if (do_macosx) {
raw_fb_addr = macosx_get_fb_addr();
raw_fb_mmap = size;
rfbLog("rawfb: macosx fb: %s\n", q);
rfbLog(" w: %d h: %d b: %d addr: %p sz: %d\n", w, h,
b, raw_fb_addr, size);
last_mode = 0;
} else if (do_mmap) {
#if LIBVNCSERVER_HAVE_MMAP
raw_fb_addr = mmap(0, size, PROT_READ, MAP_SHARED,
fd, 0);
@ -1211,6 +1242,12 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
raw_fb_image->bytes_per_line = dpy_x*b/8;
raw_fb_image->bitmap_unit = -1;
#ifdef MACOSX
if (do_macosx) {
raw_fb_image->bytes_per_line = macosxCG_CGDisplayBytesPerRow();
}
#endif
if (use_snapfb && (raw_fb_seek || raw_fb_mmap)) {
int b_use = b;
if (snap_fb) {
@ -1556,7 +1593,7 @@ if (0) fprintf(stderr, "DefaultDepth: %d visial_id: %d\n", depth, (int) visual_
vinfo->bits_per_rgb);
fprintf(stderr, "\n");
}
XFree(vinfo);
XFree_wr(vinfo);
}
if (! quiet) {

@ -205,13 +205,13 @@ void cutbuffer_send(void) {
/* too big */
rfbLog("warning: truncating large CUT_BUFFER0"
" selection > %d bytes.\n", PROP_MAX);
XFree(data);
XFree_wr(data);
break;
}
memcpy(cutbuffer_str+slen, data, dlen);
slen += dlen;
cutbuffer_str[slen] = '\0';
XFree(data);
XFree_wr(data);
}
} while (bytes_after > 0);
@ -309,7 +309,7 @@ void selection_send(XEvent *ev) {
if (slen + dlen > PROP_MAX) {
/* too big */
toobig = 1;
XFree(data);
XFree_wr(data);
if (err) { /* cut down on messages */
break;
} else {
@ -324,7 +324,7 @@ if (debug_sel) fprintf(stderr, "selection_send: data: '%s' dlen: %d nitems: %lu
memcpy(selection_str+slen, data, dlen);
slen += dlen;
selection_str[slen] = '\0';
XFree(data);
XFree_wr(data);
}
} while (bytes_after > 0);

@ -3607,11 +3607,14 @@ proc toggle_simple_gui {} {
proc little_qs {m} {
global bfont ffont beginner_mode
global helpremote helptext helplabel
global tk_version
global tk_version osname
if {$tk_version < 8.0} {
return
}
if {$osname == "Darwin"} {
return
}
set n [$m index end]
@ -3856,6 +3859,7 @@ proc make_menu_items {} {
}
# Now make the little "(?)" help buttons
global osname
foreach case [array names menu_m] {
if {$case == "Help"} {
continue;
@ -5224,7 +5228,12 @@ proc make_widgets {top} {
}
incr ul
}
menubutton $menub -text "$case" -underline $ul \
global osname
set tstr "$case"
if {$osname == "Darwin"} {
#set tstr " $case "
}
menubutton $menub -text "$tstr" -underline $ul \
-anchor w -menu $menu -background $fbg \
-font $bfont
pack $menub -side top -fill x
@ -5296,30 +5305,42 @@ proc make_widgets {top} {
bind $ef_entry <KeyPress-Return> {set entry_set 1}
bind $ef_entry <KeyPress-Escape> {set entry_set 0}
set ok_s "OK"
set cancel_s "Cancel"
set help_s "Help"
set browse_s "Browse..."
global osname
if {$osname == "Darwin"} {
set ok_s " OK "
set cancel_s " Cancel "
set help_s " Help "
set browse_s " Browse... "
}
# Entry OK button
set bpx "1m"
set bpy "1"
set hlt "0"
set ef_ok "$ef.ok"
button $ef_ok -text OK -pady $bpy -padx $bpx -command {set entry_set 1} \
button $ef_ok -text $ok_s -pady $bpy -padx $bpx -command {set entry_set 1} \
-highlightthickness $hlt \
-font $bfont
# Entry Skip button
set ef_skip "$ef.skip"
button $ef_skip -text Cancel -pady $bpy -padx $bpx -command {set entry_set 0} \
button $ef_skip -text $cancel_s -pady $bpy -padx $bpx -command {set entry_set 0} \
-highlightthickness $hlt \
-font $bfont
# Entry Help button
set ef_help "$ef.help"
button $ef_help -text Help -pady $bpy -padx $bpx -command \
button $ef_help -text $help_s -pady $bpy -padx $bpx -command \
{menu_help $entry_dialog_item} -font $bfont \
-highlightthickness $hlt
# Entry Browse button
set ef_browse "$ef.browse"
button $ef_browse -text "Browse..." -pady $bpy -padx $bpx -font $bfont \
button $ef_browse -text $browse_s -pady $bpy -padx $bpx -font $bfont \
-highlightthickness $hlt \
-command {entry_insert [tk_getOpenFile]}
@ -6453,6 +6474,10 @@ if {[regexp -nocase {IRIX} $osname]} {
# IRIX "fixed" font is huge and doublespaced...
set ffont $snfont
}
if {[regexp -nocase {Darwin} $osname]} {
set ffont {Monaco 10}
set bfont {system}
}
#puts [exec env]
#puts "x11vnc_xdisplay: $x11vnc_xdisplay"

@ -3618,11 +3618,14 @@ char gui_code[] = "";
"proc little_qs {m} {\n"
" global bfont ffont beginner_mode\n"
" global helpremote helptext helplabel\n"
" global tk_version\n"
" global tk_version osname\n"
"\n"
" if {$tk_version < 8.0} {\n"
" return\n"
" }\n"
" if {$osname == \"Darwin\"} {\n"
" return\n"
" }\n"
"\n"
" set n [$m index end]\n"
"\n"
@ -3867,6 +3870,7 @@ char gui_code[] = "";
" }\n"
"\n"
" # Now make the little \"(?)\" help buttons\n"
" global osname\n"
" foreach case [array names menu_m] {\n"
" if {$case == \"Help\"} {\n"
" continue;\n"
@ -5235,7 +5239,12 @@ char gui_code[] = "";
" }\n"
" incr ul\n"
" }\n"
" menubutton $menub -text \"$case\" -underline $ul \\\n"
" global osname\n"
" set tstr \"$case\"\n"
" if {$osname == \"Darwin\"} {\n"
" #set tstr \" $case \"\n"
" }\n"
" menubutton $menub -text \"$tstr\" -underline $ul \\\n"
" -anchor w -menu $menu -background $fbg \\\n"
" -font $bfont\n"
" pack $menub -side top -fill x\n"
@ -5307,30 +5316,42 @@ char gui_code[] = "";
" bind $ef_entry <KeyPress-Return> {set entry_set 1}\n"
" bind $ef_entry <KeyPress-Escape> {set entry_set 0}\n"
"\n"
" set ok_s \"OK\"\n"
" set cancel_s \"Cancel\"\n"
" set help_s \"Help\"\n"
" set browse_s \"Browse...\"\n"
" global osname\n"
" if {$osname == \"Darwin\"} {\n"
" set ok_s \" OK \"\n"
" set cancel_s \" Cancel \"\n"
" set help_s \" Help \"\n"
" set browse_s \" Browse... \"\n"
" }\n"
"\n"
" # Entry OK button\n"
" set bpx \"1m\"\n"
" set bpy \"1\"\n"
" set hlt \"0\"\n"
" set ef_ok \"$ef.ok\"\n"
" button $ef_ok -text OK -pady $bpy -padx $bpx -command {set entry_set 1} \\\n"
" button $ef_ok -text $ok_s -pady $bpy -padx $bpx -command {set entry_set 1} \\\n"
" -highlightthickness $hlt \\\n"
" -font $bfont\n"
"\n"
" # Entry Skip button\n"
" set ef_skip \"$ef.skip\"\n"
" button $ef_skip -text Cancel -pady $bpy -padx $bpx -command {set entry_set 0} \\\n"
" button $ef_skip -text $cancel_s -pady $bpy -padx $bpx -command {set entry_set 0} \\\n"
" -highlightthickness $hlt \\\n"
" -font $bfont\n"
"\n"
" # Entry Help button\n"
" set ef_help \"$ef.help\"\n"
" button $ef_help -text Help -pady $bpy -padx $bpx -command \\\n"
" button $ef_help -text $help_s -pady $bpy -padx $bpx -command \\\n"
" {menu_help $entry_dialog_item} -font $bfont \\\n"
" -highlightthickness $hlt\n"
"\n"
" # Entry Browse button\n"
" set ef_browse \"$ef.browse\"\n"
" button $ef_browse -text \"Browse...\" -pady $bpy -padx $bpx -font $bfont \\\n"
" button $ef_browse -text $browse_s -pady $bpy -padx $bpx -font $bfont \\\n"
" -highlightthickness $hlt \\\n"
" -command {entry_insert [tk_getOpenFile]} \n"
"\n"
@ -6464,6 +6485,10 @@ char gui_code[] = "";
" # IRIX \"fixed\" font is huge and doublespaced... \n"
" set ffont $snfont\n"
"}\n"
"if {[regexp -nocase {Darwin} $osname]} {\n"
" set ffont {Monaco 10}\n"
" set bfont {system}\n"
"}\n"
"\n"
"#puts [exec env]\n"
"#puts \"x11vnc_xdisplay: $x11vnc_xdisplay\"\n"

@ -96,12 +96,19 @@ int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
int rootx, rooty, wx, wy;
unsigned int mask;
#ifdef MACOSX
if (! dpy) {
return macosx_get_wm_frame_pos(px, py, x, y, w, h, frame, win);
}
#endif
RAWFB_RET(0)
#if NO_X11
return 0;
#else
ret = XQueryPointer(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy,
ret = XQueryPointer_wr(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy,
&mask);
*frame = c;
@ -2876,6 +2883,7 @@ static int try_copyrect(Window frame, int x, int y, int w, int h, int dx, int dy
x -= off_x;
y -= off_y;
}
if (db2) fprintf(stderr, "try_copyrect: 0x%lx bad: %d stack_list_num: %d\n", frame, dt_bad, stack_list_num);
if (dt_bad && wireframe_in_progress) {
sraRegionPtr rect;
@ -2941,6 +2949,7 @@ if (db2) fprintf(stderr, "moved_win: %4d %3d, %4d %3d 0x%lx ---\n",
}
swin = stack_list[k].win;
if (db2) fprintf(stderr, "sw: %d/%lx\n", k, swin);
if (swin == frame) {
if (db2) {
saw_me = 1; fprintf(stderr, " ----------\n");
@ -2953,11 +2962,16 @@ fprintf(stderr, "bo: %d/%lx\n", k, swin);
#endif
/* skip some unwanted cases: */
#ifdef MACOSX
if (0) {
;
#else
if (swin == None) {
continue;
}
if (swin < 10) {
; /* blackouts */
#endif
} else if (! stack_list[k].fetched ||
stack_list[k].time > tm + 2.0) {
if (!valid_window(swin, &attr, 1)) {
@ -3349,7 +3363,9 @@ int check_wireframe(void) {
int try_it = 0;
DB_SET
#ifndef MACOSX
RAWFB_RET(0)
#endif
if (unixpw_in_progress) return 0;
@ -3359,12 +3375,14 @@ int check_wireframe(void) {
if (subwin) {
return 0; /* don't even bother for -id case */
}
if (db > 1 && button_mask) fprintf(stderr, "check_wireframe: bm: %d gpi: %d\n", button_mask, got_pointer_input);
if (! button_mask) {
return 0; /* no button pressed down */
}
if (!use_threads && !got_pointer_input) {
return 0; /* need ptr input, e.g. button down, motion */
}
if (db > 1) fprintf(stderr, "check_wireframe: %d\n", db);
if (db) fprintf(stderr, "\n*** button down!! x: %d y: %d\n", cursor_x, cursor_y);
@ -3375,12 +3393,12 @@ if (db) fprintf(stderr, "\n*** button down!! x: %d y: %d\n", cursor_x, cursor_
*/
X_LOCK;
if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &frame, NULL)) {
if (db) fprintf(stderr, "NO get_wm_frame_pos: 0x%lx\n", frame);
if (db) fprintf(stderr, "NO get_wm_frame_pos-1: 0x%lx\n", frame);
X_UNLOCK;
return 0;
}
X_UNLOCK;
if (db) fprintf(stderr, "a: %d wf: %.3f A: %d\n", w*h, wireframe_frac, (dpy_x*dpy_y));
if (db) fprintf(stderr, "a: %d wf: %.3f A: %d frm: 0x%lx\n", w*h, wireframe_frac, (dpy_x*dpy_y), frame);
/*
* apply the percentage size criterion (allow opaque moves for
@ -3390,7 +3408,7 @@ if (db) fprintf(stderr, "a: %d wf: %.3f A: %d\n", w*h, wireframe_frac, (dpy_x*
if (db) fprintf(stderr, "small window %.3f\n", ((double) w*h)/(dpy_x * dpy_y));
return 0;
}
if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, orig_frame);
if (db) fprintf(stderr, " frame: x: %d y: %d w: %d h: %d px: %d py: %d fr: 0x%lx\n", x, y, w, h, px, py, frame);
/*
* see if the pointer is within range of the assumed wm frame
@ -3590,7 +3608,7 @@ if (db) fprintf(stderr, " ++pointer event!! [%02d] dt: %.3f x: %d y: %d mas
if (! get_wm_frame_pos(&px, &py, &x, &y, &w, &h,
&frame, NULL)) {
frame = 0x0;
if (db) fprintf(stderr, "NO get_wm_frame_pos: 0x%lx\n", frame);
if (db) fprintf(stderr, "NO get_wm_frame_pos-2: 0x%lx\n", frame);
}
if (frame != orig_frame) {
@ -3754,7 +3772,7 @@ if (db || db2) fprintf(stderr, "NO button_mask\n");
sent_copyrect = try_copyrect(frame, x, y, w, h, dx, dy,
&obscured, NULL, 0.15);
if (db) fprintf(stderr, "send_copyrect: %d\n", sent_copyrect);
if (db) fprintf(stderr, "sent_copyrect: %d - obs: %d frame: 0x%lx\n", sent_copyrect, obscured, frame);
if (sent_copyrect) {
/* try to push the changes to viewers: */
if (! obscured) {
@ -4361,7 +4379,9 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) {
#ifndef MACOSX
RAWFB_RET(0)
#endif
if (use_xrecord) {
int rc = check_xrecord();

@ -43,7 +43,7 @@ Window parent_window(Window win, char **name) {
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
rc = XQueryTree(dpy, win, &r, &parent, &list, &nchild);
rc = XQueryTree_wr(dpy, win, &r, &parent, &list, &nchild);
XSetErrorHandler(old_handler);
if (! rc || trapped_xerror) {
@ -53,7 +53,7 @@ Window parent_window(Window win, char **name) {
trapped_xerror = 0;
if (list) {
XFree(list);
XFree_wr(list);
}
if (parent && name) {
XFetchName(dpy, parent, name);
@ -77,6 +77,11 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
if (win == None) {
return 0;
}
#ifdef MACOSX
if (! dpy) {
return macosx_valid_window(win, attr_ret);
}
#endif
RAWFB_RET(0)
#if NO_X11
nox11_exit(1);
@ -179,14 +184,16 @@ void snapshot_stack_list(int free_only, double allowed_age) {
stack_list_num = 0;
last_free = now;
#ifndef MACOSX
RAWFB_RET_VOID
#if NO_X11
#endif
#if NO_X11 && !defined(MACOSX)
return;
#else
X_LOCK;
/* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
rc = XQueryTree_wr(dpy, rootwin, &r, &w, &list, &ui);
num = (int) ui;
if (! rc) {
@ -213,6 +220,12 @@ void snapshot_stack_list(int free_only, double allowed_age) {
j++;
}
for (i=0; i<blackouts; i++) {
#ifdef MACOSX
if (! dpy) {
num = num - blackouts;
break;
}
#endif
stack_list[j].win = 0x1;
stack_list[j].fetched = 1;
stack_list[j].valid = 1;
@ -237,7 +250,7 @@ if (0) fprintf(stderr, "blackr: %d %dx%d+%d+%d\n", i,
stack_list_num, stack_list_len);
}
XFree(list);
XFree_wr(list);
X_UNLOCK;
#endif /* NO_X11 */
}
@ -296,7 +309,7 @@ Window query_pointer(Window start) {
if (start == None) {
start = rootwin;
}
if (XQueryPointer(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
if (XQueryPointer_wr(dpy, start, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
return c;
} else {
return None;
@ -314,7 +327,7 @@ unsigned int mask_state(void) {
return 0;
#else
if (XQueryPointer(dpy, rootwin, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
if (XQueryPointer_wr(dpy, rootwin, &r, &c, &rx, &ry, &wx, &wy, &mask)) {
return mask;
} else {
return 0;
@ -462,7 +475,7 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
} else {
filled = 1;
}
XFree(name);
XFree_wr(name);
}
}
if (store && classhint && ! filled) {
@ -492,14 +505,14 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
filled = 1;
}
if (classhint->res_class) {
XFree(classhint->res_class);
XFree_wr(classhint->res_class);
}
if (classhint->res_name) {
XFree(classhint->res_name);
XFree_wr(classhint->res_name);
}
}
}
if (! XQueryPointer(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) {
if (! XQueryPointer_wr(dpy, c, &r, &c, &rx, &ry, &wx, &wy, &m)) {
break;
}
if (! c) {

@ -2,7 +2,7 @@
.TH X11VNC "1" "November 2006" "x11vnc " "User Commands"
.SH NAME
x11vnc - allow VNC connections to real X11 displays
version: 0.8.3, lastmod: 2006-11-06
version: 0.8.4, lastmod: 2006-11-13
.SH SYNOPSIS
.B x11vnc
[OPTION]...
@ -3331,6 +3331,18 @@ Example:
You can also set the env. var X11VNC_UINPUT_DEBUG=1 or
higher to get debugging output for UINPUT mode.
.PP
\fB-macnodim\fR
.IP
For the native Mac OS X server, disable dimming.
.PP
\fB-macnosleep\fR
.IP
For the native Mac OS X server, disable display sleep.
.PP
\fB-macnosaver\fR
.IP
For the native Mac OS X server, disable screensaver.
.PP
\fB-gui\fR \fI[gui-opts]\fR
.IP
Start up a simple tcl/tk gui based on the the remote
@ -3892,6 +3904,10 @@ desktop:str set \fB-desktop\fR name to str for new clients.
.IP
rfbport:n set \fB-rfbport\fR to n.
.IP
macnosaver enable \fB-macnosaver\fR mode.
.IP
macsaver disable \fB-macnosaver\fR mode.
.IP
httpport:n set \fB-httpport\fR to n.
.IP
httpdir:dir set \fB-httpdir\fR to dir (and enable http).
@ -4046,7 +4062,7 @@ debug_xdamage debug_wireframe nodebug_wireframe
debug_wireframe debug_scroll nodebug_scroll debug_scroll
debug_tiles dbt nodebug_tiles nodbt debug_tiles
debug_grabs nodebug_grabs debug_sel nodebug_sel dbg
nodbg noremote
nodbg macnosaver macsaver noremote
.IP
aro= noop display vncdisplay desktopname guess_desktop
http_url auth xauth users rootshift clipshift

@ -530,6 +530,7 @@ static void watch_loop(void) {
eat_viewonly_input(10, 3);
}
} else {
/* -threads here. */
if (wireframe && button_mask) {
check_wireframe();
}
@ -1440,6 +1441,8 @@ static void store_homedir_passwd(char *file) {
&& !query_cmd && !remote_cmd && !unixpw && !got_gui_pw \
&& ! ssl_verify && !inetd)
extern int dragum(void);
int main(int argc, char* argv[]) {
int i, len, tmpi;
@ -1463,6 +1466,9 @@ int main(int argc, char* argv[]) {
int argc_vnc_max = 1024;
int argc_vnc = 1; char *argv_vnc[2048];
//dragum();
/* check for -loop mode: */
check_loop_mode(argc, argv);
@ -2280,6 +2286,12 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-pipeinput")) {
CHECK_ARGC
pipeinput_str = strdup(argv[++i]);
} else if (!strcmp(arg, "-macnodim")) {
macosx_nodimming = 1;
} else if (!strcmp(arg, "-macnosleep")) {
macosx_nosleep = 1;
} else if (!strcmp(arg, "-macnosaver")) {
macosx_noscreensaver = 1;
} else if (!strcmp(arg, "-gui")) {
launch_gui = 1;
if (i < argc-1) {
@ -2434,8 +2446,23 @@ int main(int argc, char* argv[]) {
if (launch_gui) {
int sleep = 0;
if (SHOW_NO_PASSWORD_WARNING && !nopw) {
sleep = 2;
sleep = 1;
}
#ifdef MACOSX
if (! use_dpy && getenv("DISPLAY") == NULL) {
/* we need this for gui since no X properties */
if (! client_connect_file && ! client_connect) {
int fd;
char tmp[] = "/tmp/x11vnc-macosx-channel.XXXXXX";
fd = mkstemp(tmp);
if (fd >= 0) {
close(fd);
client_connect_file = strdup(tmp);
rfbLog("MacOS X: set -connect file to %s\n", client_connect_file);
}
}
}
#endif
do_gui(gui_str, sleep);
}
if (logfile) {
@ -2952,6 +2979,12 @@ int main(int argc, char* argv[]) {
dpy = XOpenDisplay_wr("");
}
#ifdef MACOSX
if (! dpy && ! raw_fb_str) {
raw_fb_str = strdup("console");
}
#endif
if (! dpy && raw_fb_str) {
rfbLog("continuing without X display in -rawfb mode, "
"hold on tight..\n");
@ -3355,6 +3388,19 @@ int main(int argc, char* argv[]) {
raw_fb_pass_go_and_collect_200_dollars:
#ifdef MACOSX
if (! dpy) {
if (! multiple_cursors_mode) {
multiple_cursors_mode = strdup("most");
}
initialize_cursors_mode();
if (use_xdamage) {
xdamage_present = 1;
initialize_xdamage();
}
}
#endif
if (! dt) {
static char str[] = "-desktop";
argv_vnc[argc_vnc++] = str;

@ -47,7 +47,9 @@
#else
#define NO_X11 1
#ifndef SKIP_NO_X11
#include "nox11.h"
#endif
#include <rfb/keysym.h>
#endif
@ -308,6 +310,10 @@ extern int h_errno;
(defined(__MACH__) && defined(__APPLE__))
_AIX
*/
#if (defined(__MACH__) && defined(__APPLE__))
#define MACOSX
#endif
#ifdef IRIX_OVERLAY
#include <X11/extensions/readdisplay.h>

@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.3 lastmod: 2006-11-06";
char lastmod[] = "0.8.4 lastmod: 2006-11-13";
/* X display info */

@ -13,7 +13,13 @@ Damage xdamage = 0;
#endif
int use_xdamage = XDAMAGE; /* use the xdamage rects for scanline hints */
int xdamage_present = 0;
#ifdef MACOSX
int xdamage_max_area = 50000;
#else
int xdamage_max_area = 20000; /* pixels */
#endif
double xdamage_memory = 1.0; /* in units of NSCAN */
int xdamage_tile_count = 0, xdamage_direct_count = 0;
double xdamage_scheduled_mark = 0.0;
@ -24,6 +30,7 @@ int XD_skip = 0, XD_tot = 0, XD_des = 0; /* for stats */
void add_region_xdamage(sraRegionPtr new_region);
void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
int collect_xdamage(int scancnt, int call);
int xdamage_hint_skip(int y);
void initialize_xdamage(void);
@ -31,7 +38,6 @@ void create_xdamage_if_needed(void);
void destroy_xdamage_if_needed(void);
void check_xdamage_state(void);
static void record_desired_xdamage_rect(int x, int y, int w, int h);
@ -158,7 +164,7 @@ void add_region_xdamage(sraRegionPtr new_region) {
reg = xdamage_regions[prev_tick];
if (reg != NULL) {
if (0) fprintf(stderr, "add_region_xdamage: prev_tick: %d reg %p\n", prev_tick, (void *)reg);
if (debug_xdamage > 1) fprintf(stderr, "add_region_xdamage: prev_tick: %d reg %p\n", prev_tick, (void *)reg);
sraRgnOr(reg, new_region);
}
}
@ -211,6 +217,125 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
#endif
}
int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call) {
sraRegionPtr tmpregion;
sraRegionPtr reg;
static int rect_count = 0;
int nreg, ccount = 0, dcount = 0, ecount = 0;
static time_t last_rpt = 0;
time_t now;
double tm, dt;
int x, y, w, h, x2, y2;
if (call && debug_xdamage > 1) fprintf(stderr, "collect_macosx_damage: %d %d %d %d - %d / %d\n", x_in, y_in, w_in, h_in, call, use_xdamage);
if (! use_xdamage) {
return 0;
}
dtime0(&tm);
nreg = (xdamage_memory * NSCAN) + 1;
if (call == 0) {
xdamage_ticker = (xdamage_ticker+1) % nreg;
xdamage_direct_count = 0;
reg = xdamage_regions[xdamage_ticker];
sraRgnMakeEmpty(reg);
} else {
reg = xdamage_regions[xdamage_ticker];
}
if (x_in < 0) {
return 0;
}
x = x_in;
y = y_in;
w = w_in;
h = h_in;
/* translate if needed */
if (clipshift) {
/* set coords relative to fb origin */
if (0 && rootshift) {
/*
* Note: not needed because damage is
* relative to subwin, not rootwin.
*/
x = x - off_x;
y = y - off_y;
}
if (clipshift) {
x = x - coff_x;
y = y - coff_y;
}
x2 = x + w; /* upper point */
x = nfix(x, dpy_x); /* place both in fb area */
x2 = nfix(x2, dpy_x+1);
w = x2 - x; /* recompute w */
y2 = y + h;
y = nfix(y, dpy_y);
y2 = nfix(y2, dpy_y+1);
h = y2 - y;
if (w <= 0 || h <= 0) {
return 0;
}
}
if (debug_xdamage > 2) {
fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"
" %d dups: %d %s\n", w, h, x, y, w*h, dcount,
(w*h > xdamage_max_area) ? "TOO_BIG" : "");
}
record_desired_xdamage_rect(x, y, w, h);
tmpregion = sraRgnCreateRect(x, y, x + w, y + h);
sraRgnOr(reg, tmpregion);
sraRgnDestroy(tmpregion);
rect_count++;
ccount++;
if (0 && xdamage_direct_count) {
fb_push();
}
dt = dtime(&tm);
if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
|| debug_xdamage > 1) {
fprintf(stderr, "collect_macosx_damage(%d): %.4f t: %.4f ev/dup/accept"
"/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
dcount, ccount, xdamage_direct_count);
}
now = time(NULL);
if (! last_rpt) {
last_rpt = now;
}
if (now > last_rpt + 15) {
double rat = -1.0;
if (XD_tot) {
rat = ((double) XD_skip)/XD_tot;
}
if (debug_tiles || debug_xdamage) {
fprintf(stderr, "xdamage: == scanline skip/tot: "
"%04d/%04d =%.3f rects: %d desired: %d\n",
XD_skip, XD_tot, rat, rect_count, XD_des);
}
XD_skip = 0;
XD_tot = 0;
XD_des = 0;
rect_count = 0;
last_rpt = now;
}
return 0;
}
int collect_xdamage(int scancnt, int call) {
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
XDamageNotifyEvent *dev;
@ -436,6 +561,7 @@ int xdamage_hint_skip(int y) {
}
}
sraRgnDestroy(tmpl);
if (0) fprintf(stderr, "xdamage_hint_skip: %d -> %d\n", y, ret);
return ret;
}

@ -19,6 +19,7 @@ extern int XD_skip, XD_tot, XD_des;
extern void add_region_xdamage(sraRegionPtr new_region);
extern void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
extern int collect_macosx_damage(int x_in, int y_in, int w_in, int h_in, int call);
extern int collect_xdamage(int scancnt, int call);
extern int xdamage_hint_skip(int y);
extern void initialize_xdamage(void);

@ -190,13 +190,13 @@ static void get_prop(char *str, int len, Atom prop) {
dlen = nitems * (format/8);
if (slen + dlen > len) {
/* too big */
XFree(data);
XFree_wr(data);
break;
}
memcpy(str+slen, data, dlen);
slen += dlen;
str[slen] = '\0';
XFree(data);
XFree_wr(data);
}
} while (bytes_after > 0);
#endif /* NO_X11 */

@ -272,7 +272,7 @@ static void initialize_xinerama (void) {
rfbLog("Xinerama: no blackouts needed (only one"
" sub-screen)\n");
}
XFree(xineramas);
XFree_wr(xineramas);
return; /* must be OK w/o change */
}
@ -293,7 +293,7 @@ static void initialize_xinerama (void) {
sraRgnDestroy(tmp_region);
sc++;
}
XFree(xineramas);
XFree_wr(xineramas);
if (sraRgnEmpty(black_region)) {
rfbLog("Xinerama: no blackouts needed (screen fills"

@ -22,7 +22,6 @@ void initialize_xrandr(void);
int check_xrandr_event(char *msg);
int known_xrandr_mode(char *s);
static int handle_subwin_resize(char *msg);
static void handle_xrandr_change(int new_x, int new_y);

@ -156,9 +156,9 @@ void initialize_xrecord(void) {
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_RECORD
if (rr_CA) XFree(rr_CA);
if (rr_CW) XFree(rr_CW);
if (rr_GS) XFree(rr_GS);
if (rr_CA) XFree_wr(rr_CA);
if (rr_CW) XFree_wr(rr_CW);
if (rr_GS) XFree_wr(rr_GS);
rr_CA = XRecordAllocRange();
rr_CW = XRecordAllocRange();
@ -236,9 +236,9 @@ void shutdown_xrecord(void) {
xserver_grabbed, dnowx());
}
if (rr_CA) XFree(rr_CA);
if (rr_CW) XFree(rr_CW);
if (rr_GS) XFree(rr_GS);
if (rr_CA) XFree_wr(rr_CA);
if (rr_CW) XFree_wr(rr_CW);
if (rr_GS) XFree_wr(rr_GS);
rr_CA = NULL;
rr_CW = NULL;

@ -75,6 +75,12 @@ int xauth_raw(int on);
Display *XOpenDisplay_wr(char *display_name);
int XCloseDisplay_wr(Display *display);
Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
Window *child_return, int *root_x_return, int *root_y_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return);
int XFree_wr(void *data);
void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
static void upup_downdown_warning(KeyCode key, Bool down);
@ -1057,6 +1063,59 @@ int XCloseDisplay_wr(Display *display) {
#endif /* NO_X11 */
}
Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
Window *child_return, int *root_x_return, int *root_y_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return) {
#if NO_X11
return False;
#else
if (! display) {
return False;
}
return XQueryPointer(display, w, root_return, child_return,
root_x_return, root_y_return, win_x_return, win_y_return,
mask_return);
#endif /* NO_X11 */
}
Status XQueryTree_wr(Display *display, Window w, Window *root_return,
Window *parent_return, Window **children_return,
unsigned int *nchildren_return) {
#ifdef MACOSX
if (! display) {
return macosx_xquerytree(w, root_return, parent_return,
children_return, nchildren_return);
}
#endif
#if NO_X11
return (Status) 0;
#else
if (! display) {
return (Status) 0;
}
return XQueryTree(display, w, root_return, parent_return,
children_return, nchildren_return);
#endif /* NO_X11 */
}
int XFree_wr(void *data) {
if (data == NULL) {
return 1;
}
if (! dpy) {
return 1;
}
#if NO_X11
return 1;
#else
return XFree(data);
#endif
}
void nox11_exit(int rc) {
#if NO_X11
rfbLog("This x11vnc was not built with X11 support.\n");
@ -1066,6 +1125,7 @@ void nox11_exit(int rc) {
#endif
}
#if NO_X11
#include "nox11_funcs.h"
#endif

@ -72,4 +72,11 @@ extern int xauth_raw(int on);
extern Display *XOpenDisplay_wr(char *display_name);
extern int XCloseDisplay_wr(Display *display);
extern Bool XQueryPointer_wr(Display *display, Window w, Window *root_return,
Window *child_return, int *root_x_return, int *root_y_return,
int *win_x_return, int *win_y_return, unsigned int *mask_return);
extern int XFree_wr(void *data);
#endif /* _X11VNC_XWRAPPERS_H */

Loading…
Cancel
Save