/***************************************************** * * Handle_CommandUpdateStatus(inHandlerCallRef, inEvent, inUserData) * * Purpose: called to update status of the commands, enabling or disabling the menu items * * Inputs: inHandlerCallRef - reference to the current handler call chain * inEvent - the event * inUserData - app-specified data you passed in the call to InstallEventHandler * * Returns: OSStatus - noErr indicates the event was handled * eventNotHandledErr indicates the event was not handled and the Toolbox should take over */ static pascal OSStatus Handle_CommandUpdateStatus(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData) { OSStatus status = eventNotHandledErr; HICommand aCommand; GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand); WindowRef aWindowRef = GetFrontWindowOfClass(kDocumentWindowClass, true); if (aWindowRef == NULL) { switch (aCommand.commandID) { case kHICommandClose: DisableMenuItem(aCommand.menu.menuRef, aCommand.menu.menuItemIndex); break; } } else { switch (aCommand.commandID) { case kHICommandClose: EnableMenuItem(aCommand.menu.menuRef, aCommand.menu.menuItemIndex); break; } } return status; } // Handle_CommandUpdateStatus
static void OPL_DSN_notification_item (ControlRef browser, DataBrowserItemID itemID, DataBrowserItemNotification message) { OSStatus err; WindowRef window; window = GetFrontWindowOfClass(kMovableModalWindowClass, false); if (window == NULL) return; // get LoginDialog instance OPL_LoginDialog *dlg = NULL; err = GetWindowProperty(window, kPropertyCreator, kPropertyTag, sizeof(dlg), NULL, &dlg); require_noerr(err, error); if (!dlg) return; switch (message) { case kDataBrowserItemDoubleClicked: dlg->dir_dblclick(); break; }; error: return; }
// -------------------------------------------------------------------------------------- static pascal OSErr viewsFontChangedAEHandler(const AppleEvent *appleEvent, AppleEvent *reply, long refcon) { #pragma unused (reply, refcon) OSErr error; DescType returnedType; Size actualSize; error = AEGetAttributePtr(appleEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, NULL, 0, &actualSize); if (error == noErr) error = errAEParamMissed; else if (error == errAEDescNotFound) { WindowRef window; for (window = GetFrontWindowOfClass(kDocumentWindowClass, false); window != NULL; window = GetNextWindowOfClass(window, kDocumentWindowClass, false)) { if (GetWindowKind(window) == kDialogWindowKind) RedrawPrefsDialogDataBrowser(GetDialogFromWindow(window)); else // kApplicationWindowKind RedrawPrefsWindowDataBrowser(window); } error = noErr; } return error; }
/***************************************************** * * Handle_ReopenApplication(inAppleEvent, reply, inHandlerRefcon) * * Purpose: AppleEvent handler for the kAEReopenApplication event * * Inputs: inAppleEvent - the Apple event * reply - our reply to the Apple event * inHandlerRefcon - refcon passed to AEInstallEventHandler when this hander was installed * * Returns: OSErr - error code (0 == no error) */ static pascal OSErr Handle_ReopenApplication(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon) { // We were already running but with no windows so we create an empty one. WindowRef theWindow = GetFrontWindowOfClass(kDocumentWindowClass, true); if (theWindow == NULL) return Do_NewWindow(NULL); else return noErr; } // Handle_ReopenApplication
/***************************************************** * * Do_CleanUp(void) * * Purpose: called when we get the quit event, closes all the windows. * * Inputs: none * * Returns: OSStatus - eventNotHandledErr indicates that the quit process can continue */ static OSStatus Do_CleanUp(void) { WindowRef windowToDispose, aWindowRef = GetFrontWindowOfClass(kDocumentWindowClass, true); for ( ; aWindowRef != NULL; ) { windowToDispose = aWindowRef; aWindowRef = GetNextWindowOfClass(aWindowRef, kDocumentWindowClass, true); DisposeWindow(windowToDispose); } return eventNotHandledErr; } // Do_CleanUp
// -------------------------------------------------------------------------------------- static pascal OSErr viewsFontChangedAEHandler(const AppleEvent *appleEvent, AppleEvent *reply, long refcon) { #pragma unused (reply, refcon) OSErr error; DescType returnedType; Size actualSize; error = AEGetAttributePtr(appleEvent, keyMissedKeywordAttr, typeWildCard, &returnedType, NULL, 0, &actualSize); if (error == noErr) error = errAEParamMissed; else if (error == errAEDescNotFound) { WindowRef window; FourCharCode prefsWindowKind; for (window = GetFrontWindowOfClass(kDocumentWindowClass, false); window != NULL; window = GetNextWindowOfClass(window, kDocumentWindowClass, false)) { GetWindowProperty(window, kAppSignature, kPrefsWindowKindTag, sizeof(FourCharCode), NULL, &prefsWindowKind); if (prefsWindowKind == kPrefsWindowKindDialog) RedrawPrefsDialogDataBrowser(window); else // kPrefsWindowKindWindow RedrawPrefsWindowDataBrowser(window); } error = noErr; } return error; }
int main(int argc, char **argv) #endif { // 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(GetFrontWindowOfClass(kAllWindowClasses, true) != 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((GetFrontWindowOfClass(kAllWindowClasses, true) != 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(GetFrontWindowOfClass(kAllWindowClasses, true), layer_group); } if(parent_is_front_process) { // Bring this process's windows to the front. (void) SetFrontProcess( &self ); } ActivateWindow(GetFrontWindowOfClass(kAllWindowClasses, true), true); } else if((GetFrontWindowOfClass(kAllWindowClasses, true) == 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 = GetFrontWindowOfClass(kAllWindowClasses, true); } } #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; return 0; }
// Event handling for HICommand events pascal OSStatus CommandProcess(EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) { #pragma unused (nextHandler, userData) WindowRef window; HIViewRef textView; HICommandExtended inCommand; OSStatus status = noErr; status = GetEventParameter(theEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommandExtended), NULL, &inCommand); require_noerr( status, CantGetEventParameter); // Check to see if this came from one of the buttons if ( inCommand.attributes & kHICommandFromControl ) { ControlRef hitControl; // Get the control and the window & text view associated with it hitControl = inCommand.source.control; window = HIViewGetWindow(hitControl); status = GetTextViewFromWindow(window, textView); if ( status != noErr ) return status; // The button controls need the text view to be the active focus // in order for the HICommands to be correctly dispatched. // So we will just force the TextView to be the focus before handling. // the HICommand. status = TextViewFocusInWindow( HIViewGetWindow(hitControl) ); if ( status != noErr ) return status; switch (inCommand.commandID) { case kDefaultHITextViewCommand: // **** Reset button status = TextViewDefaultSettings( textView ); if (status == noErr) status = UpdateControlsFromTextViewWindow(window); if (status == noErr) status = TextViewFocusInWindow( window ); break; case kFontPanelSupportCommand: // **** Checkboxes if ( GetControl32BitValue(hitControl) == kControlCheckBoxCheckedValue ) status = TextViewDemoFontPanelSupport( textView ); else status = TextViewFontPanelSupport(textView, false); break; case kDemoSpellingSupportCommand: if ( GetControl32BitValue(hitControl) == kControlCheckBoxCheckedValue ) status = TextViewDemoSpellingSupport( textView ); else status = TextViewSpellingSupport(textView, false); break; case kDemoAutoScrollCommand: // **** Radio button // The radio button values correspond to the MLTE auto scroll constants // plus one (the constants start from zero, the radio button values // start from one): // // (radio button 1) kTXNAutoScrollInsertionIntoView == 0 // (radio button 2) kTXNAutoScrollNever == 1 // (radio button 3) kTXNAutoScrollWhenInsertionVisible == 2 // // See the definition of the type TXNAutoScrollBehavior for // more information on each constant and its associated behavior. status = TextViewScrollingOptions( textView, (UInt32)(GetControl32BitValue(hitControl) - 1) ); break; case kDemoActionGrouping: // **** Demo actions status = TextViewDemoActionGroup( textView ); break; case kHICommandSave: case kDemoCFURLWriteCommand: status = TextViewDemoWriteToCFURL( textView ); break; case kDemoCFURLReadCommand: status = TextViewDemoReadFromCFURL( textView ); break; default: status = eventNotHandledErr; break; } } else { switch (inCommand.commandID) { case kHICommandNew: status = NewWindow(); break; case kHICommandOpen: window = GetFrontWindowOfClass(kDocumentWindowClass, true); if ( window != NULL ) { status = GetTextViewFromWindow(window, textView); if ( status == noErr ) status = TextViewDemoReadFromCFURL( textView ); } break; default: status = eventNotHandledErr; break; } } CantGetEventParameter: return status; }