+static unsigned clients_;
+
+static CFMessagePortRef ashikase_;
+static bool cursor_;
+
+static rfbPixel *black_;
+
+static void VNCBlack() {
+ if (_unlikely(black_ == NULL))
+ black_ = reinterpret_cast<rfbPixel *>(mmap(NULL, sizeof(rfbPixel) * width_ * height_, PROT_READ, MAP_ANON | MAP_PRIVATE | MAP_NOCACHE, VM_FLAGS_PURGABLE, 0));
+ screen_->frameBuffer = reinterpret_cast<char *>(black_);
+}
+
+static bool Ashikase(bool always) {
+ if (!always && !cursor_)
+ return false;
+
+ if (ashikase_ == NULL)
+ ashikase_ = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR("jp.ashikase.mousesupport"));
+ if (ashikase_ != NULL)
+ return true;
+
+ cursor_ = false;
+ return false;
+}
+
+static CFDataRef cfTrue_;
+static CFDataRef cfFalse_;
+
+typedef struct {
+ float x, y;
+ int buttons;
+ BOOL absolute;
+} MouseEvent;
+
+static MouseEvent event_;
+static CFDataRef cfEvent_;
+
+typedef enum {
+ MouseMessageTypeEvent,
+ MouseMessageTypeSetEnabled
+} MouseMessageType;
+
+static void AshikaseSendEvent(float x, float y, int buttons = 0) {
+ event_.x = x;
+ event_.y = y;
+ event_.buttons = buttons;
+ event_.absolute = true;
+
+ CFMessagePortSendRequest(ashikase_, MouseMessageTypeEvent, cfEvent_, 0, 0, NULL, NULL);
+}
+
+static void AshikaseSetEnabled(bool enabled, bool always) {
+ if (!Ashikase(always))
+ return;
+
+ CFMessagePortSendRequest(ashikase_, MouseMessageTypeSetEnabled, enabled ? cfTrue_ : cfFalse_, 0, 0, NULL, NULL);
+
+ if (enabled)
+ AshikaseSendEvent(x_, y_);
+}
+
+MSClassHook(SBAlertItem)
+MSClassHook(SBAlertItemsController)
+MSClassHook(SBStatusBarController)
+
+@interface VNCAlertItem : SBAlertItem
+@end
+
+static Class $VNCAlertItem;
+
+static NSString *DialogTitle(@"Remote Access Request");
+static NSString *DialogFormat(@"Accept connection from\n%s?\n\nVeency VNC Server\nby Jay Freeman (saurik)\nsaurik@saurik.com\nhttp://www.saurik.com/\n\nSet a VNC password in Settings!");
+static NSString *DialogAccept(@"Accept");
+static NSString *DialogReject(@"Reject");
+
+static volatile rfbNewClientAction action_ = RFB_CLIENT_ON_HOLD;
+static NSCondition *condition_;
+static NSLock *lock_;
+
+static rfbClientPtr client_;
+
+static void VNCSetup();
+static void VNCEnabled();
+
+float (*$GSMainScreenScaleFactor)();
+
+static void OnUserNotification(CFUserNotificationRef notification, CFOptionFlags flags) {
+ [condition_ lock];
+
+ if ((flags & 0x3) == 1)
+ action_ = RFB_CLIENT_ACCEPT;
+ else
+ action_ = RFB_CLIENT_REFUSE;
+
+ [condition_ signal];
+ [condition_ unlock];
+
+ CFRelease(notification);
+}
+
+@interface VNCBridge : NSObject {
+}
+
++ (void) askForConnection;
++ (void) removeStatusBarItem;
++ (void) registerClient;
+
+@end
+
+@implementation VNCBridge
+
++ (void) askForConnection {
+ if ($VNCAlertItem != nil) {
+ [[$SBAlertItemsController sharedInstance] activateAlertItem:[[[$VNCAlertItem alloc] init] autorelease]];
+ return;
+ }
+
+ SInt32 error;
+ CFUserNotificationRef notification(CFUserNotificationCreate(kCFAllocatorDefault, 0, kCFUserNotificationPlainAlertLevel, &error, (CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:
+ DialogTitle, kCFUserNotificationAlertHeaderKey,
+ [NSString stringWithFormat:DialogFormat, client_->host], kCFUserNotificationAlertMessageKey,
+ DialogAccept, kCFUserNotificationAlternateButtonTitleKey,
+ DialogReject, kCFUserNotificationDefaultButtonTitleKey,
+ nil]));
+
+ if (error != 0) {
+ CFRelease(notification);
+ notification = NULL;
+ }
+
+ if (notification == NULL) {
+ [condition_ lock];
+ action_ = RFB_CLIENT_REFUSE;
+ [condition_ signal];
+ [condition_ unlock];
+ return;
+ }
+
+ CFRunLoopSourceRef source(CFUserNotificationCreateRunLoopSource(kCFAllocatorDefault, notification, &OnUserNotification, 0));
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
+}
+
++ (void) removeStatusBarItem {
+ AshikaseSetEnabled(false, false);
+
+ if (SBA_available())
+ SBA_removeStatusBarImage(const_cast<char *>("Veency"));
+ else if ($SBStatusBarController != nil)
+ [[$SBStatusBarController sharedStatusBarController] removeStatusBarItem:@"Veency"];
+ else if (UIApplication *app = [$UIApplication sharedApplication])
+ [app removeStatusBarImageNamed:@"Veency"];
+}
+
++ (void) registerClient {
+ // XXX: this could find a better home
+ if (ratio_ == 0) {
+ if ($GSMainScreenScaleFactor == NULL)
+ ratio_ = 1.0f;
+ else
+ ratio_ = $GSMainScreenScaleFactor();
+ }
+
+ ++clients_;
+ AshikaseSetEnabled(true, false);
+
+ if (SBA_available())
+ SBA_addStatusBarImage(const_cast<char *>("Veency"));
+ else if ($SBStatusBarController != nil)
+ [[$SBStatusBarController sharedStatusBarController] addStatusBarItem:@"Veency"];
+ else if (UIApplication *app = [$UIApplication sharedApplication])
+ [app addStatusBarImageNamed:@"Veency"];
+}
+
++ (void) performSetup:(NSThread *)thread {
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+ [thread autorelease];
+ VNCSetup();
+ VNCEnabled();
+ [pool release];
+}
+
+@end
+
+MSInstanceMessage2(void, VNCAlertItem, alertSheet,buttonClicked, id, sheet, int, button) {
+ [condition_ lock];
+
+ switch (button) {
+ case 1:
+ action_ = RFB_CLIENT_ACCEPT;
+
+ @synchronized (condition_) {
+ [VNCBridge registerClient];
+ }
+ break;
+
+ case 2:
+ action_ = RFB_CLIENT_REFUSE;
+ break;
+ }
+
+ [condition_ signal];
+ [condition_ unlock];
+ [self dismiss];
+}
+
+MSInstanceMessage2(void, VNCAlertItem, configure,requirePasscodeForActions, BOOL, configure, BOOL, require) {
+ UIModalView *sheet([self alertSheet]);
+ [sheet setDelegate:self];
+ [sheet setTitle:DialogTitle];
+ [sheet setBodyText:[NSString stringWithFormat:DialogFormat, client_->host]];
+ [sheet addButtonWithTitle:DialogAccept];
+ [sheet addButtonWithTitle:DialogReject];
+}
+
+MSInstanceMessage0(void, VNCAlertItem, performUnlockAction) {
+ [[$SBAlertItemsController sharedInstance] activateAlertItem:self];
+}
+
+static mach_port_t (*GSTakePurpleSystemEventPort)(void);
+static bool PurpleAllocated;
+static int Level_;
+
+static void FixRecord(GSEventRecord *record) {
+ if (Level_ < 1)
+ memmove(&record->windowContextId, &record->windowContextId + 1, sizeof(*record) - (reinterpret_cast<uint8_t *>(&record->windowContextId + 1) - reinterpret_cast<uint8_t *>(record)) + record->size);
+}
+
+static void VNCSettings() {
+ NSDictionary *settings([NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Library/Preferences/com.saurik.Veency.plist", NSHomeDirectory()]]);
+
+ @synchronized (lock_) {
+ for (NSValue *handler in handlers_)
+ rfbUnregisterSecurityHandler(reinterpret_cast<rfbSecurityHandler *>([handler pointerValue]));
+ [handlers_ removeAllObjects];
+ }
+
+ @synchronized (condition_) {
+ if (screen_ == NULL)
+ return;
+
+ [reinterpret_cast<NSString *>(screen_->authPasswdData) release];
+ screen_->authPasswdData = NULL;
+
+ if (settings != nil)
+ if (NSString *password = [settings objectForKey:@"Password"])
+ if ([password length] != 0)
+ screen_->authPasswdData = [password retain];
+
+ NSNumber *cursor = [settings objectForKey:@"ShowCursor"];
+ cursor_ = cursor == nil ? true : [cursor boolValue];
+
+ if (clients_ != 0)
+ AshikaseSetEnabled(cursor_, true);
+ }
+}
+
+static void VNCNotifySettings(
+ CFNotificationCenterRef center,
+ void *observer,
+ CFStringRef name,
+ const void *object,
+ CFDictionaryRef info
+) {
+ VNCSettings();
+}
+
+static rfbBool VNCCheck(rfbClientPtr client, const char *data, int size) {
+ @synchronized (condition_) {
+ if (NSString *password = reinterpret_cast<NSString *>(screen_->authPasswdData)) {
+ NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]);
+ rfbEncryptBytes(client->authChallenge, const_cast<char *>([password UTF8String]));
+ bool good(memcmp(client->authChallenge, data, size) == 0);
+ [pool release];
+ return good;
+ } return TRUE;
+ }
+}
+
+static bool iPad1_;
+
+struct VeencyEvent {
+ struct GSEventRecord record;
+ struct {
+ struct GSEventRecordInfo info;
+ struct GSPathInfo path;
+ } data;
+};
+
+static void VNCPointerOld(int buttons, int x, int y, CGPoint location, int diff, bool twas, bool tis);
+static void VNCPointerNew(int buttons, int x, int y, CGPoint location, int diff, bool twas, bool tis);
+