diff options
author | runge <runge@karlrunge.com> | 2010-12-29 10:05:52 -0500 |
---|---|---|
committer | runge <runge@karlrunge.com> | 2010-12-29 10:05:52 -0500 |
commit | 596331a5c3124f080cdcbb400c188c095048ef35 (patch) | |
tree | 66eb904b6c0181703d8f3c9ec81352a970d52601 /x11vnc/macosxCG.c | |
parent | 0c03b989407f9e5ea66b403011baaaad09fcd536 (diff) | |
download | libvncserver-596331a5c3124f080cdcbb400c188c095048ef35.zip libvncserver-596331a5c3124f080cdcbb400c188c095048ef35.tar.gz |
x11vnc: Use opengl to read screen on macosx. non-deprecated macosx interfaces for input injection.
Diffstat (limited to 'x11vnc/macosxCG.c')
-rw-r--r-- | x11vnc/macosxCG.c | 423 |
1 files changed, 373 insertions, 50 deletions
diff --git a/x11vnc/macosxCG.c b/x11vnc/macosxCG.c index a465493..12041e0 100644 --- a/x11vnc/macosxCG.c +++ b/x11vnc/macosxCG.c @@ -62,7 +62,7 @@ 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); +void macosxCG_keysym_inject(int down, unsigned int keysym); void macosxCG_keycode_inject(int down, int keycode); CGDirectDisplayID displayID = 0; @@ -81,27 +81,31 @@ 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; +> +> if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I/opt/local/include -I/opt/local/include -ObjC -g -O2 -Wall -MT x11vnc-macosxCG.o -MD -MP -MF ".deps/x11vnc-macosxCG.Tpo" -c -o x11vnc-macosxCG.o `test -f 'macosxCG.c' || echo './'`macosxCG.c; \ +> then mv -f ".deps/x11vnc-macosxCG.Tpo" ".deps/x11vnc-macosxCG.Po"; else rm -f ".deps/x11vnc-macosxCG.Tpo"; exit 1; fi +> macosxCG.c:149: warning: CGSetLocalEventsSuppressionInterval is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:373) +> macosxCG.c:150: warning: CGSetLocalEventsFilterDuringSuppressionState is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:366) +> macosxCG.c:153: warning: CGSetLocalEventsFilterDuringSuppressionState is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:366) +> macosxCG.c:244: warning: CGDisplayBaseAddress is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:466) +> macosxCG.c:254: warning: CGDisplayBitsPerPixel is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:517) +> macosxCG.c:257: warning: CGDisplayBitsPerSample is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:522) +> macosxCG.c:260: warning: CGDisplaySamplesPerPixel is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:526) +> macosxCG.c:263: warning: CGDisplayBytesPerRow is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGDirectDisplay.h:476) +> macosxCG.c:419: warning: CGPostScrollWheelEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:327) +> macosxCG.c:422: warning: CGPostScrollWheelEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:327) +> macosxCG.c:425: warning: CGPostMouseEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:307) +> macosxCG.c:641: warning: CGPostKeyboardEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:333) +> macosxCG.c:661: warning: CGPostKeyboardEvent is deprecated (declared at /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers/CGRemoteOperation.h:333) +> + +X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS +X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS +X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER +X11VNC_MACOSX_NO_DEPRECATED - CGDirectDisplayID displayID2 = kCGDirectMainDisplay; -#ifdef X11VNC_MACOSX_USE_GETMAINDEVICE - (void) GetMainDevice(); -#endif - - 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); #endif - return 0; -} static int callback_set = 0; extern int nofb; @@ -112,7 +116,7 @@ void macosxCG_refresh_callback_on(void) { } if (! callback_set) { - if (1) macosx_log("macosxCG_callback: register\n"); + if (1) macosx_log("macosxCG_refresh_callback: register\n"); CGRegisterScreenRefreshCallback(macosxCG_callback, NULL); } callback_set = 1; @@ -120,44 +124,93 @@ void macosxCG_refresh_callback_on(void) { void macosxCG_refresh_callback_off(void) { if (callback_set) { - if (1) macosx_log("macosxCG_callback: unregister\n"); + if (1) macosx_log("macosxCG_refresh_callback: unregister\n"); CGUnregisterScreenRefreshCallback(macosxCG_callback, NULL); } callback_set = 0; } extern int macosx_noscreensaver; +extern int macosx_read_opengl; +extern int macosx_read_rawfb; + extern void macosxGCS_initpb(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); +extern void macosx_opengl_init(void); +extern void macosx_opengl_fini(void); + +int x11vnc_macosx_no_deprecated_localevents = 0; +int x11vnc_macosx_no_deprecated_postevents = 0; +int x11vnc_macosx_no_deprecated_framebuffer = 0; void macosxCG_init(void) { + + x11vnc_macosx_no_deprecated_localevents = 0; + x11vnc_macosx_no_deprecated_postevents = 0; + x11vnc_macosx_no_deprecated_framebuffer = 0; + + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + x11vnc_macosx_no_deprecated_localevents = 1; + } + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + x11vnc_macosx_no_deprecated_postevents = 1; + } + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + x11vnc_macosx_no_deprecated_framebuffer = 1; + } + if (displayID == 0) { macosx_log("macosxCG_init: initializing display.\n"); -#if 0 - dragum(); -#endif displayID = kCGDirectMainDisplay; #ifdef X11VNC_MACOSX_USE_GETMAINDEVICE + /* not sure this ever did anything. */ (void) GetMainDevice(); #endif + if (displayID == 0) { + macosx_log("macosxCG_init: could not get kCGDirectMainDisplay / CGMainDisplayID() display.\n"); + exit(1); + } + +#if X11VNC_MACOSX_NO_DEPRECATED_LOCALEVENTS || X11VNC_MACOSX_NO_DEPRECATED + macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsSuppressionInterval()\n"); + macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsFilterDuringSupressionState()\n"); +#else + if (!x11vnc_macosx_no_deprecated_localevents) { + CGSetLocalEventsSuppressionInterval(0.0); + CGSetLocalEventsFilterDuringSupressionState( + kCGEventFilterMaskPermitAllEvents, + kCGEventSupressionStateSupressionInterval); + CGSetLocalEventsFilterDuringSupressionState( + kCGEventFilterMaskPermitAllEvents, + kCGEventSupressionStateRemoteMouseDrag); + } else { + macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsSuppressionInterval()\n"); + macosx_log("NO_DEPRECATED_LOCALEVENTS: not calling CGSetLocalEventsFilterDuringSupressionState()\n"); + } +#endif - CGSetLocalEventsSuppressionInterval(0.0); - CGSetLocalEventsFilterDuringSupressionState( - kCGEventFilterMaskPermitAllEvents, - kCGEventSupressionStateSupressionInterval); - CGSetLocalEventsFilterDuringSupressionState( - kCGEventFilterMaskPermitAllEvents, - kCGEventSupressionStateRemoteMouseDrag); + macosx_opengl_init(); + + if (!macosx_read_opengl) { + char *addr = macosxCG_get_fb_addr(); + if (addr == NULL) { + macosx_log("macosxCG_init: could not get raw framebuffer address / CGDisplayBaseAddress().\n"); + exit(1); + } + macosx_read_rawfb = 1; + macosx_log("macosxCG_init: using raw framebuffer address for screen capture.\n"); + } macosxCGP_init_dimming(); if (macosx_noscreensaver) { macosxCGP_screensaver_timer_on(); } + macosxGCS_initpb(); } } @@ -168,6 +221,8 @@ void macosxCG_fini(void) { macosxCGP_screensaver_timer_off(); } macosxCG_refresh_callback_off(); + macosx_opengl_fini(); + displayID = 0; } extern int dpy_x, dpy_y, bpp, wdpy_x, wdpy_y; @@ -187,6 +242,7 @@ extern void clean_up_exit(int ret); void macosxCG_event_loop(void) { OSStatus rc; int nbpp; + static int nbpp_save = -1; macosxGCS_poll_pb(); if (nofb) { @@ -203,18 +259,22 @@ void macosxCG_event_loop(void) { nbpp = macosxCG_CGDisplayBitsPerPixel(); + if (nbpp_save < 0) { + nbpp_save = nbpp; + } - if (nbpp > 0 && nbpp != bpp) { + if (nbpp > 0 && nbpp != nbpp_save) { + nbpp_save = nbpp; if (macosx_resize) { do_new_fb(1); } - } else if (wdpy_x != (int) CGDisplayPixelsWide(displayID)) { - if (wdpy_y != (int) CGDisplayPixelsHigh(displayID)) { + } else if (wdpy_x != macosxCG_CGDisplayPixelsWide()) { + if (wdpy_y != macosxCG_CGDisplayPixelsHigh()) { if (macosx_wait_for_switch) { int cnt = 0; while (1) { - if(CGDisplayPixelsWide(displayID) > 0) { - if(CGDisplayPixelsHigh(displayID) > 0) { + if(macosxCG_CGDisplayPixelsWide() > 0) { + if(macosxCG_CGDisplayPixelsHigh() > 0) { usleep(500*1000); break; } @@ -225,8 +285,8 @@ void macosxCG_event_loop(void) { } sleep(1); } - if (wdpy_x == (int) CGDisplayPixelsWide(displayID)) { - if (wdpy_y == (int) CGDisplayPixelsHigh(displayID)) { + if (wdpy_x == macosxCG_CGDisplayPixelsWide()) { + if (wdpy_y == macosxCG_CGDisplayPixelsHigh()) { macosx_log("we're back...\n"); return; } @@ -237,32 +297,100 @@ void macosxCG_event_loop(void) { } } } + if (nbpp > 0) { + nbpp_save = nbpp; + } } +extern int macosx_no_rawfb; +extern int macosx_read_opengl; +extern int macosx_opengl_get_width(); +extern int macosx_opengl_get_height(); +extern int macosx_opengl_get_bpp(); +extern int macosx_opengl_get_bps(); +extern int macosx_opengl_get_spp(); + +#if X11VNC_MACOSX_NO_DEPRECATED_FRAMEBUFFER || X11VNC_MACOSX_NO_DEPRECATED + char *macosxCG_get_fb_addr(void) { - macosxCG_init(); + return NULL; +} +int macosxCG_CGDisplayPixelsWide(void) { + return macosx_opengl_get_width(); +} +int macosxCG_CGDisplayPixelsHigh(void) { + return macosx_opengl_get_height(); +} +int macosxCG_CGDisplayBitsPerPixel(void) { + return macosx_opengl_get_bpp(); +} +int macosxCG_CGDisplayBitsPerSample(void) { + return macosx_opengl_get_bps(); +} +int macosxCG_CGDisplaySamplesPerPixel(void) { + return macosx_opengl_get_spp(); +} +int macosxCG_CGDisplayBytesPerRow(void) { + return macosx_opengl_get_width() * macosx_opengl_get_bpp() / 8; +} + +#else + +char *macosxCG_get_fb_addr(void) { + if (x11vnc_macosx_no_deprecated_framebuffer) { + macosx_log("CGDisplayBaseAddress disabled by env. var\n"); + return NULL; + } + if (macosx_no_rawfb) { + macosx_log("CGDisplayBaseAddress disabled by user.\n"); + return NULL; + } + if (macosx_read_opengl) { + macosx_log("CGDisplayBaseAddress disabled by OpenGL.\n"); + return NULL; + } return (char *) CGDisplayBaseAddress(displayID); } int macosxCG_CGDisplayPixelsWide(void) { + if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_width(); + } return (int) CGDisplayPixelsWide(displayID); } int macosxCG_CGDisplayPixelsHigh(void) { + if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_height(); + } return (int) CGDisplayPixelsHigh(displayID); } int macosxCG_CGDisplayBitsPerPixel(void) { + if ((0 && macosx_read_opengl) || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_bpp(); + } return (int) CGDisplayBitsPerPixel(displayID); } int macosxCG_CGDisplayBitsPerSample(void) { + if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_bps(); + } return (int) CGDisplayBitsPerSample(displayID); } int macosxCG_CGDisplaySamplesPerPixel(void) { + if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_spp(); + } return (int) CGDisplaySamplesPerPixel(displayID); } int macosxCG_CGDisplayBytesPerRow(void) { + if (macosx_read_opengl || x11vnc_macosx_no_deprecated_framebuffer) { + return macosx_opengl_get_width() * macosx_opengl_get_bpp()/8; + } return (int) CGDisplayBytesPerRow(displayID);; } +#endif + typedef int CGSConnectionRef; static CGSConnectionRef conn = 0; extern CGError CGSNewConnection(void*, CGSConnectionRef*); @@ -358,6 +486,8 @@ int macosxCG_get_cursor(void) { } } + /* XXX all of these interfaces are undocumented. */ + cursor_seed = CGSCurrentCursorSeed(); if (last_idx && cursor_seed == last_cursor_seed) { if (now < last_fetch + 2) { @@ -376,6 +506,10 @@ int macosxCG_get_cursor(void) { err = CGSGetGlobalCursorData(conn, data, &datasize, &row_bytes, &rect, &hot, &cdepth, &comps, &bpcomp); +#if 0 + fprintf(stderr, "datasize: %d row_bytes: %d cdepth: %d comps: %d bpcomp: %d w: %d h: %d\n", + datasize, row_bytes, cdepth, comps, bpcomp, (int) rect.size.width, (int) rect.size.height); +#endif if (err != kCGErrorSuccess) { macosx_log("CGSGetGlobalCursorData error\n"); return which; @@ -385,6 +519,21 @@ int macosxCG_get_cursor(void) { cdepth = 32; } + if (sizeof(long) == 8 && comps * bpcomp <= 32) { + /* pad it out to unsigned long array size (like xfixes) */ + int i; + unsigned char *dsave; + unsigned char *data64 = (unsigned char*) malloc(2 *datasize); + unsigned int *uI = (unsigned int *) data; + unsigned long *uL = (unsigned long *) data64; + for (i=0; i < datasize/4; i++) { + uL[i] = uI[i]; + } + dsave = data; + data = data64; + free(dsave); + } + which = store_cursor(cursor_seed, (unsigned long*) data, (int) rect.size.width, (int) rect.size.height, cdepth, (int) hot.x, (int) hot.y); @@ -396,12 +545,137 @@ extern int macosx_mouse_wheel_speed; extern int macosx_swap23; extern int off_x, coff_x, off_y, coff_y; +extern int debug_pointer; + +static void CGPostScrollWheelEvent_wr(CGWheelCount wheel_count, int wheel_distance) { + static int post_mode = -1, mcnt = 0; + +#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED + if (post_mode < 0) { + post_mode = 1; + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + post_mode = 0; + } + } + + if (post_mode) { + if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGPostScrollWheelEvent()\n"); + CGPostScrollWheelEvent(wheel_count, wheel_distance); + } else +#endif + { + /* XXX 10.5 and later */ +#ifndef X11VNC_MACOSX_NO_CGEVENTCREATESCROLLWHEELEVENT + CGEventRef event; + event = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheel_count, wheel_distance); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } +#endif + if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGEventCreateScrollWheelEvent()\n"); + } +} + +static void CGPostMouseEvent_wr(CGPoint loc, int update, int count, int d1, int d2, int d3, int p1, int p2, int p3) { + static int post_mode = -1, mcnt = 0; + +#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED + if (post_mode < 0) { + post_mode = 1; + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + post_mode = 0; + } + } + + if (post_mode) { + if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGPostMouseEvent()\n"); + CGPostMouseEvent(loc, update, count, d1, d2, d3); + } else +#endif + { + /* XXX 10.4 and later */ +#ifndef X11VNC_MACOSX_NO_CGEVENTCREATEMOUSEEVENT + CGEventRef event; + static int xp = -1, yp; + + if (xp == -1) { + xp = loc.x; + yp = loc.y; + } + if (xp != loc.x || yp != loc.y) { + int moved = 0; + if (p1 && p1 == d1) { + event = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDragged, loc, 0); + if (event != NULL) { + moved = 1; + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + if (p3 && p3 == d3) { + event = CGEventCreateMouseEvent(NULL, kCGEventOtherMouseDragged, loc, 0); + if (event != NULL) { + moved = 1; + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + if (p2 && p2 == d2) { + event = CGEventCreateMouseEvent(NULL, kCGEventRightMouseDragged, loc, 0); + if (event != NULL) { + moved = 1; + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + if (!moved) { + event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, loc, 0); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + } + xp = loc.x; + yp = loc.y; + if (p1 != d1) { + CGEventType type = (!p1 && d1) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp; + event = CGEventCreateMouseEvent(NULL, type, loc, 0); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + if (p3 != d3) { + CGEventType type = (!p3 && d3) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp; + event = CGEventCreateMouseEvent(NULL, type, loc, kCGMouseButtonCenter); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } + if (p2 != d2) { + CGEventType type = (!p2 && d2) ? kCGEventRightMouseDown : kCGEventRightMouseUp; + event = CGEventCreateMouseEvent(NULL, type, loc, 0); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } + } +#endif + if (mcnt++ < 10 || debug_pointer) fprintf(stderr, "CGEventCreateMouseEvent()\n"); + } +} + void macosxCG_pointer_inject(int mask, int x, int y) { int swap23 = macosx_swap23; int s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4; CGPoint loc; int wheel_distance = macosx_mouse_wheel_speed; static int cnt = 0; + static int first = 1, prev1 = 0, prev2 = 0, prev3 = 0; + int curr1, curr2, curr3; if (swap23) { s2 = 2; @@ -416,17 +690,28 @@ void macosxCG_pointer_inject(int mask, int x, int y) { } if ((mask & (1 << s4))) { - CGPostScrollWheelEvent(1, wheel_distance); + CGPostScrollWheelEvent_wr(1, wheel_distance); } if ((mask & (1 << s5))) { - CGPostScrollWheelEvent(1, -wheel_distance); + CGPostScrollWheelEvent_wr(1, -wheel_distance); } - - CGPostMouseEvent(loc, TRUE, 3, - (mask & (1 << s1)) ? TRUE : FALSE, - (mask & (1 << s2)) ? TRUE : FALSE, - (mask & (1 << s3)) ? TRUE : FALSE - ); + + curr1 = (mask & (1 << s1)) ? TRUE : FALSE; + curr2 = (mask & (1 << s2)) ? TRUE : FALSE; + curr3 = (mask & (1 << s3)) ? TRUE : FALSE; + + if (first) { + prev1 = curr1; + prev2 = curr2; + prev3 = curr3; + first = 0; + } + + CGPostMouseEvent_wr(loc, TRUE, 3, curr1, curr2, curr3, prev1, prev2, prev3); + + prev1 = curr1; + prev2 = curr2; + prev3 = curr3; } #define keyTableSize 0xFFFF @@ -634,14 +919,48 @@ void macosxCG_init_key_table(void) { extern void init_key_table(void); extern int macosx_us_kbd; +extern int debug_keyboard; + +void CGPostKeyboardEvent_wr(CGCharCode keyChar, CGKeyCode keyCode, int down) { + static int post_mode = -1, mcnt = 0; + +#if !X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS && !X11VNC_MACOSX_NO_DEPRECATED + if (post_mode < 0) { + post_mode = 1; + if (getenv("X11VNC_MACOSX_NO_DEPRECATED_POSTEVENTS") || getenv("X11VNC_MACOSX_NO_DEPRECATED")) { + post_mode = 0; + } + } + + if (post_mode) { + if (mcnt++ < 10 || debug_keyboard) fprintf(stderr, "CGPostKeyboardEvent(keyChar=%d, keyCode=%d, down=%d)\n", keyChar, keyCode, down); + CGPostKeyboardEvent(keyChar, keyCode, down); + } else +#endif + { + /* XXX 10.4 and later */ +#ifndef X11VNC_MACOSX_NO_CGEVENTCREATEKEYBOARDEVENT + CGEventRef event; + event = CGEventCreateKeyboardEvent(NULL, keyCode, down); + if (event != NULL) { + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + } +#endif + if (mcnt++ < 10 || debug_keyboard) fprintf(stderr, "CGEventCreateKeyboardEvent(NULL, keyCode=%d, down=%d)\n", keyCode, down); + } +} + void macosxCG_keycode_inject(int down, int keycode) { CGKeyCode keyCode = (CGKeyCode) keycode; CGCharCode keyChar = 0; - CGPostKeyboardEvent(keyChar, keyCode, down); + if (debug_keyboard) fprintf(stderr, "macosxCG_keycode_inject(down=%d, keycode=%d)\n", down, keycode); + + CGPostKeyboardEvent_wr(keyChar, keyCode, down); } -void macosxCG_key_inject(int down, unsigned int keysym) { +void macosxCG_keysym_inject(int down, unsigned int keysym) { CGKeyCode keyCode = keyTable[(unsigned short)keysym]; CGCharCode keyChar = 0; #if 0 @@ -651,14 +970,18 @@ void macosxCG_key_inject(int down, unsigned int keysym) { init_key_table(); + if (debug_keyboard) fprintf(stderr, "macosxCG_keysym_inject(down=%d, keysym=%d)\n", down, (int) keysym); + if (keysym < 0xFF && macosx_us_kbd) { keyChar = (CGCharCode) keysym; + if (debug_keyboard) fprintf(stderr, "macosxCG_keysym_inject keyChar=>%d\n", (int) keyChar); } if (keyCode == 0xFFFF) { return; } macosxCGP_undim(); - CGPostKeyboardEvent(keyChar, keyCode, down); + + CGPostKeyboardEvent_wr(keyChar, keyCode, down); } #endif /* __APPLE__ */ |