diff options
Diffstat (limited to 'x11vnc/macosx.c')
-rw-r--r-- | x11vnc/macosx.c | 304 |
1 files changed, 282 insertions, 22 deletions
diff --git a/x11vnc/macosx.c b/x11vnc/macosx.c index 647e62c..86833b9 100644 --- a/x11vnc/macosx.c +++ b/x11vnc/macosx.c @@ -36,6 +36,12 @@ int macosx_valid_window(Window, XWindowAttributes*); Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return, Window **children_return, unsigned int *nchildren_return); +void macosx_add_mapnotify(Window win, int level, int map); +void macosx_add_create(Window win, int level); +void macosx_add_destroy(Window win, int level); +void macosx_add_visnotify(Window win, int level, int obscured); +int macosx_checkevent(XEvent *ev); + #if (! DOMAC) void macosx_event_loop(void) { @@ -72,6 +78,22 @@ Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return, Window **children_return, unsigned int *nchildren_return) { return (Status) 0; } +void macosx_add_mapnotify(Window win, int level, int map) { + return; +} +void macosx_add_create(Window win, int level) { + return; +} +void macosx_add_destroy(Window win, int level) { + return; +} +void macosx_add_visnotify(Window win, int level, int obscured) { + return; +} + +int macosx_checkevent(XEvent *ev) { + return 0; +} int dragum(void) {return 1;} @@ -169,6 +191,8 @@ char *macosx_console_guess(char *str, int *fd) { return q; } +Window macosx_click_frame = None; + void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) { allowed_input_t input; static int last_mask = 0; @@ -197,6 +221,16 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) { last_pointer_client = client; last_pointer_time = time(NULL); } + if (last_mask != mask) { + fprintf(stderr, "about to inject mask change %d -> %d: %.4f\n", last_mask, mask, dnowx()); + if (mask) { + int px, py, x, y, w, h; + macosx_click_frame = None; + if (!macosx_get_wm_frame_pos(&px, &py, &x, &y, &w, &h, &macosx_click_frame, NULL)) { + macosx_click_frame = None; + } + } + } macosxCG_pointer_inject(mask, x, y); @@ -209,6 +243,19 @@ void macosx_pointer_command(int mask, int x, int y, rfbClientPtr client) { if (last_mask != mask) { last_pointer_click_time = dnow(); + if (ncache > 0) { + /* XXX Y */ + int i; +fprintf(stderr, "about to get all windows: %.4f\n", dnowx()); + for (i=0; i < 2; i++) { + macosxCGS_get_all_windows(); + fprintf(stderr, "!"); + if (macosx_checkevent(NULL)) { + break; + } + } +fprintf(stderr, "\ndone: %.4f\n", dnowx()); + } } last_mask = mask; @@ -299,11 +346,130 @@ int macosx_get_cursor(void) { return macosxCG_get_cursor(); } +typedef struct evdat { + int win; + int map; + int level; + int vis; + int type; +} evdat_t; + +#define MAX_EVENTS 1024 +evdat_t mac_events[MAX_EVENTS]; +int mac_events_ptr = 0; +int mac_events_last = 0; + +void macosx_add_mapnotify(Window win, int level, int map) { + int i = mac_events_last++; + mac_events[i].win = win; + mac_events[i].level = level; + + if (map) { + mac_events[i].type = MapNotify; + } else { + mac_events[i].type = UnmapNotify; + } + mac_events[i].map = map; + mac_events[i].vis = -1; + + mac_events_last = mac_events_last % MAX_EVENTS; + + return; +} + +void macosx_add_create(Window win, int level) { + int i = mac_events_last++; + mac_events[i].win = win; + mac_events[i].level = level; + + mac_events[i].type = CreateNotify; + mac_events[i].map = -1; + mac_events[i].vis = -1; + + mac_events_last = mac_events_last % MAX_EVENTS; + + return; +} + +void macosx_add_destroy(Window win, int level) { + int i = mac_events_last++; + mac_events[i].win = win; + mac_events[i].level = level; + + mac_events[i].type = DestroyNotify; + mac_events[i].map = -1; + mac_events[i].vis = -1; + + mac_events_last = mac_events_last % MAX_EVENTS; + + return; +} + +void macosx_add_visnotify(Window win, int level, int obscured) { + int i = mac_events_last++; + mac_events[i].win = win; + mac_events[i].level = level; + + mac_events[i].type = VisibilityNotify; + mac_events[i].map = -1; + + mac_events[i].vis = 1; + if (obscured == 0) { + mac_events[i].vis = VisibilityUnobscured; + } else if (obscured == 1) { + mac_events[i].vis = VisibilityPartiallyObscured; + } else if (obscured == 2) { + mac_events[i].vis = VisibilityFullyObscured; /* NI */ + } + + mac_events_last = mac_events_last % MAX_EVENTS; + + return; +} + +int macosx_checkevent(XEvent *ev) { + int i = mac_events_ptr; + + if (mac_events_ptr == mac_events_last) { + return 0; + } + if (ev == NULL) { + return mac_events[i].type; + } + + ev->xany.window = mac_events[i].win; + + if (mac_events[i].type == CreateNotify) { + ev->type = CreateNotify; + ev->xany.window = rootwin; + ev->xcreatewindow.window = mac_events[i].win; + } else if (mac_events[i].type == DestroyNotify) { + ev->type = DestroyNotify; + ev->xdestroywindow.window = mac_events[i].win; + } else if (mac_events[i].type == VisibilityNotify) { + ev->type = VisibilityNotify; + ev->xvisibility.state = mac_events[i].vis; + } else if (mac_events[i].type == MapNotify) { + ev->type = MapNotify; + } else if (mac_events[i].type == UnmapNotify) { + ev->type = UnmapNotify; + } else { + fprintf(stderr, "unknown macosx_checkevent: %d\n", mac_events[i].type); + } + mac_events_ptr++; + mac_events_ptr = mac_events_ptr % MAX_EVENTS; + + return mac_events[i].type; +} + typedef struct windat { int win; int x, y; int width, height; int level; + int mapped; + int clipped; + int ncache_only; } windat_t; extern int macwinmax; @@ -313,19 +479,13 @@ 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; + int idx = -1, 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; - } + for (k = 0; k<macwinmax; k++) { + if (! macwins[k].mapped) { + continue; } x1 = macwins[k].x; x2 = macwins[k].x + macwins[k].width; @@ -362,19 +522,38 @@ int macosx_valid_window(Window w, XWindowAttributes* a) { 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 (last_idx >= 0 && last_idx < macwinmax) { + if (macwins[last_idx].win == win) { + idx = last_idx; + } + } + + if (idx < 0) { + idx = macosxCGS_get_qlook(w); + if (idx >= 0 && idx < macwinmax) { + if (macwins[idx].win != win) { + idx = -1; } + } else { + idx = -1; } - if (macwins[k].win == win) { - idx = k; - break; + } + + if (idx < 0) { + for (i = 0; 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) { @@ -388,7 +567,11 @@ int macosx_valid_window(Window w, XWindowAttributes* a) { a->depth = depth; a->border_width = 0; a->backing_store = 0; - a->map_state = IsViewable; + if (macwins[idx].mapped) { + a->map_state = IsViewable; + } else { + a->map_state = IsUnmapped; + } last_idx = idx; @@ -415,6 +598,7 @@ Status macosx_xquerytree(Window w, Window *root_return, Window *parent_return, n = 0; for (k = CGS_levelmax - 1; k >= 0; k--) { for (i = macwinmax - 1; i >= 0; i--) { + if (n >= QTMAX) break; if (macwins[i].level == CGS_levels[k]) { if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n); cret[n++] = (Window) macwins[i].win; @@ -427,5 +611,81 @@ if (0) fprintf(stderr, "k=%d i=%d n=%d\n", k, i, n); return (Status) 1; } +int macosx_check_offscreen(int win) { + sraRegionPtr r0, r1; + int x1, y1, x2, y2; + int ret; + int i = macosxCGS_find_index(win); + + if (i < 0) { + return 0; + } + + x1 = macwins[i].x; + y1 = macwins[i].y; + x2 = macwins[i].x + macwins[i].width; + y2 = macwins[i].y + macwins[i].height; + + r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); + r1 = sraRgnCreateRect(x1, y1, x2, y2); + + if (sraRgnAnd(r1, r0)) { + ret = 0; + } else { + ret = 1; + } + sraRgnDestroy(r0); + sraRgnDestroy(r1); + + return ret; +} + +int macosx_check_clipped(int win, int *list, int n) { + sraRegionPtr r0, r1, r2; + int x1, y1, x2, y2; + int ret = 0; + int k, j, i = macosxCGS_find_index(win); + + if (i < 0) { + return 0; + } + + x1 = macwins[i].x; + y1 = macwins[i].y; + x2 = macwins[i].x + macwins[i].width; + y2 = macwins[i].y + macwins[i].height; + + r0 = sraRgnCreateRect(0, 0, dpy_x, dpy_y); + r1 = sraRgnCreateRect(x1, y1, x2, y2); + sraRgnAnd(r1, r0); + + for (k = 0; k < n; k++) { + j = macosxCGS_find_index(list[k]); /* XXX slow? */ + if (j < 0) { + continue; + } + x1 = macwins[j].x; + y1 = macwins[j].y; + x2 = macwins[j].x + macwins[j].width; + y2 = macwins[j].y + macwins[j].height; + r2 = sraRgnCreateRect(x1, y1, x2, y2); + if (sraRgnAnd(r2, r1)) { + ret = 1; + sraRgnDestroy(r2); +//fprintf(stderr, "macosx_check_clipped: %4d %4d -- CLIP\n", win, list[k]); + break; + } +//fprintf(stderr, "macosx_check_clipped: %4d %4d -- -no-\n", win, list[k]); + sraRgnDestroy(r2); + } + sraRgnDestroy(r0); + sraRgnDestroy(r1); + +//fprintf(stderr, "macosx_check_clipped: %4d -- CLIP: %s\n", win, ret ? "yes" : "no"); + + return ret; +} + + #endif /* LIBVNCSERVER_HAVE_MACOSX_NATIVE_DISPLAY */ |