Created
January 30, 2015 19:08
-
-
Save krisselden/d05c3dce6e8d206444dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <CoreFoundation/CoreFoundation.h> | |
#include <objc/runtime.h> | |
#include <objc/message.h> | |
#include <ruby.h> | |
#include <ruby/encoding.h> | |
static CFStringRef bundle_identifier = CFSTR("com.apple.finder"); | |
static Class NSBundle = NULL; | |
static Class NSUserNotification = NULL; | |
static Class NSUserNotificationCenter = NULL; | |
static SEL mainBundle = NULL; | |
static SEL __bundleIdentifier = NULL; | |
static SEL alloc = NULL; | |
static SEL init = NULL; | |
static SEL release = NULL; | |
static VALUE UserNotificationCenter = Qnil; | |
void hook_bundle_identifier(); | |
VALUE UserNotificationCenter_bundle_identifier(VALUE self); | |
VALUE UserNotificationCenter_set_bundle_identifier(VALUE self, VALUE value); | |
VALUE UserNotificationCenter_deliver_notification(VALUE self, VALUE title, VALUE details); | |
CFStringRef CFStringFromRString(VALUE); | |
VALUE RStringFromCFString(CFStringRef); | |
void Init_nsusernotification() { | |
NSBundle = objc_getClass("NSBundle"); | |
mainBundle = sel_registerName("mainBundle"); | |
__bundleIdentifier = sel_registerName("__bundleIdentifier"); | |
hook_bundle_identifier(); | |
NSUserNotification = objc_getClass("NSUserNotification"); | |
NSUserNotificationCenter = objc_getClass("NSUserNotificationCenter"); | |
alloc = sel_registerName("alloc"); | |
init = sel_registerName("init"); | |
release = sel_registerName("release"); | |
UserNotificationCenter = rb_define_module("UserNotificationCenter"); | |
rb_define_singleton_method(UserNotificationCenter, "bundle_identifier", UserNotificationCenter_bundle_identifier, 0); | |
rb_define_singleton_method(UserNotificationCenter, "bundle_identifier=", UserNotificationCenter_set_bundle_identifier, 1); | |
rb_define_singleton_method(UserNotificationCenter, "deliver_notification", UserNotificationCenter_deliver_notification, 2); | |
} | |
VALUE UserNotificationCenter_bundle_identifier(VALUE self) | |
{ | |
return RStringFromCFString(bundle_identifier); | |
} | |
VALUE UserNotificationCenter_set_bundle_identifier(VALUE self, VALUE value) | |
{ | |
CFStringRef old = bundle_identifier; | |
bundle_identifier = CFStringFromRString(value); | |
if (old) CFRelease(old); | |
return value; | |
} | |
VALUE UserNotificationCenter_deliver_notification(VALUE self, VALUE title, VALUE details) | |
{ | |
id notification = objc_msgSend(objc_msgSend((id)NSUserNotification, alloc), init); | |
CFStringRef cfTitle = CFStringFromRString(title); | |
objc_msgSend(notification, sel_registerName("setTitle:"), cfTitle); | |
CFRelease(cfTitle); | |
CFStringRef cfDetails = CFStringFromRString(details); | |
objc_msgSend(notification, sel_registerName("setInformativeText:"), cfDetails); | |
CFRelease(cfDetails); | |
id userNotificationCenter = objc_msgSend((id)NSUserNotificationCenter, sel_registerName("defaultUserNotificationCenter")); | |
objc_msgSend(userNotificationCenter, sel_registerName("deliverNotification:"), notification); | |
objc_msgSend(notification, release); | |
return Qnil; | |
} | |
id __bundleIdentifierIMP(id self, SEL _cmd) | |
{ | |
if (self == objc_msgSend((id)NSBundle, mainBundle)) { | |
return (id)bundle_identifier; | |
} else { | |
return objc_msgSend(self, __bundleIdentifier); | |
} | |
} | |
void hook_bundle_identifier() | |
{ | |
class_addMethod(NSBundle, __bundleIdentifier, (IMP)__bundleIdentifierIMP, "@@:"); | |
SEL bundleIdentifier = sel_registerName("bundleIdentifier"); | |
method_exchangeImplementations(class_getInstanceMethod(NSBundle, bundleIdentifier), | |
class_getInstanceMethod(NSBundle, __bundleIdentifier)); | |
} | |
CFStringRef CFStringFromRString(VALUE value) | |
{ | |
return CFStringCreateWithCString(NULL, StringValueCStr(value), kCFStringEncodingUTF8); | |
} | |
VALUE RStringFromCFString(CFStringRef value) | |
{ | |
const char* str = CFStringGetCStringPtr(value, kCFStringEncodingUTF8); | |
return rb_enc_str_new(str, strlen(str), rb_utf8_encoding()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment