From ba1d9e67a56187380f3ed656f17bf948a438603f Mon Sep 17 00:00:00 2001 From: David Eisner Date: Fri, 9 Dec 2011 14:21:57 +0000 Subject: [PATCH] Report volume removal and attachment events on OS X, as volume.removed and volume.added --- modules/ti.UI/SConscript | 2 +- modules/ti.UI/mac/UIMac.h | 1 + modules/ti.UI/mac/UIMac.mm | 75 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/modules/ti.UI/SConscript b/modules/ti.UI/SConscript index 73e0109aa..98510012b 100644 --- a/modules/ti.UI/SConscript +++ b/modules/ti.UI/SConscript @@ -29,7 +29,7 @@ elif build.is_win32(): elif build.is_osx(): env.Append(FRAMEWORKPATH=[build.tp('growl')]) - env.Append(FRAMEWORKS=['Cocoa','Carbon', 'IOKit', 'Growl']) + env.Append(FRAMEWORKS=['Cocoa','Carbon', 'IOKit', 'Growl', 'DiskArbitration']) sources = sources + Glob('mac/*.mm') + Glob('mac/*.cpp') env.Append(CCFLAGS=['-x', 'objective-c++']) diff --git a/modules/ti.UI/mac/UIMac.h b/modules/ti.UI/mac/UIMac.h index 7c1a50b07..880a6f409 100644 --- a/modules/ti.UI/mac/UIMac.h +++ b/modules/ti.UI/mac/UIMac.h @@ -73,6 +73,7 @@ class UIMac : public UI { NSObject* application; AutoPtr activeMenu; AutoPtr activeWindow; + DASessionRef session; void InstallMenu (MenuItemMac*); }; diff --git a/modules/ti.UI/mac/UIMac.mm b/modules/ti.UI/mac/UIMac.mm index 925b61d2b..805c24d50 100644 --- a/modules/ti.UI/mac/UIMac.mm +++ b/modules/ti.UI/mac/UIMac.mm @@ -27,6 +27,71 @@ #include "TrayItemMac.h" #include "UserWindowMac.h" +#include +#include + +#define DBG if(0) +void printPair(const void* key, const void* value, void* context) +{ + printf("{\n"); + CFShow(key); + CFShow(value); + printf("}\n"); +} +inline bool TestBool(const void *v) +{ + return v && CFBooleanGetValue((CFBooleanRef)v); +} +inline bool TestStr(const void *v, CFStringRef s) +{ + return v && !CFStringCompare((CFStringRef)v, s, 0); +} + +void report_disk(DADiskRef disk, void *context, const char *event, CFDictionaryRef desc = NULL) +{ + if (!desc) + desc = DADiskCopyDescription(disk); + if (desc) { + DBG CFDictionaryApplyFunction(desc, printPair, context); + DBG printf("disk %s %s\n", DADiskGetBSDName(disk), event); + if (TestBool(CFDictionaryGetValue(desc, kDADiskDescriptionMediaLeafKey))) { + DBG DBG printf("disk %s is leafy\n", DADiskGetBSDName(disk)); + if (TestBool(CFDictionaryGetValue(desc, kDADiskDescriptionMediaRemovableKey))) { + DBG printf("disk %s is removable\n", DADiskGetBSDName(disk)); + if (TestBool(CFDictionaryGetValue(desc, kDADiskDescriptionMediaWritableKey))) { + DBG printf("disk %s is writable\n", DADiskGetBSDName(disk)); + if (!TestBool(CFDictionaryGetValue(desc, kDADiskDescriptionVolumeNetworkKey))) { + DBG printf("disk %s is not networked\n", DADiskGetBSDName(disk)); + if (TestStr(CFDictionaryGetValue(desc, kDADiskDescriptionMediaKindKey), CFSTR("IOMedia"))) { + DBG printf("disk %s is not optical\n", DADiskGetBSDName(disk)); + DBG printf("disk %s %s\n", DADiskGetBSDName(disk), event); + GlobalObject::GetInstance()->FireEvent(event); + } + } + } + } + } + CFRelease(desc); + } +} + +void hello_disk(DADiskRef disk, void *context) +{ + report_disk(disk, context, "volume.added"); +} + +void goodbye_disk(DADiskRef disk, void *context) +{ + report_disk(disk, context, "volume.removed"); +} + +void follow_disk(DADiskRef disk, CFArrayRef keys, void *context) +{ + CFDictionaryRef desc = DADiskCopyDescription(disk); + if (desc && CFDictionaryGetValue(desc, kDADiskDescriptionVolumePathKey)) + report_disk(disk, context, "volume.added", desc); +} + @interface NSApplication (LegacyWarningSurpression) - (id) dockTile; @end @@ -79,12 +144,22 @@ - (id)owner; // make sure this is part of the upcoming security work [WebView registerURLSchemeAsLocal:@"app"]; [WebView registerURLSchemeAsLocal:@"ti"]; + + session = DASessionCreate(kCFAllocatorDefault); + + DBG DARegisterDiskAppearedCallback(session, NULL, hello_disk, NULL); + DARegisterDiskDisappearedCallback(session, NULL, goodbye_disk, NULL); + DARegisterDiskDescriptionChangedCallback(session, NULL, kDADiskDescriptionWatchVolumePath, follow_disk, NULL); + + DASessionScheduleWithRunLoop(session, + CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); } UIMac::~UIMac() { [application release]; [savedDockView release]; + CFRelease(session); } AutoPtr UIMac::CreateMenu()