Skip to content

Instantly share code, notes, and snippets.

@krisselden
Created January 30, 2015 19:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save krisselden/d05c3dce6e8d206444dc to your computer and use it in GitHub Desktop.
Save krisselden/d05c3dce6e8d206444dc to your computer and use it in GitHub Desktop.
#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