parent
5f9693d4a2
commit
4a83f87609
File diff suppressed because it is too large
Load Diff
@ -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 */
|
Loading…
Reference in new issue