SOM_Scope ODBoolean SOMLINK ODLinkSpecFromThisDraft(ODLinkSpec *somSelf, Environment *ev) { ODLinkSpecData *somThis = ODLinkSpecGetData(somSelf); ODLinkSpecMethodDebug("ODLinkSpec","FromThisDraft"); #ifdef _PLATFORM_MACINTOSH_ SOM_CATCH return kODFalse; ProcessSerialNumber myPSN; ProcessInfoRec myProcessInfo; Boolean isSamePSN; myPSN.lowLongOfPSN = kCurrentProcess; myPSN.highLongOfPSN = 0; myProcessInfo.processAppSpec = NULL; myProcessInfo.processName = NULL; myProcessInfo.processInfoLength = sizeof(myProcessInfo); THROW_IF_ERROR(GetProcessInformation(&myPSN, &myProcessInfo)); THROW_IF_ERROR(SameProcess(&_fProcessID, &myProcessInfo.processNumber, &isSamePSN)); return (isSamePSN && (myProcessInfo.processLaunchDate == _fProcessLaunchDate)); #else return(kODFalse); #endif }
/* * Like FrontWindow(), but return NULL if we aren't the front process * (i.e. the front window isn't one of ours). */ WindowPtr mac_frontwindow(void) { ProcessSerialNumber frontpsn; ProcessSerialNumber curpsn = { 0, kCurrentProcess }; Boolean result; GetFrontProcess(&frontpsn); if (SameProcess(&frontpsn, &curpsn, &result) == noErr && result) return FrontWindow(); return NULL; }
Boolean HelperMacX::isFrontProcess(pid_t pid){ Boolean result; ProcessSerialNumber pidPSN; ProcessSerialNumber frontPSN; OSStatus status = GetProcessForPID(pid, &pidPSN); if (noErr != status) { qWarning("HelperMacX::isFrontProcess: GetProcessForPID error for pid %d: %d", pid, (int)status); return false; } GetFrontProcess(&frontPSN); SameProcess(&pidPSN, &frontPSN, &result); return result; }
/** This chunk of code is heavily based off SDL_macosx.m from SDL. * The CPSEnableForegroundOperation that was here before is private * and should not be used. * Replaced by a call to the 10.3+ TransformProcessType. */ void osx_foreground_hack(void) { #if !defined (CONFIG_MACOSX_FINDER) || !defined (CONFIG_SDL) ProcessSerialNumber myProc, frProc; Boolean sameProc; if (GetFrontProcess(&frProc) == noErr && GetCurrentProcess(&myProc) == noErr) { if (SameProcess(&frProc, &myProc, &sameProc) == noErr && !sameProc) { TransformProcessType(&myProc, kProcessTransformToForegroundApplication); } SetFrontProcess(&myProc); } #endif }
int is_mplayer_front(void) { ProcessSerialNumber myProc, frProc; Boolean sameProc; pid_t parentPID; if (GetFrontProcess(&frProc) == noErr && GetCurrentProcess(&myProc) == noErr && SameProcess(&frProc, &myProc, &sameProc) == noErr) { if (sameProc) return 1; // If MPlayer is running in slave mode, also check parent process. if (slave_mode && GetProcessPID(&frProc, &parentPID) == noErr) return parentPID==getppid(); } return 0; }
pascal OSStatus osx_launch_app_callback(EventHandlerCallRef next_h, EventRef event,void *user_data) { EXEC_EVENT_DATA_S *ev_datap = (EXEC_EVENT_DATA_S *)user_data; ProcessSerialNumber pid; Boolean res = 0; static int dont_do_anything_yet = 0; switch(GetEventClass(event)){ case kEventClassKeyboard: ev_datap->done = 1; break; case kEventClassApplication: switch(GetEventKind(event)){ case kEventAppTerminated: GetEventParameter(event, kEventParamProcessID, typeProcessSerialNumber, NULL, sizeof(pid), NULL, &pid); SameProcess(&ev_datap->pid, &pid, &res); if(res){ ev_datap->done = 1; ev_datap->set_pid = 0; } break; case kEventAppLaunchNotification: /* could check asyncRef too */ if(!ev_datap->set_pid){ /* should always be true */ GetEventParameter(event, kEventParamProcessID, typeProcessSerialNumber, NULL, sizeof(ev_datap->pid), NULL, &(ev_datap->pid)); ev_datap->set_pid = 1; } break; } break; } return(noErr); }
extern pascal Boolean MoreProcIsProcessAtFront(const ProcessSerialNumber *pPSN) // See comment in header. { OSStatus anErr; ProcessSerialNumber localPSN; ProcessSerialNumber frontPSN; Boolean isSame; if ( pPSN == nil ) { localPSN.highLongOfPSN = 0; localPSN.lowLongOfPSN = kCurrentProcess; } else { localPSN = *pPSN; } anErr = GetFrontProcess(&frontPSN); if (noErr == anErr) { anErr = SameProcess(&localPSN, &frontPSN, &isSame); } MoreAssertQ(noErr == anErr); // If either of the previous return an error, we want to know why. return (noErr == anErr) && isSame; }
OSStatus ApplicationHandler(EventHandlerCallRef next, EventRef event, void *data) { ProcessSerialNumber them; ProcessSerialNumber us; Boolean same; UInt32 kind; // Get event kind kind = GetEventKind(event); // switch on event kind switch (kind) { // Front app switched case kEventAppFrontSwitched: // Get their process id GetEventParameter(event, kEventParamProcessID, typeProcessSerialNumber, NULL, sizeof(them), NULL, &them); // Get our process id GetCurrentProcess(&us); // Is it the same? SameProcess(&them, &us, &same); // If not the same if (!same) { // Turn all the notes off and reset all the buttons that // are down for (int i = 0; i < Length(bass); i++) { // Bass buttons if (bass[i]) { bass[i] = false; HIViewSetValue(bassdisplay[i], false); int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, 0, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, 0, 0); } } for (int i = 0; i < Length(buttons); i++) { for (int j = 0; j < Length(buttons[i]); j++) { // Melody buttons if (buttons[i][j]) { buttons[i][j] = false; int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } if ((type == CHROMATIC) && (hilites[key][i][j] == true)) HIViewSetValue(display[i][k], true); else HIViewSetValue(display[i][k], false); int note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + i, note, 0, 0); } } } if (bellows) { // Space bar button bellows = false; HIViewSetValue(spacebar, false); } } break; default: return eventNotHandledErr; } // Return ok return noErr; }
int main(int argc, char **argv) #endif { ll_init_apr(); // Set up llerror logging { LLError::initForApplication("."); LLError::setDefaultLevel(LLError::LEVEL_INFO); // LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); // LLError::logToFile("slplugin.log"); } #if LL_WINDOWS if( strlen( lpCmdLine ) == 0 ) { LL_ERRS("slplugin") << "usage: " << "SLPlugin" << " launcher_port" << LL_ENDL; }; U32 port = 0; if(!LLStringUtil::convertToU32(lpCmdLine, port)) { LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL; }; // Insert our exception handler into the system so this plugin doesn't // display a crash message if something bad happens. The host app will // see the missing heartbeat and log appropriately. initExceptionHandler(); #elif LL_DARWIN || LL_LINUX if(argc < 2) { LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL; } U32 port = 0; if(!LLStringUtil::convertToU32(argv[1], port)) { LL_ERRS("slplugin") << "port number must be numeric" << LL_ENDL; } // Catch signals that most kinds of crashes will generate, and exit cleanly so the system crash dialog isn't shown. signal(SIGILL, &crash_handler); // illegal instruction # if LL_DARWIN signal(SIGEMT, &crash_handler); // emulate instruction executed # endif // LL_DARWIN signal(SIGFPE, &crash_handler); // floating-point exception signal(SIGBUS, &crash_handler); // bus error signal(SIGSEGV, &crash_handler); // segmentation violation signal(SIGSYS, &crash_handler); // non-existent system call invoked #endif #if LL_DARWIN setupCocoa(); createAutoReleasePool(); #endif LLPluginProcessChild *plugin = new LLPluginProcessChild(); plugin->init(port); #if LL_DARWIN deleteAutoReleasePool(); #endif LLTimer timer; timer.start(); #if LL_WINDOWS checkExceptionHandler(); #endif #if LL_DARWIN // If the plugin opens a new window (such as the Flash plugin's fullscreen player), we may need to bring this plugin process to the foreground. // Use this to track the current frontmost window and bring this process to the front if it changes. WindowRef front_window = NULL; WindowGroupRef layer_group = NULL; int window_hack_state = 0; CreateWindowGroup(kWindowGroupAttrFixedLevel, &layer_group); if(layer_group) { // Start out with a window layer that's way out in front (fixes the problem with the menubar not getting hidden on first switch to fullscreen youtube) SetWindowGroupName(layer_group, CFSTR("SLPlugin Layer")); SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel); } #endif #if LL_DARWIN EventTargetRef event_target = GetEventDispatcherTarget(); #endif while(!plugin->isDone()) { #if LL_DARWIN createAutoReleasePool(); #endif timer.reset(); plugin->idle(); #if LL_DARWIN { // Some plugins (webkit at least) will want an event loop. This qualifies. EventRef event; if(ReceiveNextEvent(0, 0, kEventDurationNoWait, true, &event) == noErr) { SendEventToEventTarget (event, event_target); ReleaseEvent(event); } // Check for a change in this process's frontmost window. if(FrontWindow() != front_window) { ProcessSerialNumber self = { 0, kCurrentProcess }; ProcessSerialNumber parent = { 0, kNoProcess }; ProcessSerialNumber front = { 0, kNoProcess }; Boolean this_is_front_process = false; Boolean parent_is_front_process = false; { // Get this process's parent ProcessInfoRec info; info.processInfoLength = sizeof(ProcessInfoRec); info.processName = NULL; info.processAppSpec = NULL; if(GetProcessInformation( &self, &info ) == noErr) { parent = info.processLauncher; } // and figure out whether this process or its parent are currently frontmost if(GetFrontProcess(&front) == noErr) { (void) SameProcess(&self, &front, &this_is_front_process); (void) SameProcess(&parent, &front, &parent_is_front_process); } } if((FrontWindow() != NULL) && (front_window == NULL)) { // Opening the first window if(window_hack_state == 0) { // Next time through the event loop, lower the window group layer window_hack_state = 1; } if(layer_group) { SetWindowGroup(FrontWindow(), layer_group); } if(parent_is_front_process) { // Bring this process's windows to the front. (void) SetFrontProcess( &self ); } ActivateWindow(FrontWindow(), true); } else if((FrontWindow() == NULL) && (front_window != NULL)) { // Closing the last window if(this_is_front_process) { // Try to bring this process's parent to the front (void) SetFrontProcess(&parent); } } else if(window_hack_state == 1) { if(layer_group) { // Set the window group level back to something less extreme SetWindowGroupLevel(layer_group, kCGNormalWindowLevel); } window_hack_state = 2; } front_window = FrontWindow(); } } #endif F64 elapsed = timer.getElapsedTimeF64(); F64 remaining = plugin->getSleepTime() - elapsed; if(remaining <= 0.0f) { // We've already used our full allotment. // LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, not sleeping" << LL_ENDL; // Still need to service the network... plugin->pump(); } else { // LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL; // timer.reset(); // This also services the network as needed. plugin->sleep(remaining); // LL_INFOS("slplugin") << "slept for "<< timer.getElapsedTimeF64() * 1000.0f << " ms" << LL_ENDL; } #if LL_WINDOWS // More agressive checking of interfering exception handlers. // Doesn't appear to be required so far - even for plugins // that do crash with a single call to the intercept // exception handler such as QuickTime. //checkExceptionHandler(); #endif #if LL_DARWIN deleteAutoReleasePool(); #endif } delete plugin; ll_cleanup_apr(); return 0; }
void PromiseResolver::ResolvePromise(Environment* ev) { CMValue value = fSU->GetCurValue(ev); ODValueRefCon* theRefCon = (ODValueRefCon *) this->GetPromiseInfo(value); if (theRefCon) { ODStorageUnitView* destSUView = kODNULL; ODVolatile(destSUView); TRY fResolvingPromiseInfo = theRefCon; // First we must remove the refCon to stop any recursion this->SetPromiseInfo(value, kODNULL); // Create a view for this storage unit destSUView = fSU->CreateView(ev); #ifdef _PLATFORM_MACINTOSH_ ODDragAndDrop* dragAndDrop = fSU->GetSession(ev)->GetDragAndDrop(ev); if (dragAndDrop->GetDragReference(ev) == 0) { Boolean sameProcess; #else ODBoolean sameProcess = kODTrue; #endif OSErr result; ProcessSerialNumber thePSN; #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_) result = 0; #else result = GetCurrentProcess(&thePSN); THROW_IF_ERROR(result); result = SameProcess(&(theRefCon->sourcePSN), &thePSN, &sameProcess); THROW_IF_ERROR(result); #endif if (sameProcess) { ODPart* sourcePart = theRefCon->sourcePart; if (sourcePart) sourcePart->FulfillPromise(ev, destSUView); } else { WARNMSG(WARN_INDEX(AMSG_410),"Cannot fulfill promise in another process."); } #ifdef _PLATFORM_MACINTOSH_ } else { fSU->GetSession(ev)->GetDragAndDrop(ev)->GetPromiseFromDragManager(ev, theRefCon->sourcePart, destSUView); } #endif destSUView->SetOffset(ev, 0); delete destSUView; ODPart* sourcePart = theRefCon->sourcePart; if (sourcePart) { ODReleaseObject(ev, sourcePart); } ODDisposePtr(theRefCon); this->DecrementPromiseCount(); CATCH_ALL if (destSUView) delete destSUView; fResolvingPromiseInfo = kODNULL; if (ErrorCode() != kODErrUnfocusedStorageUnit) RERAISE; ENDTRY fResolvingPromiseInfo = kODNULL; } }