From eca619985206462d39dc9ae665857e97948562da Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Mon, 12 Nov 2012 18:06:32 -0800
Subject: Ported slplugin and some other missing components for cocoa.

---
 indra/llplugin/slplugin/CMakeLists.txt   |   3 +-
 indra/llplugin/slplugin/slplugin-objc.h  |  22 +++++-
 indra/llplugin/slplugin/slplugin-objc.mm | 101 +++++++++++++++++++++++-
 indra/llplugin/slplugin/slplugin.cpp     | 131 ++++++-------------------------
 4 files changed, 140 insertions(+), 117 deletions(-)

(limited to 'indra/llplugin')

diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 3fc54573a7..8183467dc5 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -15,7 +15,6 @@ include_directories(
 
 if (DARWIN)
     include(CMakeFindFrameworks)
-    find_library(CARBON_LIBRARY Carbon)
     find_library(COCOA_LIBRARY Cocoa)
 endif (DARWIN)
 
@@ -68,7 +67,7 @@ add_dependencies(SLPlugin
 
 if (DARWIN)
   # Mac version needs to link against Carbon
-  target_link_libraries(SLPlugin ${CARBON_LIBRARY} ${COCOA_LIBRARY})
+  target_link_libraries(SLPlugin ${COCOA_LIBRARY})
   # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
   add_custom_command(
     TARGET SLPlugin POST_BUILD
diff --git a/indra/llplugin/slplugin/slplugin-objc.h b/indra/llplugin/slplugin/slplugin-objc.h
index 602d848f7e..9a8e81873f 100644
--- a/indra/llplugin/slplugin/slplugin-objc.h
+++ b/indra/llplugin/slplugin/slplugin-objc.h
@@ -28,8 +28,24 @@
  * @endcond
  */
 
+//Protos for ObjectiveC classes (cannot import cocoa here due to BOOL conflict)
+class NSWindow;
 
 /* Defined in slplugin-objc.mm: */
-void setupCocoa();
-void createAutoReleasePool();
-void deleteAutoReleasePool();
+
+class LLCocoaPlugin
+{
+public:  
+    LLCocoaPlugin();
+    void setupCocoa();
+    void createAutoReleasePool();
+    void deleteAutoReleasePool();
+    void setupGroup();
+    void updateWindows();
+    void processEvents();
+public:
+    //EventTargetRef mEventTarget;
+    NSWindow* mFrontWindow;
+    NSWindow* mPluginWindow;
+    int mHackState;
+};
\ No newline at end of file
diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm
index 646416b9d2..a434739350 100644
--- a/indra/llplugin/slplugin/slplugin-objc.mm
+++ b/indra/llplugin/slplugin/slplugin-objc.mm
@@ -30,11 +30,13 @@
 
 
 #include <AppKit/AppKit.h>
+#import <Cocoa/Cocoa.h>
 
 #include "slplugin-objc.h"
 
+//Note: NSApp is a global defined by cocoa which is an id to the application.
 
-void setupCocoa()
+void LLCocoaPlugin::setupCocoa()
 {
 	static bool inited = false;
 	
@@ -56,6 +58,8 @@ void setupCocoa()
 		//	Must first call [[[NSWindow alloc] init] release] to get the NSWindow machinery set up so that NSCursor can use a window to cache the cursor image
 		[[[NSWindow alloc] init] release];
 		
+        mPluginWindow = [NSApp mainWindow];
+        
 		deleteAutoReleasePool();
 		
 		inited = true;
@@ -64,7 +68,7 @@ void setupCocoa()
 
 static NSAutoreleasePool *sPool = NULL;
 
-void createAutoReleasePool()
+void LLCocoaPlugin::createAutoReleasePool()
 {
 	if(!sPool)
 	{
@@ -72,7 +76,7 @@ void createAutoReleasePool()
 	}
 }
 
-void deleteAutoReleasePool()
+void LLCocoaPlugin::deleteAutoReleasePool()
 {
 	if(sPool)
 	{
@@ -80,3 +84,94 @@ void deleteAutoReleasePool()
 		sPool = NULL;
 	}
 }
+
+LLCocoaPlugin::LLCocoaPlugin():mHackState(0)
+{
+    NSArray* window_list = [NSApp orderedWindows];
+    mFrontWindow = [window_list objectAtIndex:0];
+}
+
+void LLCocoaPlugin::processEvents()
+{
+     // Some plugins (webkit at least) will want an event loop.  This qualifies.
+    NSEvent * event;
+    event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES];
+    [NSApp sendEvent: event];
+}
+
+
+//Turns out the window ordering stuff never gets hit with any of the current plugins.
+//Leaving the following code here 'just in case' for the time being.
+
+void LLCocoaPlugin::setupGroup()
+{
+    //    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);		
+    //    }
+    
+}
+
+void LLCocoaPlugin::updateWindows()  //SPATTERS give this a better name.
+{
+//    NSArray* window_list = [NSApp orderedWindows];
+//    NSWindow* current_window = [window_list objectAtIndex:0];
+//    NSWindow* parent_window = [ current_window parentWindow ];
+//    bool this_is_front_process = false;
+//    bool parent_is_front_process = false;
+//
+//    
+//    // Check for a change in this process's frontmost window.
+//    if ( current_window != mFrontWindow )
+//    {
+//        // and figure out whether this process or its parent are currently frontmost
+//        if ( current_window == parent_window ) parent_is_front_process = true;
+//        if ( current_window == mPluginWindow ) this_is_front_process = true;
+//    
+//        if (current_window != NULL && mFrontWindow == NULL)
+//        {
+//            // Opening the first window
+//            
+//            if(mHackState == 0)
+//            {
+//                // Next time through the event loop, lower the window group layer
+//                mHackState = 1;
+//            }
+//            
+//            if(parent_is_front_process)
+//            {
+//                // Bring this process's windows to the front.
+//                [mPluginWindow makeKeyAndOrderFront:NSApp];
+//                [mPluginWindow setOrderedIndex:0];
+//            }
+//            
+//            [NSApp activateIgnoringOtherApps:YES];
+//        }
+//        
+//        else if (( current_window == NULL) && (mFrontWindow != NULL))
+//        {
+//            // Closing the last window
+//            
+//            if(this_is_front_process)
+//            {
+//                // Try to bring this process's parent to the front
+//                [parent_window makeKeyAndOrderFront:NSApp];
+//                [parent_window setOrderedIndex:0];
+//            }
+//        }
+//        else if(mHackState == 1)
+//        {
+////            if(layer_group)
+////            {
+////                // Set the window group level back to something less extreme
+////                SetWindowGroupLevel(layer_group, kCGNormalWindowLevel);
+////            }
+//            mHackState = 2;
+//        }
+//        
+//        mFrontWindow = [window_list objectAtIndex:0];
+//    }
+ }
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 516a58db88..6c9ba0ae52 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -37,8 +37,12 @@
 #include "llapr.h"
 #include "llstring.h"
 
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+
 #if LL_DARWIN
-	#include <Carbon/Carbon.h>
 	#include "slplugin-objc.h"
 #endif
 
@@ -176,6 +180,7 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
 int main(int argc, char **argv)
 #endif
 {
+
 	ll_init_apr();
 
 	// Set up llerror logging
@@ -216,26 +221,25 @@ int main(int argc, char **argv)
 
 	// 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
+	signal(SIGEMT, &crash_handler);		// emulate instruction executed
 
-#if LL_DARWIN
-	setupCocoa();
-	createAutoReleasePool();
-#endif
+    LLCocoaPlugin cocoa_interface;
+	cocoa_interface.setupCocoa();
+	cocoa_interface.createAutoReleasePool();
+#endif //LL_DARWIN
 
 	LLPluginProcessChild *plugin = new LLPluginProcessChild();
 
 	plugin->init(port);
 
 #if LL_DARWIN
-		deleteAutoReleasePool();
+    cocoa_interface.deleteAutoReleasePool();
 #endif
 
 	LLTimer timer;
@@ -246,114 +250,22 @@ int main(int argc, char **argv)
 #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();
+ //   cocoa_interface.mEventTarget = GetEventDispatcherTarget();
 #endif
 	while(!plugin->isDone())
 	{
 #if LL_DARWIN
-		createAutoReleasePool();
+		cocoa_interface.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);
-
-			}
-		}
+			cocoa_interface.processEvents();
+        }
 #endif
 		F64 elapsed = timer.getElapsedTimeF64();
 		F64 remaining = plugin->getSleepTime() - elapsed;
@@ -377,7 +289,8 @@ int main(int argc, char **argv)
 
 //			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
@@ -387,14 +300,14 @@ int main(int argc, char **argv)
 #endif
 
 #if LL_DARWIN
-		deleteAutoReleasePool();
+		cocoa_interface.deleteAutoReleasePool();
 #endif
 	}
-
 	delete plugin;
 
 	ll_cleanup_apr();
 
+
 	return 0;
 }
 
-- 
cgit v1.2.3


From 2282d6b11a2d46387514c9a352b4ccae5fa6e5d9 Mon Sep 17 00:00:00 2001
From: Aura Linden <aura@lindenlab.com>
Date: Thu, 13 Dec 2012 12:24:17 -0800
Subject: Fixed whitespace issues for merge.

---
 indra/llplugin/slplugin/slplugin-objc.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'indra/llplugin')

diff --git a/indra/llplugin/slplugin/slplugin-objc.h b/indra/llplugin/slplugin/slplugin-objc.h
index 9a8e81873f..f2c2b3239c 100644
--- a/indra/llplugin/slplugin/slplugin-objc.h
+++ b/indra/llplugin/slplugin/slplugin-objc.h
@@ -48,4 +48,6 @@ public:
     NSWindow* mFrontWindow;
     NSWindow* mPluginWindow;
     int mHackState;
-};
\ No newline at end of file
+};
+
+
-- 
cgit v1.2.3