14 #ifndef NS_RETURNS_INNER_POINTER
15 #define NS_RETURNS_INNER_POINTER
17 #import <AppKit/AppKit.h>
19 #include <objc/objc-runtime.h>
28 static void **mainThread;
29 static dispatch_once_t once = 0;
30 dispatch_once(&once, ^{
31 mainThread = (
void **)dlsym(RTLD_SELF,
"VuoApp_mainThread");
33 mainThread = (
void **)dlsym(RTLD_DEFAULT,
"VuoApp_mainThread");
37 VUserLog(
"Error: Couldn't find VuoApp_mainThread.");
44 VUserLog(
"Error: VuoApp_mainThread isn't set.");
50 return *mainThread == (
void *)pthread_self();
74 VUserLog(
"Error: VuoEventLoop_processEvent must be called from the main thread.");
79 NSAutoreleasePool *pool = [NSAutoreleasePool new];
82 id *nsAppGlobal = (
id *)dlsym(RTLD_DEFAULT,
"NSApp");
85 if (nsAppGlobal && *nsAppGlobal)
92 NSEvent *
event = [*nsAppGlobal nextEventMatchingMask:NSAnyEventMask
93 untilDate:(mode == VuoEventLoop_WaitIndefinitely ? [NSDate distantFuture] : [NSDate distantPast])
94 inMode:NSDefaultRunLoopMode
96 [*nsAppGlobal sendEvent:event];
97 [*nsAppGlobal updateWindows];
103 if (mode == VuoEventLoop_WaitIndefinitely)
106 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0,
false);
120 id *nsAppGlobal = (
id *)dlsym(RTLD_DEFAULT,
"NSApp");
122 if (nsAppGlobal && *nsAppGlobal)
126 dispatch_async(dispatch_get_main_queue(), ^{
127 NSEvent *killswitch = [NSEvent otherEventWithType:NSApplicationDefined
128 location:NSMakePoint(0,0)
136 [*nsAppGlobal postEvent:killswitch atStart:NO];
142 CFRunLoopStop(CFRunLoopGetMain());
154 CFRunLoopStop(CFRunLoopGetMain());
166 VUserLog(
"Error: VuoEventLoop_mayBeTerminated must be called from the main thread.");
172 id *nsAppGlobal = (
id *)dlsym(RTLD_DEFAULT,
"NSApp");
173 if (!nsAppGlobal || !*nsAppGlobal)
176 if ([*nsAppGlobal modalWindow])
179 for (NSWindow *window in [*nsAppGlobal windows])
180 if ([window attachedSheet])
196 static dispatch_queue_attr_t attr = 0;
197 static dispatch_once_t once = 0;
198 dispatch_once(&once, ^{
199 attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INTERACTIVE, 0);
212 vuoStopCompositionType
vuoStopComposition = (vuoStopCompositionType)dlsym(RTLD_SELF,
"vuoStopComposition");
214 vuoStopComposition = (vuoStopCompositionType)dlsym(RTLD_DEFAULT,
"vuoStopComposition");
217 VUserLog(
"Warning: Couldn't find vuoStopComposition symbol; not installing clean-shutdown signal handlers.");
222 signal(SIGINT, SIG_IGN);
223 signal(SIGQUIT, SIG_IGN);
224 signal(SIGTERM, SIG_IGN);
228 void (^stop)(void) = ^{
231 dispatch_source_t sigintSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGINT, 0, dispatch_get_main_queue());
232 dispatch_source_t sigquitSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGQUIT, 0, dispatch_get_main_queue());
233 dispatch_source_t sigtermSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue());
234 dispatch_source_set_event_handler(sigintSource, stop);
235 dispatch_source_set_event_handler(sigquitSource, stop);
236 dispatch_source_set_event_handler(sigtermSource, stop);
237 dispatch_resume(sigintSource);
238 dispatch_resume(sigquitSource);
239 dispatch_resume(sigtermSource);
248 void (^logThermalState)(
int thermalState) = ^(
int thermalState){
249 if (thermalState == 0)
251 else if (thermalState == 1)
252 VDebugLog(
"thermalState = fair (\"fans audible\")");
253 else if (thermalState == 2)
254 VDebugLog(
"thermalState = serious (\"fans at maximum speed\")");
255 else if (thermalState == 3)
256 VDebugLog(
"thermalState = critical (\"system needs to cool down\")");
258 if ([NSProcessInfo.processInfo respondsToSelector:
@selector(thermalState)])
260 logThermalState((
int)objc_msgSend(NSProcessInfo.processInfo,
@selector(thermalState)));
261 [NSNotificationCenter.defaultCenter addObserverForName:@"NSProcessInfoThermalStateDidChangeNotification" object:nil queue:nil usingBlock:^(NSNotification *note){
262 logThermalState((int)objc_msgSend(note.object, @selector(thermalState)));
276 id activityToken = [[NSProcessInfo processInfo] performSelector:@selector(beginActivityWithOptions:reason:)
277 withObject: (id)((0x00FFFFFFULL | (1ULL << 20)) & ~(1ULL << 14))
278 withObject: @"Many Vuo compositions need to process input and send output even when the app's window is not visible."];
280 [activityToken retain];