diff options
author | dscho <dscho> | 2001-08-01 11:52:01 +0000 |
---|---|---|
committer | dscho <dscho> | 2001-08-01 11:52:01 +0000 |
commit | 757fdc2454a97890c119cca8662b8d1763265e9a (patch) | |
tree | 44256826d7aafaa816041a18fa0405097f2ed4cd /mac.c | |
download | libtdevnc-757fdc2454a97890c119cca8662b8d1763265e9a.tar.gz libtdevnc-757fdc2454a97890c119cca8662b8d1763265e9a.zip |
Initial revision
Diffstat (limited to 'mac.c')
-rw-r--r-- | mac.c | 388 |
1 files changed, 388 insertions, 0 deletions
@@ -0,0 +1,388 @@ + +/* + * OSXvnc Copyright (C) 2001 Dan McGuirk <[email protected]>. + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * Cut in two parts by Johannes Schindelin (2001): libvncserver and OSXvnc. + * + * + * This file implements every system specific function for Mac OS X. + * + * It includes the init function: + * + void rfbScreenInit(void) + * + * the function to get the address of the framebuffer: + * + char *rfbGetFramebuffer(void) + * + * keyboard functions: + * + void KbdAddEvent(down, keySym, cl) + Bool down; + KeySym keySym; + rfbClientPtr cl; + void KbdReleaseAllKeys() + * + * the mouse functions: + * + void PtrAddEvent(buttonMask, x, y, cl) + int buttonMask; + int x; + int y; + rfbClientPtr cl; + * + * and the EventLoop: + * + void runEventLoop() + * + * These six functions have to be defined by every VNC server using + * libvncserver. + * + * The main function just calls runVNCServer. This is different + * for more complex users of libvncserver. + * + */ + +#include "rfb.h" +#include <ApplicationServices/ApplicationServices.h> +#include <Carbon/Carbon.h> +#include <X11/keysym.h> + +void +rfbScreenInit(void) +{ + int bitsPerSample; + int samplesPerPixel; + + rfbScreen.width = CGDisplayPixelsWide(kCGDirectMainDisplay); + rfbScreen.height = CGDisplayPixelsHigh(kCGDirectMainDisplay); + rfbScreen.bitsPerPixel = rfbScreen.depth = + CGDisplayBitsPerPixel(kCGDirectMainDisplay); + gethostname(rfbThisHost, 255); + rfbScreen.paddedWidthInBytes = CGDisplayBytesPerRow(kCGDirectMainDisplay); + rfbServerFormat.bitsPerPixel = rfbScreen.bitsPerPixel; + rfbServerFormat.depth = rfbScreen.depth; + rfbServerFormat.bigEndian = !(*(char *)&rfbEndianTest); + rfbServerFormat.trueColour = TRUE; + + bitsPerSample = CGDisplayBitsPerSample(kCGDirectMainDisplay); + samplesPerPixel = CGDisplaySamplesPerPixel(kCGDirectMainDisplay); + if (samplesPerPixel != 3) { + rfbLog("screen format not supported. exiting.\n"); + exit(1); + } + + /* This works for 16 and 32-bit, but not for 8-bit. + What should it be for 8-bit? (Shouldn't 8-bit use a colormap?) */ + rfbServerFormat.redMax = (1 << bitsPerSample) - 1; + rfbServerFormat.greenMax = (1 << bitsPerSample) - 1; + rfbServerFormat.blueMax = (1 << bitsPerSample) - 1; + rfbServerFormat.redShift = bitsPerSample * 2; + rfbServerFormat.greenShift = bitsPerSample; + rfbServerFormat.blueShift = 0; + + /* We want to use the X11 REGION_* macros without having an actual + X11 ScreenPtr, so we do this. Pretty ugly, but at least it lets us + avoid hacking up regionstr.h, or changing every call to REGION_* + (which actually I should probably do eventually). */ + hackScreen.RegionCreate = miRegionCreate; + hackScreen.RegionInit = miRegionInit; + hackScreen.RegionCopy = miRegionCopy; + hackScreen.RegionDestroy = miRegionDestroy; + hackScreen.RegionUninit = miRegionUninit; + hackScreen.Intersect = miIntersect; + hackScreen.Union = miUnion; + hackScreen.Subtract = miSubtract; + hackScreen.Inverse = miInverse; + hackScreen.RegionReset = miRegionReset; + hackScreen.TranslateRegion = miTranslateRegion; + hackScreen.RectIn = miRectIn; + hackScreen.PointInRegion = miPointInRegion; + hackScreen.RegionNotEmpty = miRegionNotEmpty; + hackScreen.RegionEmpty = miRegionEmpty; + hackScreen.RegionExtents = miRegionExtents; + hackScreen.RegionAppend = miRegionAppend; + hackScreen.RegionValidate = miRegionValidate; +} + +char * +rfbGetFramebuffer(void) +{ + return (char *)CGDisplayBaseAddress(kCGDirectMainDisplay); +} + +/* Where do I get the "official" list of Mac key codes? + Ripped these out of a Mac II emulator called Basilisk II + that I found on the net. */ +static int keyTable[] = { + /* 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, 10, /* ` */ /* XXX ? */ + XK_asciitilde, 10, /* ~ */ + 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, /* | */ + + /* "Special" keys */ + XK_space, 49, /* Space */ + 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_Shift_L, 56, /* Shift Left */ + XK_Shift_R, 56, /* Shift Right */ + XK_Control_L, 59, /* Ctrl Left */ + XK_Control_R, 59, /* Ctrl Right */ + XK_Meta_L, 58, /* Logo Left (-> Option) */ + XK_Meta_R, 58, /* Logo Right (-> Option) */ + XK_Alt_L, 55, /* Alt Left (-> Command) */ + XK_Alt_R, 55, /* Alt Right (-> Command) */ + + /* Weirdness I can't figure out */ + /* XK_3270_PrintScreen, 105, /* PrintScrn */ /* XXX ? */ + /* ??? 94, 50, /* International */ + XK_Menu, 50, /* Menu (-> International) */ +}; + +void +KbdAddEvent(down, keySym, cl) + Bool down; + KeySym keySym; + rfbClientPtr cl; +{ + int i; + CGKeyCode keyCode = -1; + int found = 0; + + for (i = 0; i < (sizeof(keyTable) / sizeof(int)); i += 2) { + if (keyTable[i] == keySym) { + keyCode = keyTable[i+1]; + found = 1; + break; + } + } + + if (!found) { + rfbLog("warning: couldn't figure out keycode for X keysym %d (0x%x)\n", + (int)keySym, (int)keySym); + } else { + /* Hopefully I can get away with not specifying a CGCharCode. + (Why would you need both?) */ + CGPostKeyboardEvent((CGCharCode)0, keyCode, down); + } +} + +void +PtrAddEvent(buttonMask, x, y, cl) + int buttonMask; + int x; + int y; + rfbClientPtr cl; +{ + CGPoint position; + + position.x = x; + position.y = y; + + CGPostMouseEvent(position, TRUE, 8, + (buttonMask & (1 << 0)) ? TRUE : FALSE, + (buttonMask & (1 << 1)) ? TRUE : FALSE, + (buttonMask & (1 << 2)) ? TRUE : FALSE, + (buttonMask & (1 << 3)) ? TRUE : FALSE, + (buttonMask & (1 << 4)) ? TRUE : FALSE, + (buttonMask & (1 << 5)) ? TRUE : FALSE, + (buttonMask & (1 << 6)) ? TRUE : FALSE, + (buttonMask & (1 << 7)) ? TRUE : FALSE); +} + +void +KbdReleaseAllKeys() +{ + /* Doesn't seem to be possible. */ +} + +static void +refreshCallback(CGRectCount count, const CGRect *rectArray, void *ignore) +{ + BoxRec box; + RegionRec region; + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + int i; + + for (i = 0; i < count; i++) { + box.x1 = rectArray[i].origin.x; + box.y1 = rectArray[i].origin.y; + box.x2 = box.x1 + rectArray[i].size.width; + box.y2 = box.y1 + rectArray[i].size.height; + + SAFE_REGION_INIT(&hackScreen, ®ion, &box, 0); + + iterator = rfbGetClientIterator(); + while ((cl = rfbClientIteratorNext(iterator)) != NULL) { + pthread_mutex_lock(&cl->updateMutex); + REGION_UNION(&hackScreen,&cl->modifiedRegion,&cl->modifiedRegion,®ion); + pthread_cond_signal(&cl->updateCond); + pthread_mutex_unlock(&cl->updateMutex); + } + rfbReleaseClientIterator(iterator); + + REGION_UNINIT(&hackScreen, ®ion); + } +} + +void runEventLoop() +{ + CGRegisterScreenRefreshCallback(refreshCallback, NULL); + + RunApplicationEventLoop(); +} + +int main(int argc,char *argv[]) +{ + runVNCServer(argc,argv); +} |