x11vnc: Mac OS X fb fixes and cuttext, -nodpms option, local user wireframing

pull/1/head
runge 17 years ago
parent 05ba45f72e
commit 27a884d2f3

@ -1,3 +1,6 @@
2006-11-21 Karl Runge <runge@karlrunge.com>
* configure.ac: add DPMS detection.
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

@ -61,6 +61,7 @@ AH_TEMPLATE(HAVE_RECORD, [RECORD extension build environment present])
AH_TEMPLATE(HAVE_SOLARIS_XREADSCREEN, [Solaris XReadScreen available])
AH_TEMPLATE(HAVE_IRIX_XREADDISPLAY, [IRIX XReadDisplay available])
AH_TEMPLATE(HAVE_FBPM, [FBPM extension build environment present])
AH_TEMPLATE(HAVE_DPMS, [DPMS extension build environment present])
AH_TEMPLATE(HAVE_LINUX_VIDEODEV_H, [video4linux build environment present])
AH_TEMPLATE(HAVE_LINUX_FB_H, [linux fb device build environment present])
AH_TEMPLATE(HAVE_LINUX_INPUT_H, [linux/input.h present])
@ -119,6 +120,10 @@ elif test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
[#include <X11/Xlib.h>
#include <X11/Xmd.h>])
AC_CHECK_HEADER(X11/extensions/dpms.h,
[AC_DEFINE(HAVE_DPMS)], ,
[#include <X11/Xlib.h>])
AC_CHECK_LIB(Xtst, XTestGrabControl,
X_PRELIBS="-lXtst $X_PRELIBS"
[AC_DEFINE(HAVE_XTESTGRABCONTROL) HAVE_XTESTGRABCONTROL="true"], ,

@ -1,3 +1,9 @@
2006-11-21 Karl Runge <runge@karlrunge.com>
* x11vnc: macosx: problem with padded framebuffer rows, wait for
user to switch back, CutText xfer support, ignore a few more
types of toplevels. Add local user wireframing. -dpms/-nodpms
option to work around kdesktop_lock problem.
2006-11-13 Karl Runge <runge@karlrunge.com>
* x11vnc: Native Mac OS X support.

File diff suppressed because it is too large Load Diff

@ -133,7 +133,7 @@ void clean_up_exit (int ret) {
unlink(client_connect_file);
}
}
if (! dpy) {
if (macosx_console) {
macosxCG_fini();
}
#endif

@ -748,7 +748,7 @@ void client_gone(rfbClientPtr client) {
clean_up_exit(0);
}
#ifdef MACOSX
if (! dpy && client_count == 0) {
if (macosx_console && client_count == 0) {
macosxCG_refresh_callback_off();
}
#endif
@ -2108,7 +2108,7 @@ enum rfbNewClientAction new_client(rfbClientPtr client) {
autorepeat(0, 0);
}
#ifdef MACOSX
if (! dpy && client_count == 1) {
if (macosx_console && client_count == 1) {
macosxCG_refresh_callback_on();
}
#endif

@ -1246,7 +1246,7 @@ static int get_exact_cursor(int init) {
}
#ifdef MACOSX
if (! dpy) {
if (macosx_console) {
return macosx_get_cursor();
}
#endif
@ -1325,6 +1325,11 @@ fprintf(stderr, "sc: %d %d/%d %d - %d %d\n", serial, w, h, cbpp, xhot, yhot);
* 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;
@ -1481,11 +1486,7 @@ int get_which_cursor(void) {
}
if (mode == 3) {
int try_macosx = 0;
#ifdef MACOSX
if (! dpy) try_macosx = 1;
#endif
if ((xfixes_present && use_xfixes) || try_macosx) {
if ((xfixes_present && use_xfixes) || macosx_console) {
if (db) fprintf(stderr, "get_which_cursor call get_exact_cursor\n");
return get_exact_cursor(0);
}
@ -1846,24 +1847,23 @@ int check_x11_pointer(void) {
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 {
if (macosx_console) {
ret = macosx_get_cursor_pos(&root_x, &root_y);
} else {
RAWFB_RET(0)
}
#else
RAWFB_RET(0)
#if NO_X11
# if NO_X11
return 0;
#endif
# endif
#endif
@ -1876,6 +1876,7 @@ int check_x11_pointer(void) {
}
#endif /* NO_X11 */
if (0) fprintf(stderr, "check_x11_pointer %d %d\n", root_x, root_y);
if (! ret) {
return 0;
}

@ -839,7 +839,7 @@ void print_help(int mode) {
"\n"
" Your VNC viewer will also need to be able to connect\n"
" via SSL. See the discussion below under -stunnel and\n"
" the FAQ (ssl_vncviewer script) for how this might be\n"
" the FAQ (ss_vncviewer script) for how this might be\n"
" achieved. E.g. on Unix it is easy to write a shell\n"
" script that starts up stunnel and then vncviewer.\n"
" Also in the x11vnc source a SSL enabled Java VNC Viewer\n"
@ -985,7 +985,7 @@ void print_help(int mode) {
" be \"imported\" somehow. Web browsers have \"Manage\n"
" Certificates\" actions as does the Java applet plugin\n"
" Control Panel. stunnel can also use these files (see\n"
" the ssl_vncviewer example script in the FAQ.)\n"
" the ss_vncviewer example script in the FAQ.)\n"
"\n"
"-sslGenCA [dir] Generate your own Certificate Authority private key,\n"
" certificate, and other files in directory [dir].\n"
@ -1126,14 +1126,14 @@ void print_help(int mode) {
" x11vnc -sslGenCert server\n"
" x11vnc -ssl SAVE -display :0 ...\n"
"\n"
" and then on viewer using ssl_vncviewer stunnel wrapper\n"
" and then on viewer using ss_vncviewer stunnel wrapper\n"
" (see the FAQ):\n"
" ssl_vncviewer -verify ./cacert.crt hostname:0\n"
" ss_vncviewer -verify ./cacert.crt hostname:0\n"
"\n"
" (this assumes the cacert.crt cert from -sslGenCA\n"
" was safely copied to the VNC viewer machine where\n"
" ssl_vncviewer is run)\n"
" ss_vncviewer is run)\n"
"\n"
" Example using a name:\n"
"\n"
@ -1151,7 +1151,7 @@ void print_help(int mode) {
" roger), and on the viewer user on somehost could do\n"
" for example:\n"
"\n"
" ssl_vncviewer -mycert ./roger.pem hostname:0\n"
" ss_vncviewer -mycert ./roger.pem hostname:0\n"
"\n"
" If you set the env. var REQ_ARGS='...' it will be\n"
" passed to openssl req(1). A common use would be\n"
@ -2014,6 +2014,12 @@ void print_help(int mode) {
" link is detected, these values may be automatically\n"
" changed to something better for a slow link.\n"
"\n"
"-nowireframelocal By default, mouse motion and button presses of a\n"
" user sitting at the LOCAL display are monitored for\n"
" wireframing opportunities (so that the changes will be\n"
" sent efficiently to the VNC clients). Use this option\n"
" to disable this behavior.\n"
"\n"
"-wirecopyrect mode Since the -wireframe mechanism evidently tracks moving\n"
"-nowirecopyrect windows accurately, a speedup can be obtained by\n"
" telling the VNC viewers to locally copy the translated\n"
@ -2432,6 +2438,27 @@ void print_help(int mode) {
" for details. -nofbpm is basically the same as running\n"
" \"xset fbpm force on\" periodically. Default: %s\n"
"\n"
"-nodpms If the system supports the DPMS (Display Power Management\n"
"-dpms Signaling) extension, then prevent the monitor from\n"
" going into a reduced power state when VNC clients\n"
" are connected.\n"
"\n"
" DPMS reduced power monitor states are a good thing\n"
" and you normally want the power down to take place\n"
" (usually x11vnc has no problem exporting the display in\n"
" this state). You probably only want to use \"-nodpms\"\n"
" to work around problems with Screen Savers kicking\n"
" on in DPMS low power states. There is known problem\n"
" with kdesktop_lock on KDE where the screen saver keeps\n"
" kicking in every time user input stops for a second\n"
" or two. Specifying \"-nodpms\" works around it.\n"
"\n"
" \"-nodpms\" means prevent DPMS low power states whenever\n"
" VNC clients are connected, while \"-dpms\" means to not\n"
" monitor the DPMS state at all. See the xset(1) manpage\n"
" for details. -nodpms is basically the same as running\n"
" \"xset dpms force on\" periodically. Default: %s\n"
"\n"
"-noxdamage Do not use the X DAMAGE extension to detect framebuffer\n"
" changes even if it is available. Use -xdamage if your\n"
" default is to have it off.\n"
@ -2547,6 +2574,11 @@ void print_help(int mode) {
" memory object. If the masks are not provided x11vnc\n"
" guesses them based on the bpp.\n"
"\n"
" Another optional suffix is the Bytes Per Line which in\n"
" some cases is not WxHxB/4. Specify it as WxHxB-BPL\n"
" e.g. 800x600x16-2048. This could be a normal width\n"
" 1024 at 16bpp fb, but only width 800 shows up.\n"
"\n"
" Examples:\n"
" -rawfb shm:210337933@800x600x32:ff/ff00/ff0000\n"
" -rawfb map:/dev/fb0@1024x768x32\n"
@ -2851,6 +2883,15 @@ void print_help(int mode) {
"-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"
"-macnowait For the native Mac OS X server, do not wait for the\n"
" user to switch back to his display.\n"
"-macwheel n For the native Mac OS X server, set the mouse wheel\n"
" speed to n (default 5).\n"
"-macnoswap For the native Mac OS X server, do not swap mouse\n"
" buttons 2 and 3.\n"
"-macnoresize For the native Mac OS X server, do not resize or reset\n"
" the framebuffer even if it is detected that the screen\n"
" resolution or depth has changed.\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"
@ -3165,6 +3206,8 @@ void print_help(int mode) {
" nowireframe disable -wireframe mode. same as \"nowf\"\n"
" wireframe:str enable -wireframe mode string.\n"
" wireframe_mode:str enable -wireframe mode string.\n"
" wireframelocal enable wireframelocal. same as \"wfl\"\n"
" nowireframe disable wireframelocal. same as \"nowfl\"\n"
" wirecopyrect:str set -wirecopyrect string. same as \"wcr:\"\n"
" scrollcopyrect:str set -scrollcopyrect string. same \"scr\"\n"
" noscrollcopyrect disable -scrollcopyrect mode. \"noscr\"\n"
@ -3202,6 +3245,8 @@ void print_help(int mode) {
" sb:n set -sb to n s, same as screen_blank:n\n"
" fbpm disable -nofbpm mode.\n"
" nofbpm enable -nofbpm mode.\n"
" dpms disable -nodpms mode.\n"
" nodpms enable -nodpms mode.\n"
" xdamage enable xdamage polling hints.\n"
" noxdamage disable xdamage polling hints.\n"
" xd_area:A set -xd_area max pixel area to \"A\"\n"
@ -3297,35 +3342,36 @@ void print_help(int mode) {
" listen lookup nolookup accept afteraccept gone shm\n"
" noshm flipbyteorder noflipbyteorder onetile noonetile\n"
" solid_color solid nosolid blackout xinerama noxinerama\n"
" xtrap noxtrap xrandr noxrandr xrandr_mode rotate\n"
" padgeom quiet q noquiet modtweak nomodtweak xkb noxkb\n"
" capslock nocapslock skip_lockkeys noskip_lockkeys\n"
" skip_keycodes sloppy_keys nosloppy_keys skip_dups\n"
" noskip_dups add_keysyms noadd_keysyms clear_mods\n"
" noclear_mods clear_keys noclear_keys remap repeat\n"
" norepeat fb nofb bell nobell sel nosel primary\n"
" noprimary setprimary nosetprimary clipboard noclipboard\n"
" setclipboard nosetclipboard seldir cursorshape\n"
" nocursorshape cursorpos nocursorpos cursor_drag\n"
" nocursor_drag cursor show_cursor noshow_cursor\n"
" nocursor arrow xfixes noxfixes xdamage noxdamage\n"
" xd_area xd_mem alphacut alphafrac alpharemove\n"
" noalpharemove alphablend noalphablend xwarppointer\n"
" xwarp noxwarppointer noxwarp buttonmap dragging\n"
" nodragging wireframe_mode wireframe wf nowireframe\n"
" nowf wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" xtrap noxtrap xrandr noxrandr xrandr_mode rotate padgeom\n"
" quiet q noquiet modtweak nomodtweak xkb noxkb capslock\n"
" nocapslock skip_lockkeys noskip_lockkeys skip_keycodes\n"
" sloppy_keys nosloppy_keys skip_dups noskip_dups\n"
" add_keysyms noadd_keysyms clear_mods noclear_mods\n"
" clear_keys noclear_keys remap repeat norepeat fb nofb\n"
" bell nobell sel nosel primary noprimary setprimary\n"
" nosetprimary clipboard noclipboard setclipboard\n"
" nosetclipboard seldir cursorshape nocursorshape\n"
" cursorpos nocursorpos cursor_drag nocursor_drag cursor\n"
" show_cursor noshow_cursor nocursor arrow xfixes noxfixes\n"
" xdamage noxdamage xd_area xd_mem alphacut alphafrac\n"
" alpharemove noalpharemove alphablend noalphablend\n"
" xwarppointer xwarp noxwarppointer noxwarp buttonmap\n"
" dragging nodragging wireframe_mode wireframe wf\n"
" nowireframe nowf wireframelocal wfl nowireframelocal\n"
" nowfl wirecopyrect wcr nowirecopyrect nowcr scr_area\n"
" scr_skip scr_inc scr_keys scr_term scr_keyrepeat\n"
" scr_parms scrollcopyrect scr noscrollcopyrect noscr\n"
" fixscreen noxrecord xrecord reset_record pointer_mode pm\n"
" input_skip allinput noallinput input grabkbd nograbkbd\n"
" grabptr nograbptr client_input ssltimeout speeds wmdt\n"
" debug_pointer dp nodebug_pointer nodp debug_keyboard\n"
" dk nodebug_keyboard nodk deferupdate defer wait_ui\n"
" wait_bog nowait_bog slow_fb wait readtimeout nap nonap\n"
" sb screen_blank fbpm nofbpm fs gaps grow fuzz snapfb\n"
" nosnapfb rawfb uinput_accel uinput_thresh uinput_reset\n"
" uinput_always progressive rfbport http nohttp httpport\n"
" httpdir enablehttpproxy noenablehttpproxy alwaysshared\n"
" fixscreen noxrecord xrecord reset_record pointer_mode\n"
" pm input_skip allinput noallinput input grabkbd\n"
" nograbkbd grabptr nograbptr client_input ssltimeout\n"
" speeds wmdt debug_pointer dp nodebug_pointer nodp\n"
" debug_keyboard dk nodebug_keyboard nodk deferupdate\n"
" defer wait_ui wait_bog nowait_bog slow_fb wait\n"
" readtimeout nap nonap sb screen_blank fbpm nofbpm\n"
" dpms nodpms fs gaps grow fuzz snapfb nosnapfb rawfb\n"
" uinput_accel uinput_thresh uinput_reset uinput_always\n"
" progressive rfbport http nohttp httpport httpdir\n"
" enablehttpproxy noenablehttpproxy alwaysshared\n"
" noalwaysshared nevershared noalwaysshared dontdisconnect\n"
" nodontdisconnect desktop debug_xevents nodebug_xevents\n"
" debug_xevents debug_xdamage nodebug_xdamage\n"
@ -3350,7 +3396,6 @@ void print_help(int mode) {
" mouse_x mouse_y bpp depth indexed_color dpy_x dpy_y\n"
" wdpy_x wdpy_y off_x off_y cdpy_x cdpy_y coff_x coff_y\n"
" rfbauth passwd viewpasswd\n"
"\n"
"-QD variable Just like -query variable, but returns the default\n"
" value for that parameter (no running x11vnc server\n"
" is consulted)\n"
@ -3497,6 +3542,7 @@ void print_help(int mode) {
take_naps ? "take naps":"no naps",
screen_blank,
watch_fbpm ? "-nofbpm":"-fbpm",
watch_dpms ? "-nodpms":"-dpms",
xdamage_max_area, NSCAN, xdamage_memory,
use_threads ? "-threads":"-nothreads",
fs_frac,

@ -2870,7 +2870,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
last_rfb_key_accepted = TRUE;
if (pipeinput_fh != NULL || pipeinput_int) {
pipe_keyboard(down, keysym, client);
pipe_keyboard(down, keysym, client); /* MACOSX here. */
if (! pipeinput_tee) {
if (! view_only || raw_fb) { /* raw_fb hack */
last_keyboard_client = client;

@ -29,6 +29,8 @@ 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 *);
void macosx_send_sel(char *, int);
void macosx_set_sel(char *, int);
int macosx_valid_window(Window, XWindowAttributes*);
Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
@ -57,6 +59,12 @@ int macosx_get_cursor(void) {
int macosx_get_cursor_pos(int *x, int *y) {
return 0;
}
void macosx_send_sel(char * str, int len) {
return;
}
void macosx_set_sel(char * str, int len) {
return;
}
int macosx_valid_window(Window w, XWindowAttributes* a) {
return 0;
}
@ -163,6 +171,7 @@ char *macosx_console_guess(char *str, int *fd) {
void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
allowed_input_t input;
static int last_mask = 0;
int rc;
if (0) fprintf(stderr, "macosx_pointer_command: %d %d - %d\n", x, y, mask);
@ -191,9 +200,18 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) {
macosxCG_pointer_inject(mask, x, y);
if (cursor_x != x || cursor_y != y) {
last_pointer_motion_time = dnow();
}
cursor_x = x;
cursor_y = y;
if (last_mask != mask) {
last_pointer_click_time = dnow();
}
last_mask = mask;
/* record the x, y position for the rfb screen as well. */
cursor_position(x, y);
@ -226,11 +244,57 @@ void macosx_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
}
extern void macosxGCS_poll_pb(void);
int macosx_get_cursor_pos(int *x, int *y) {
macosxCG_get_cursor_pos(x, y);
if (nofb) {
/* good time to poll the pasteboard */
macosxGCS_poll_pb();
}
return 1;
}
static char *cuttext = NULL;
static int cutlen = 0;
void macosx_send_sel(char *str, int len) {
if (screen && all_clients_initialized()) {
if (cuttext) {
int n = cutlen;
if (len < n) {
n = len;
}
if (!memcmp(str, cuttext, (size_t) n)) {
/* the same text we set pasteboard to ... */
return;
}
}
if (debug_sel) {
rfbLog("macosx_send_sel: %d\n", len);
}
rfbSendServerCutText(screen, str, len);
}
}
void macosx_set_sel(char *str, int len) {
if (screen && all_clients_initialized()) {
if (cutlen <= len) {
if (cuttext) {
free(cuttext);
}
cutlen = 2*(len+1);
cuttext = (char *) calloc(cutlen, 1);
}
memcpy(cuttext, str, (size_t) len);
cuttext[len] = '\0';
if (debug_sel) {
rfbLog("macosx_set_sel: %d\n", len);
}
macosxGCS_set_pasteboard(str, len);
}
}
int macosx_get_cursor(void) {
return macosxCG_get_cursor();
}
@ -346,23 +410,13 @@ Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return,
*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 (k = CGS_levelmax - 1; k >= 0; 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
if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n);
cret[n++] = (Window) macwins[i].win;
}
}

@ -13,6 +13,8 @@ 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);
extern void macosx_send_sel(char *, int);
extern void macosx_set_sel(char *, int);

@ -44,6 +44,7 @@ static void macosxCG_callback(CGRectCount n, const CGRect *rects, void *dum) {
}
int dragum(void) {
#if 0
int x =200, y = 150, dy = 10, i;
CGPoint loc;
@ -58,6 +59,7 @@ int dragum(void) {
}
CGPostMouseEvent(loc, TRUE, 1, FALSE);
usleep(4*1000*1000);
#endif
return 0;
}
@ -85,6 +87,7 @@ void macosxCG_refresh_callback_off(void) {
}
extern int macosx_noscreensaver;
extern void macosxGCS_initpb(void);
void macosxCG_init(void) {
if (displayID == NULL) {
@ -106,6 +109,7 @@ void macosxCG_init(void) {
if (macosx_noscreensaver) {
macosxCGP_screensaver_timer_on();
}
macosxGCS_initpb();
}
}
@ -117,22 +121,63 @@ void macosxCG_fini(void) {
macosxCG_refresh_callback_off();
}
extern int dpy_x, dpy_y;
extern int client_count;
extern int dpy_x, dpy_y, bpp, wdpy_x, wdpy_y;
extern int client_count, nofb;
extern void do_new_fb(int);
extern int macosx_wait_for_switch, macosx_resize;
void macosxCG_event_loop(void) {
OSStatus rc;
int nbpp;
macosxGCS_poll_pb();
if (nofb) {
return;
}
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)) {
nbpp = macosxCG_CGDisplayBitsPerPixel();
if (nbpp > 0 && nbpp != bpp) {
if (macosx_resize) {
do_new_fb(1);
}
} else if (wdpy_x != (int) CGDisplayPixelsWide(displayID)) {
if (wdpy_y != (int) CGDisplayPixelsHigh(displayID)) {
if (macosx_wait_for_switch) {
int cnt = 0;
while (1) {
if(CGDisplayPixelsWide(displayID) > 0) {
if(CGDisplayPixelsHigh(displayID) > 0) {
usleep(500*1000);
break;
}
}
if ((cnt++ % 120) == 0) {
fprintf(stderr, "waiting for user to "
"switch back..\n");
}
sleep(1);
}
if (wdpy_x == (int) CGDisplayPixelsWide(displayID)) {
if (wdpy_y == (int) CGDisplayPixelsHigh(displayID)) {
fprintf(stderr, "we're back...\n");
return;
}
}
}
if (macosx_resize) {
do_new_fb(1);
}
}
}
}
@ -171,6 +216,16 @@ extern CGError CGSGetCurrentCursorLocation(CGSConnectionRef, CGPoint*);
extern int CGSCurrentCursorSeed(void);
extern int CGSHardwareCursorActive();
static unsigned int last_local_button_mask = 0;
static unsigned int last_local_mod_mask = 0;
static int last_local_x = 0;
static int last_local_y = 0;
extern unsigned int display_button_mask;
extern unsigned int display_mod_mask;
extern int got_local_pointer_input;
extern time_t last_local_input;
static CGPoint current_cursor_pos(void) {
CGPoint pos;
pos.x = 0;
@ -183,6 +238,25 @@ static CGPoint current_cursor_pos(void) {
if (CGSGetCurrentCursorLocation(conn, &pos) != kCGErrorSuccess) {
fprintf(stderr, "CGSGetCurrentCursorLocation error\n");
}
display_button_mask = GetCurrentButtonState();
#if 0
/* not used yet */
display_mod_mask = GetCurrentKeyModifiers();
#endif
if (last_local_button_mask != display_button_mask) {
got_local_pointer_input++;
last_local_input = time(NULL);
} else if (pos.x != last_local_x || pos.y != last_local_y) {
got_local_pointer_input++;
last_local_input = time(NULL);
}
last_local_button_mask = display_button_mask;
last_local_mod_mask = display_mod_mask;
last_local_x = pos.x;
last_local_y = pos.y;
return pos;
}
@ -199,29 +273,36 @@ extern int store_cursor(int serial, unsigned long *data, int w, int h, int cbpp,
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;
static int last_cursor_seed = -1;
static time_t last_fetch = 0;
time_t now = time(NULL);
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;
}
}
cursor_seed = CGSCurrentCursorSeed();
if (last_idx && cursor_seed == last_cursor_seed) {
if (now < last_fetch + 2) {
return which;
}
}
last_cursor_seed = cursor_seed;
last_fetch = now;
if (CGSGetGlobalCursorDataSize(conn, &datasize) != kCGErrorSuccess) {
fprintf(stderr, "CGSGetGlobalCursorDataSize error\n");
return which;
@ -239,7 +320,6 @@ int macosxCG_get_cursor(void) {
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);
@ -248,21 +328,25 @@ int macosxCG_get_cursor(void) {
return(which);
}
extern int macosx_mouse_wheel_speed;
extern int macosx_swap23;
extern int off_x, coff_x, off_y, coff_y;
void macosxCG_pointer_inject(int mask, int x, int y) {
int swap23 = 1, rc;
int swap23 = macosx_swap23, rc;
int s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4;
CGPoint loc;
int wheel_distance = 10;
int wheel_distance = macosx_mouse_wheel_speed;
static int cnt = 0;
loc.x = x;
loc.y = y;
if (swap23) {
s2 = 2;
s3 = 1;
}
loc.x = x + off_x + coff_x;
loc.y = y + off_y + coff_y;
if ((cnt++ % 10) == 0) {
macosxCGP_undim();
}

@ -15,6 +15,7 @@
extern CGDirectDisplayID displayID;
void macosxCGS_get_all_windows(void);
void macosxGCS_set_pasteboard(char *str, int len);
typedef CGError CGSError;
typedef long CGSWindowCount;
@ -79,12 +80,13 @@ void macosxCGS_get_all_windows(void) {
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 */
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 pulldown menu */
CGS_levels[CGS_levelmax++] = (int) kCGMainMenuWindowLevelKey; /* 24 ? */
CGS_levels[CGS_levelmax++] = (int) kCGModalPanelWindowLevel; /* 8 open dialog box */
CGS_levels[CGS_levelmax++] = (int) kCGFloatingWindowLevel; /* 3 ? */
CGS_levels[CGS_levelmax++] = (int) kCGNormalWindowLevel; /* 0 regular window */
}
if (cid == NULL) {
@ -152,5 +154,79 @@ if (db) fprintf(stderr, "i=%03d ID: %06d x: %03d y: %03d w: %03d h: %03d leve
}
}
#if 1
NSLock *pblock = nil;
NSString *pbstr = nil;
NSString *cuttext = nil;
int pbcnt = -1;
NSStringEncoding pbenc = NSWindowsCP1252StringEncoding;
void macosxGCS_initpb(void) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
pblock = [[NSLock alloc] init];
if (![NSPasteboard generalPasteboard]) {
fprintf(stderr, "macosxGCS_initpb: pasteboard inaccessible.\n");
pbcnt = 0;
pbstr = [[NSString alloc] initWithString:@"\e<PASTEBOARD INACCESSIBLE>\e"];
}
[pool release];
}
void macosxGCS_set_pasteboard(char *str, int len) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (pbcnt != 0) {
[pblock lock];
[cuttext release];
cuttext = [[NSString alloc] initWithData:[NSData dataWithBytes:str length:len] encoding: pbenc];
if ([[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]) {
NS_DURING
[[NSPasteboard generalPasteboard] setString:cuttext forType:NSStringPboardType];
NS_HANDLER
fprintf(stderr, "macosxGCS_set_pasteboard: problem writing to pasteboard\n");
NS_ENDHANDLER
} else {
fprintf(stderr, "macosxGCS_set_pasteboard: problem writing to pasteboard\n");
}
[cuttext release];
cuttext = nil;
[pblock unlock];
}
[pool release];
}
extern void macosx_send_sel(char *, int);
void macosxGCS_poll_pb(void) {
static double dlast = 0.0;
double now = dnow();
if (now < dlast + 0.2) {
return;
}
dlast = now;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[pblock lock];
if (pbcnt != [[NSPasteboard generalPasteboard] changeCount]) {
pbcnt = [[NSPasteboard generalPasteboard] changeCount];
[pbstr release];
pbstr = nil;
if ([[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]]) {
pbstr = [[[NSPasteboard generalPasteboard] stringForType:NSStringPboardType] copy];
if (pbstr) {
NSData *str = [pbstr dataUsingEncoding:pbenc allowLossyConversion:YES];
if ([str length]) {
macosx_send_sel((char *) [str bytes], [str length]);
}
}
}
}
[pblock unlock];
[pool release];
}
#endif
#endif /* __APPLE__ */

@ -4,6 +4,7 @@
/* -- macosxCGS.h -- */
extern void macosxCGS_get_all_windows(void);
extern void macosxGCS_set_pasteboard(char *str, int len);
#endif /* _X11VNC_MACOSXCGS_H */

@ -129,9 +129,14 @@ int pipeinput_int = 0;
int pipeinput_cons_fd = -1;
char *pipeinput_cons_dev = NULL;
int macosx_nodimming = 0;
int macosx_nodimming = 0; /* Some native MacOSX server settings. */
int macosx_nosleep = 0;
int macosx_noscreensaver = 0;
int macosx_wait_for_switch = 1;
int macosx_mouse_wheel_speed = 5;
int macosx_console = 0;
int macosx_swap23 = 1;
int macosx_resize = 1;
unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0;
@ -186,6 +191,7 @@ char *wireframe_copyrect_default = "always";
char *wireframe_copyrect_default = "never";
#endif
int wireframe_in_progress = 0;
int wireframe_local = 1;
/* T+B+L+R,tkey+presist_key,tmouse+persist_mouse */
char *scroll_copyrect_str = NULL;
@ -311,6 +317,8 @@ int watch_fbpm = 1; /* -nofbpm */
int watch_fbpm = 0;
#endif
int watch_dpms = 0; /* -dpms */
int watch_selection = 1; /* normal selection/cutbuffer maintenance */
int watch_primary = 1; /* more dicey, poll for changes in PRIMARY */
int watch_clipboard = 1;

@ -107,6 +107,11 @@ extern char *pipeinput_cons_dev;
extern int macosx_nodimming;
extern int macosx_nosleep;
extern int macosx_noscreensaver;
extern int macosx_wait_for_switch;
extern int macosx_mouse_wheel_speed;
extern int macosx_console;
extern int macosx_swap23;
extern int macosx_resize;
extern unsigned long subwin;
extern int subwin_wait_mapped;
@ -143,6 +148,7 @@ extern int cursor_shape_updates;
extern int use_xwarppointer;
extern int show_dragging;
extern int wireframe;
extern int wireframe_local;
extern char *wireframe_str;
extern char *wireframe_copyrect;
@ -231,6 +237,7 @@ extern int ui_skip;
extern int all_input;
extern int watch_fbpm;
extern int watch_dpms;
extern int watch_selection;
extern int watch_primary;

@ -4,14 +4,20 @@
void check_pm(void);
static void check_fbpm(void);
static void check_dpms(void);
#if LIBVNCSERVER_HAVE_FBPM
#include <X11/Xmd.h>
#include <X11/extensions/fbpm.h>
#endif
#if LIBVNCSERVER_HAVE_DPMS
#include <X11/extensions/dpms.h>
#endif
void check_pm(void) {
check_fbpm();
check_dpms();
/* someday dpms activities? */
}
@ -20,7 +26,7 @@ static void check_fbpm(void) {
#if LIBVNCSERVER_HAVE_FBPM
static int fbpm_capable = 0;
static time_t last_fbpm = 0;
int db = 1;
int db = 0;
CARD16 level;
BOOL enabled;
@ -28,12 +34,15 @@ static void check_fbpm(void) {
RAWFB_RET_VOID
if (! init_fbpm) {
if (getenv("FBPM_DEBUG")) {
db = atoi(getenv("FBPM_DEBUG"));
}
if (FBPMCapable(dpy)) {
fbpm_capable = 1;
rfbLog("X display is capable of FBPM.\n");
if (watch_fbpm) {
rfbLog("Preventing low-power FBPM modes when"
" VNC clients are connected.\n");
" clients are connected.\n");
}
} else {
if (! raw_fb_str) {
@ -95,3 +104,86 @@ static void check_fbpm(void) {
#endif
}
static void check_dpms(void) {
static int init_dpms = 0;
#if LIBVNCSERVER_HAVE_DPMS
static int dpms_capable = 0;
static time_t last_dpms = 0;
int db = 0;
CARD16 level;
BOOL enabled;
RAWFB_RET_VOID
if (! init_dpms) {
if (getenv("DPMS_DEBUG")) {
db = atoi(getenv("DPMS_DEBUG"));
}
if (DPMSCapable(dpy)) {
dpms_capable = 1;
rfbLog("X display is capable of DPMS.\n");
if (watch_dpms) {
rfbLog("Preventing low-power DPMS modes when"
" clients are connected.\n");
}
} else {
if (! raw_fb_str) {
rfbLog("X display is not capable of DPMS.\n");
}
dpms_capable = 0;
}
init_dpms = 1;
}
if (! watch_dpms) {
return;
}
if (! dpms_capable) {
return;
}
if (! client_count) {
return;
}
if (time(NULL) < last_dpms + 5) {
return;
}
last_dpms = time(NULL);
if (DPMSInfo(dpy, &level, &enabled)) {
if (db) fprintf(stderr, "DPMSInfo level: %d enabled: %d\n", level, enabled);
if (enabled && level != DPMSModeOn) {
char *from = "unknown-dpms-state";
XErrorHandler old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
if (level == DPMSModeStandby) {
from = "DPMSModeStandby";
} else if (level == DPMSModeSuspend) {
from = "DPMSModeSuspend";
} else if (level == DPMSModeOff) {
from = "DPMSModeOff";
}
rfbLog("switching DPMS state from %s to DPMSModeOn\n", from);
DPMSForceLevel(dpy, DPMSModeOn);
XSetErrorHandler(old_handler);
trapped_xerror = 0;
}
} else {
if (db) fprintf(stderr, "DPMSInfo failed.\n");
}
#else
RAWFB_RET_VOID
if (! init_dpms) {
if (! raw_fb_str) {
rfbLog("X DPMS extension not supported.\n");
}
init_dpms = 1;
}
#endif
}

@ -664,7 +664,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
}
if ((pipeinput_fh != NULL || pipeinput_int) && mask >= 0) {
pipe_pointer(mask, x, y, client);
pipe_pointer(mask, x, y, client); /* MACOSX here. */
if (! pipeinput_tee) {
if (! view_only || raw_fb) { /* raw_fb hack */
got_user_input++;

@ -2774,6 +2774,21 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: enabling -nowireframe mode.\n");
wireframe = 0;
} else if (!strcmp(p, "wireframelocal") || !strcmp(p, "wfl")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, wireframe_local);
goto qry;
}
rfbLog("remote_cmd: enabling -wireframelocal mode.\n");
wireframe_local = 1;
} else if (!strcmp(p, "nowireframelocal") || !strcmp(p, "nowfl")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !wireframe_local);
goto qry;
}
rfbLog("remote_cmd: enabling -nowireframelocal mode.\n");
wireframe_local = 0;
} else if (strstr(p, "wirecopyrect") == p) {
COLON_CHECK("wirecopyrect:")
if (query) {
@ -3385,6 +3400,21 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: turning on -nofbpm mode.\n");
watch_fbpm = 1;
} else if (!strcmp(p, "dpms")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !watch_dpms);
goto qry;
}
rfbLog("remote_cmd: turning off -nodpms mode.\n");
watch_dpms = 0;
} else if (!strcmp(p, "nodpms")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, watch_dpms);
goto qry;
}
rfbLog("remote_cmd: turning on -nodpms mode.\n");
watch_dpms = 1;
} else if (strstr(p, "fs") == p) {
COLON_CHECK("fs:")
if (query) {

@ -2356,15 +2356,17 @@ int copy_screen(void) {
if (! fs_factor) {
return 0;
}
if (debug_tiles) fprintf(stderr, "copy_screen\n");
if (unixpw_in_progress) return 0;
block_size = (dpy_x * (dpy_y/fs_factor) * pixelsize);
if (! main_fb) {
return 0;
}
block_size = ((dpy_y/fs_factor) * main_bytes_per_line);
fbp = main_fb;
y = 0;
@ -2404,7 +2406,7 @@ static void snap_all_rawfb(void) {
if (xform24to32 && bpp == 32) {
pixelsize = 3;
}
sz = dpy_x * dpy_y * pixelsize;
sz = dpy_y * snap->bytes_per_line;
if (wdpy_x > dpy_x || wdpy_y > dpy_y) {
sz = wdpy_x * wdpy_y * pixelsize;
@ -2452,7 +2454,7 @@ static void snap_all_rawfb(void) {
for (h = 0; h < dpy_y; h++) {
memcpy(dst, src, dpy_x * pixelsize);
src += wdpy_x * pixelsize;
dst += dpy_x * pixelsize;
dst += snap->bytes_per_line;
}
}
}
@ -2481,6 +2483,9 @@ int copy_snap(void) {
if (rawfb_reset) {
initialize_raw_fb(1);
}
if (raw_fb_bytes_per_line != snap->bytes_per_line) {
read_all_at_once = 0;
}
if (read_all_at_once) {
snap_all_rawfb();
} else {
@ -2496,11 +2501,12 @@ if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - st
return 0;
}
block_size = (dpy_x * (dpy_y/fs_factor) * pixelsize);
if (! snap_fb || ! snap || ! snaprect) {
return 0;
}
block_size = ((dpy_y/fs_factor) * snap->bytes_per_line);
fbp = snap_fb;
y = 0;
@ -2578,6 +2584,7 @@ static void nap_set(int tile_cnt) {
*/
void nap_sleep(int ms, int split) {
int i, input = got_user_input;
int gd = got_local_pointer_input;
for (i=0; i<split; i++) {
usleep(ms * 1000 / split);
@ -2587,6 +2594,9 @@ void nap_sleep(int ms, int split) {
if (input != got_user_input) {
break;
}
if (gd != got_local_pointer_input) {
break;
}
}
}
@ -2623,7 +2633,9 @@ static void nap_check(int tile_cnt) {
if (naptile && nap_ok && tile_cnt < naptile) {
int ms = napfac * waitms;
ms = ms > napmax ? napmax : ms;
if (now - last_input <= 2) {
if (now - last_input <= 3) {
nap_ok = 0;
} else if (now - last_local_input <= 3) {
nap_ok = 0;
} else {
nap_sleep(ms, 1);
@ -2942,11 +2954,15 @@ int scan_for_updates(int count_only) {
if (cmap8to24 && scan_count % 1 == 0) {
check_for_multivis();
}
#ifdef MACOSX
if (macosx_console) {
macosx_event_loop();
}
#endif
if (use_xdamage) {
/* first pass collecting DAMAGE events: */
#ifdef MACOSX
if (! dpy) {
macosx_event_loop();
if (macosx_console) {
collect_macosx_damage(-1, -1, -1, -1, 0);
} else
#endif
@ -2977,7 +2993,7 @@ int scan_for_updates(int count_only) {
*/
if (use_xdamage) {
#ifdef MACOSX
if (! dpy) {
if (macosx_console) {
;
} else
#endif

@ -867,7 +867,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
}
#ifdef MACOSX
if (raw_fb_addr != NULL && raw_fb_addr == macosx_get_fb_addr()) {
if (raw_fb_addr != NULL && macosx_console && raw_fb_addr == macosx_get_fb_addr()) {
raw_fb_addr = NULL;
}
#endif
@ -963,6 +963,7 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
raw_fb_fd = -1;
raw_fb_addr = NULL;
raw_fb_offset = 0;
raw_fb_bytes_per_line = 0;
last_mode = 0;
if (last_file) {
@ -1059,6 +1060,12 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
rfbLog("invalid rawfb str: %s\n", str);
clean_up_exit(1);
}
if (strrchr(q, '-')) {
char *q2 = strrchr(q, '-');
raw_fb_bytes_per_line = atoi(q2+1);
*q2 = '\0';
}
/* @WxHxB */
if (sscanf(q, "@%dx%dx%d", &w, &h, &b) != 3) {
rfbLogEnable(1);
@ -1145,11 +1152,13 @@ if (db) fprintf(stderr, "initialize_raw_fb reset\n");
q = strchr(str, ':');
q++;
macosx_console = 0;
if (strstr(q, "macosx:") == q) {
/* mmap:macosx:/dev/null@... */
q += strlen("macosx:");