From c03dc350f33cd55f2e2019421c3df51ed50f23b4 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Tue, 16 Sep 2008 18:44:26 +0000 Subject: [PATCH] Added syslogd pseudo-tweak. --- Tweak.mm | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ control | 11 +++ make.sh | 7 ++ makefile | 4 + 4 files changed, 312 insertions(+) create mode 100644 Tweak.mm create mode 100644 control create mode 100755 make.sh create mode 100644 makefile diff --git a/Tweak.mm b/Tweak.mm new file mode 100644 index 0000000..f67c02c --- /dev/null +++ b/Tweak.mm @@ -0,0 +1,290 @@ +#include + +#include +#include + +#include + +#import +#import + +#import +#import +#import +#import +#import + +#define IOMobileFramebuffer "/System/Library/PrivateFrameworks/IOMobileFramebuffer.framework/IOMobileFramebuffer" + +static const size_t Width = 320; +static const size_t Height = 480; +static const size_t BytesPerPixel = 4; +static const size_t BitsPerSample = 8; + +static const size_t Stride = Width * BytesPerPixel; +static const size_t Size32 = Width * Height; +static const size_t Size8 = Size32 * BytesPerPixel; + +static pthread_t thread_; +static rfbScreenInfoPtr screen_; +static bool running_; +static int buttons_; +static int x_, y_; + +static void VNCPointer(int buttons, int x, int y, rfbClientPtr client) { + x_ = x; + y_ = y; + + int diff = buttons_ ^ buttons; + + rfbDefaultPtrAddEvent(buttons, x, y, client); + + mach_port_t purple(0); + + bool twas((buttons_ & 0x1) != 0); + bool tis((buttons & 0x1) != 0); + + buttons_ = buttons; + + if ((diff & 0x10) != 0) { + struct GSEventRecord record; + + memset(&record, 0, sizeof(record)); + + record.type = (buttons & 0x4) != 0 ? + GSEventTypeHeadsetButtonDown : + GSEventTypeHeadsetButtonUp; + + record.timestamp = GSCurrentEventTimestamp(); + + GSSendSystemEvent(&record); + } + + if ((diff & 0x08) != 0 && (buttons & 0x4) != 0) { + struct GSEventRecord record; + + memset(&record, 0, sizeof(record)); + + record.type = GSEventTypeRingerChanged0; + + record.timestamp = GSCurrentEventTimestamp(); + + GSSendSystemEvent(&record); + } + + if ((diff & 0x04) != 0) { + struct GSEventRecord record; + + memset(&record, 0, sizeof(record)); + + record.type = (buttons & 0x4) != 0 ? + GSEventTypeMenuButtonDown : + GSEventTypeMenuButtonUp; + + record.timestamp = GSCurrentEventTimestamp(); + + GSSendSystemEvent(&record); + } + + if ((diff & 0x02) != 0) { + struct GSEventRecord record; + + memset(&record, 0, sizeof(record)); + + record.type = (buttons & 0x2) != 0 ? + GSEventTypeLockButtonDown : + GSEventTypeLockButtonUp; + + record.timestamp = GSCurrentEventTimestamp(); + + GSSendSystemEvent(&record); + } + + if (twas != tis || tis) { + struct { + struct GSEventRecord record; + struct { + struct GSEventRecordInfo info; + struct GSPathInfo path; + } data; + } event; + + memset(&event, 0, sizeof(event)); + + event.record.type = GSEventTypeMouse; + event.record.locationInWindow.x = x; + event.record.locationInWindow.y = y; + event.record.timestamp = GSCurrentEventTimestamp(); + event.record.size = sizeof(event.data); + + event.data.info.handInfo.type = twas == tis ? + GSMouseEventTypeDragged : + tis ? + GSMouseEventTypeDown : + GSMouseEventTypeUp; + + event.data.info.handInfo.x34 = 0x1; + event.data.info.handInfo.x38 = tis ? 0x1 : 0x0; + + event.data.info.pathPositions = 1; + + event.data.path.x00 = 0x01; + event.data.path.x01 = 0x02; + event.data.path.x02 = tis ? 0x03 : 0x00; + event.data.path.position = event.record.locationInWindow; + + mach_port_t port(0); + + if (CAWindowServer *server = [CAWindowServer serverIfRunning]) { + NSArray *displays([server displays]); + if (displays != nil && [displays count] != 0) + if (CAWindowServerDisplay *display = [displays objectAtIndex:0]) + port = [display clientPortAtPosition:event.record.locationInWindow]; + } + + if (port == 0) { + if (purple == 0) + purple = GSCopyPurpleSystemEventPort(); + port = purple; + } + + GSSendEvent(&event.record, port); + } + + if (purple != 0) + mach_port_deallocate(mach_task_self(), purple); +} + +static void VNCKeyboard(rfbBool down, rfbKeySym key, rfbClientPtr client) { + if (!down) + return; + + switch (key) { + case XK_Return: key = '\r'; break; + case XK_BackSpace: key = 0x7f; break; + } + + if (key > 0xfff) + return; + + struct { + struct GSEventRecord record; + struct GSEventKeyInfo data; + } event; + + memset(&event, 0, sizeof(event)); + + event.record.type = GSEventTypeKeyDown; + event.record.timestamp = GSCurrentEventTimestamp(); + event.record.size = sizeof(event.data); + + event.data.character = key; + + mach_port_t port(0); + + if (CAWindowServer *server = [CAWindowServer serverIfRunning]) { + NSArray *displays([server displays]); + if (displays != nil && [displays count] != 0) + if (CAWindowServerDisplay *display = [displays objectAtIndex:0]) + port = [display clientPortAtPosition:CGPointMake(x_, y_)]; + } + + if (port != 0) + GSSendEvent(&event.record, port); +} + +static void *VNCServer(IOMobileFramebufferRef fb) { + CGRect rect(CGRectMake(0, 0, Width, Height)); + + CoreSurfaceBufferRef surface(NULL); + kern_return_t value(IOMobileFramebufferGetLayerDefaultSurface(fb, 0, &surface)); + if (value != 0) + return NULL; + + int argc(1); + char *arg0(strdup("VNCServer")); + char *argv[] = {arg0, NULL}; + + io_service_t service(IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOCoreSurfaceRoot"))); + CFMutableDictionaryRef properties(NULL); + IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, kNilOptions); + + screen_ = rfbGetScreen(&argc, argv, Width, Height, BitsPerSample, 3, BytesPerPixel); + screen_->desktopName = "iPhone"; + screen_->alwaysShared = TRUE; + screen_->handleEventsEagerly = TRUE; + screen_->deferUpdateTime = 5; + + screen_->serverFormat.redShift = BitsPerSample * 2; + screen_->serverFormat.greenShift = BitsPerSample * 1; + screen_->serverFormat.blueShift = BitsPerSample * 0; + + CoreSurfaceBufferLock(surface, kCoreSurfaceLockTypeGimmeVRAM); + screen_->frameBuffer = reinterpret_cast(CoreSurfaceBufferGetBaseAddress(surface)); + CoreSurfaceBufferUnlock(surface); + + screen_->kbdAddEvent = &VNCKeyboard; + screen_->ptrAddEvent = &VNCPointer; + + rfbInitServer(screen_); + running_ = true; + + rfbRunEventLoop(screen_, -1, true); + return NULL; + + running_ = false; + rfbScreenCleanup(screen_); + + CFRelease(surface); + + free(arg0); + return NULL; +} + +static rfbPixel black_[320][480]; + +MSHook(kern_return_t, IOMobileFramebufferSwapSetLayer, + IOMobileFramebufferRef fb, + int layer, + CoreSurfaceBufferRef buffer, + CGRect bounds, + CGRect frame, + int flags +) { + /*if ( + bounds.origin.x != 0 || bounds.origin.y != 0 || bounds.size.width != 320 || bounds.size.height != 480 || + frame.origin.x != 0 || frame.origin.y != 0 || frame.size.width != 320 || frame.size.height != 480 + ) NSLog(@"VNC:%f,%f:%f,%f:%f,%f:%f,%f", + bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height, + frame.origin.x, frame.origin.y, frame.size.width, frame.size.height + );*/ + + if (running_) { + if (buffer == NULL) + screen_->frameBuffer = reinterpret_cast(black_); + else { + CoreSurfaceBufferLock(buffer, kCoreSurfaceLockTypeGimmeVRAM); + rfbPixel (*data)[480] = reinterpret_cast(CoreSurfaceBufferGetBaseAddress(buffer)); + /*memcpy(black_, data, sizeof(black_)); + screen_->frameBuffer = reinterpret_cast(black_);*/ + data[x_][y_] = screen_->whitePixel; + screen_->frameBuffer = reinterpret_cast(data); + CoreSurfaceBufferUnlock(buffer); + } + } + + kern_return_t value(_IOMobileFramebufferSwapSetLayer(fb, layer, buffer, bounds, frame, flags)); + + if (thread_ == NULL) + pthread_create(&thread_, NULL, &VNCServer, fb); + else if (running_) + rfbMarkRectAsModified(screen_, 0, 0, Width, Height); + + return value; +} + +extern "C" void TweakInitialize() { + if (objc_getClass("SpringBoard") == nil) + return; + MSHookFunction(&IOMobileFramebufferSwapSetLayer, &$IOMobileFramebufferSwapSetLayer, &_IOMobileFramebufferSwapSetLayer); +} diff --git a/control b/control new file mode 100644 index 0000000..23f42ec --- /dev/null +++ b/control @@ -0,0 +1,11 @@ +Package: com.saurik.iphone.vncs +Priority: optional +Section: Tweaks +Maintainer: Jay Freeman (saurik) +Architecture: iphoneos-arm +Version: 0.9.2561-1 +Description: remotely watch your iPhone screen +Name: VNC Server +Depends: mobilesubstrate (>= 0.9.2568-1), libvncserver +Author: Jay Freeman (saurik) +Depiction: http://cydia.saurik.com/info/com.saurik.iphone.vncs/ diff --git a/make.sh b/make.sh new file mode 100755 index 0000000..2d9cc22 --- /dev/null +++ b/make.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e +export PKG_ARCH=${PKG_ARCH-iphoneos-arm} +PATH=/apl/n42/pre/bin:$PATH /apl/tel/exec.sh com.saurik.winterboard make "$@" +export CODESIGN_ALLOCATE=$(which arm-apple-darwin9-codesign_allocate) +/apl/tel/util/ldid -S *.dylib +make package diff --git a/makefile b/makefile new file mode 100644 index 0000000..65a625b --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +name := VNCServer +id := vncs +flags := -lvncserver -framework IOMobileFramebuffer -framework CoreSurface -framework IOKit -framework GraphicsServices -I/apl/inc/iPhoneOS-2.0 -framework QuartzCore +include ../tweak.mk -- 2.47.2