Fixed web browser thanks to ArminW/Imprudence

This commit is contained in:
Siana Gearz
2010-12-24 22:22:20 +01:00
parent 80fe022718
commit 1d6bb3f3ea
59 changed files with 3505 additions and 1140 deletions

170
indra/llplugin/slplugin/slplugin.cpp Normal file → Executable file
View File

@@ -1,10 +1,12 @@
/**
/**
* @file slplugin.cpp
* @brief Loader shell for plugins, intended to be launched by the plugin host application, which directly loads a plugin dynamic library.
*
* @cond
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
* Copyright (c) 2008-2010, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -12,13 +14,13 @@
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* online at http://secondlife.com/developers/opensource/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* http://secondlife.com/developers/opensource/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
@@ -28,6 +30,9 @@
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*
*
* @endcond
*/
@@ -41,6 +46,7 @@
#if LL_DARWIN
#include <Carbon/Carbon.h>
#include "slplugin-objc.h"
#endif
#if LL_DARWIN || LL_LINUX
@@ -48,16 +54,17 @@
#endif
/*
On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly flag in the Info.plist.
On Mac OS, since we call WaitNextEvent, this process will show up in the dock unless we set the LSBackgroundOnly or LSUIElement flag in the Info.plist.
Normally non-bundled binaries don't have an info.plist file, but it's possible to embed one in the binary by adding this to the linker flags:
-sectcreate __TEXT __info_plist /path/to/slplugin_info.plist
which means adding this to the gcc flags:
-Wl,-sectcreate,__TEXT,__info_plist,/path/to/slplugin_info.plist
Now that SLPlugin is a bundled app on the Mac, this is no longer necessary (it can just use a regular Info.plist file), but I'm leaving this comment in for posterity.
*/
#if LL_DARWIN || LL_LINUX
@@ -68,7 +75,7 @@ static void crash_handler(int sig)
// TODO: add our own crash reporting
_exit(1);
}
#endif
#endif
#if LL_WINDOWS
#include <windows.h>
@@ -81,7 +88,7 @@ LONG WINAPI myWin32ExceptionHandler( struct _EXCEPTION_POINTERS* exception_infop
//std::cerr << "intercepted an unhandled exception and will exit immediately." << std::endl;
// TODO: replace exception handler before we exit?
return EXCEPTION_EXECUTE_HANDLER;
return EXCEPTION_EXECUTE_HANDLER;
}
// Taken from : http://blog.kalmbachnet.de/?postid=75
@@ -153,7 +160,7 @@ bool checkExceptionHandler()
if (prev_filter == NULL)
{
ok = FALSE;
if (myWin32ExceptionHandler == NULL)
if (NULL == myWin32ExceptionHandler)
{
LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL;
}
@@ -167,7 +174,7 @@ bool checkExceptionHandler()
}
#endif
// If this application on Windows platform is a console application, a console is always
// If this application on Windows platform is a console application, a console is always
// created which is bad. Making it a Windows "application" via CMake settings but not
// adding any code to explicitly create windows does the right thing.
#if LL_WINDOWS
@@ -178,7 +185,7 @@ int main(int argc, char **argv)
{
ll_init_apr();
// Set up llerror logging
// Set up llerror logging
{
LLError::initForApplication(".");
LLError::setDefaultLevel(LLError::LEVEL_INFO);
@@ -191,25 +198,23 @@ int main(int argc, char **argv)
{
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
// 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
setpriority(PRIO_PROCESS, getpid(), 19);
if(argc < 2)
{
LL_ERRS("slplugin") << "usage: " << argv[0] << " launcher_port" << LL_ENDL;
}
U32 port = 0;
if(!LLStringUtil::convertToU32(argv[1], port))
{
@@ -227,23 +232,50 @@ int main(int argc, char **argv)
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())
{
timer.reset();
#if LL_DARWIN
createAutoReleasePool();
#endif
timer.reset();
plugin->idle();
#if LL_DARWIN
{
@@ -254,11 +286,85 @@ int main(int argc, char **argv)
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.
@@ -271,26 +377,30 @@ int main(int argc, char **argv)
{
// LL_INFOS("slplugin") << "elapsed = " << elapsed * 1000.0f << " ms, remaining = " << remaining * 1000.0f << " ms, sleeping for " << remaining * 1000.0f << " ms" << LL_ENDL;
// timer.reset();
// 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
// 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();
ll_cleanup_apr();
return 0;
}