Fixed web browser thanks to ArminW/Imprudence
This commit is contained in:
170
indra/llplugin/slplugin/slplugin.cpp
Normal file → Executable file
170
indra/llplugin/slplugin/slplugin.cpp
Normal file → Executable 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user