summaryrefslogtreecommitdiffstats
path: root/x11vnc/macosxCG.c
diff options
context:
space:
mode:
authorrunge <runge>2006-11-13 15:33:00 +0000
committerrunge <runge>2006-11-13 15:33:00 +0000
commit4a83f87609b9d53b2983806be58ccd02498a5cd3 (patch)
treea79c96930a97fb162edd1765adece43425f8db8a /x11vnc/macosxCG.c
parent5f9693d4a2c511f8f2ea069373807c5f36ac1459 (diff)
downloadlibtdevnc-4a83f87609b9d53b2983806be58ccd02498a5cd3.tar.gz
libtdevnc-4a83f87609b9d53b2983806be58ccd02498a5cd3.zip
x11vnc: Native Mac OS X support.
Diffstat (limited to 'x11vnc/macosxCG.c')
-rw-r--r--x11vnc/macosxCG.c508
1 files changed, 508 insertions, 0 deletions
diff --git a/x11vnc/macosxCG.c b/x11vnc/macosxCG.c
new file mode 100644
index 0000000..4ecf2c2
--- /dev/null
+++ b/x11vnc/macosxCG.c
@@ -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__ */
+
+