summaryrefslogtreecommitdiff
path: root/indra/llplugin
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin')
-rw-r--r--indra/llplugin/CMakeLists.txt7
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp118
-rw-r--r--indra/llplugin/llpluginclassmedia.h36
-rw-r--r--indra/llplugin/llpluginmessagepipe.cpp3
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp34
-rw-r--r--indra/llplugin/llpluginprocessparent.h3
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt56
-rw-r--r--indra/llplugin/slplugin/slplugin-objc.mm96
8 files changed, 263 insertions, 90 deletions
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 7fa5c957b6..d56bbc4f96 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -35,7 +35,12 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries( llplugin llcommon llmath llrender llmessage )
+target_link_libraries( llplugin llcommon llmath llmessage llxml )
+
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(llplugin REUSE_FROM llprecompiled)
+endif ()
+
add_subdirectory(slplugin)
include(LibraryInstall)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 17f403e8e8..32ecf7bcd1 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -33,14 +33,16 @@
#include "llpluginmessageclasses.h"
#include "llcontrol.h"
-#if LL_DARWIN || LL_LINUX || __FreeBSD__
+#include <cmath>
+
extern LLControlGroup gSavedSettings;
-#endif
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
extern bool gHiDPISupport;
#endif
static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
+static const U32 MIN_DEBUG_PORT = 1024;
+static const U32 MAX_DEBUG_PORT = 65535;
static int nextPowerOf2( int value )
{
@@ -92,6 +94,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s
void LLPluginClassMedia::reset()
{
+ LL_PROFILE_ZONE_SCOPED;
if(mPlugin)
{
mPlugin->requestShutdown();
@@ -134,9 +137,13 @@ void LLPluginClassMedia::reset()
mLastMouseY = 0;
mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
mSleepTime = 1.0f / 100.0f;
+ mCanUndo = false;
+ mCanRedo = false;
mCanCut = false;
mCanCopy = false;
mCanPaste = false;
+ mCanDoDelete = false;
+ mCanSelectAll = false;
mMediaName.clear();
mMediaDescription.clear();
mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
@@ -166,6 +173,7 @@ void LLPluginClassMedia::reset()
void LLPluginClassMedia::idle(void)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
if(mPlugin)
{
mPlugin->idle();
@@ -370,7 +378,7 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
-#if LL_DARWIN
+#if LL_DARWIN || LL_LINUX
if (!gHiDPISupport)
#endif
{
@@ -909,6 +917,18 @@ void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username,
sendMessage(message);
}
+void LLPluginClassMedia::undo()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_undo");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::redo()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_redo");
+ sendMessage(message);
+}
+
void LLPluginClassMedia::cut()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
@@ -927,6 +947,52 @@ void LLPluginClassMedia::paste()
sendMessage(message);
}
+void LLPluginClassMedia::doDelete()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_delete");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::selectAll()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_select_all");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::showPageSource()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_show_source");
+ sendMessage(message);
+}
+
+
+static U32 assignCefDebuggingPort()
+{
+ U32 base_port = gSavedSettings.getU32("CEFRemoteDebuggingPort");
+ if (base_port == 0)
+ {
+ return 0;
+ }
+ base_port = llclamp<U32>(base_port, MIN_DEBUG_PORT, MAX_DEBUG_PORT);
+
+ static U32 last_base_port = 0;
+ static U32 offset = 0;
+ if (base_port != last_base_port)
+ {
+ last_base_port = base_port;
+ offset = 0;
+ }
+
+ U32 new_port = base_port + offset;
+ if (new_port > MAX_DEBUG_PORT)
+ {
+ return 0;
+ }
+
+ ++offset;
+ return new_port;
+}
+
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
const std::string &username,
const std::string &user_data_path_cef_log)
@@ -936,10 +1002,12 @@ void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache
message.setValue("username", username); // cef shares cache between users but creates user-based contexts
message.setValue("cef_log_file", user_data_path_cef_log);
-#if LL_DARWIN || LL_LINUX || __FreeBSD__
bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
message.setValueBoolean("cef_verbose_log", cef_verbose_log);
-#endif
+
+ U32 cef_remote_debugging_port = assignCefDebuggingPort();
+ message.setValueU32("cef_remote_debugging_port", cef_remote_debugging_port);
+ mCefRemoteDebuggingPort = cef_remote_debugging_port;
sendMessage(message);
}
@@ -985,7 +1053,7 @@ void LLPluginClassMedia::enableMediaPluginDebugging( bool enable )
sendMessage( message );
}
-#if LL_LINUX
+#if LL_LINUX || __FreeBSD__
void LLPluginClassMedia::enablePipeWireVolumeCatcher( bool enable )
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "enable_pipewire_volume_catcher");
@@ -1191,6 +1259,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "edit_state")
{
+ if(message.hasValue("undo"))
+ {
+ mCanUndo = message.getValueBoolean("undo");
+ }
+ if(message.hasValue("redo"))
+ {
+ mCanRedo = message.getValueBoolean("redo");
+ }
if(message.hasValue("cut"))
{
mCanCut = message.getValueBoolean("cut");
@@ -1203,6 +1279,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mCanPaste = message.getValueBoolean("paste");
}
+ if (message.hasValue("delete"))
+ {
+ mCanDoDelete = message.getValueBoolean("delete");
+ }
+ if (message.hasValue("select_all"))
+ {
+ mCanSelectAll = message.getValueBoolean("select_all");
+ }
}
else if(message_name == "name_text")
{
@@ -1586,7 +1670,13 @@ void LLPluginClassMedia::setLoop(bool loop)
void LLPluginClassMedia::setVolume(float volume)
{
- if(volume != mRequestedVolume)
+ // VLC's volume is integer, 0 to 100 range. When converted from float,
+ // changes below 0.01 won't be noticed by VLC.
+ // CEF's audio range is DWORD, 0 to 65535. But changes so small are
+ // inaudible and don't warrant the overhead, so use a bigger epsilon
+ // to avoid extra messages and locking.
+ constexpr float VOLUME_EPSILON = 0.002f;
+ if (std::abs(volume - mRequestedVolume) > VOLUME_EPSILON)
{
mRequestedVolume = volume;
@@ -1612,3 +1702,15 @@ void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
}
+
+void LLPluginClassMedia::forceRenderRefresh()
+{
+ // Force layout recalculation by briefly hiding/showing the web content
+ // Used to clear black screen issues after resize, see #5607
+ const std::string refresh_script =
+ "document.documentElement.style.visibility='hidden';"
+ "document.documentElement.offsetHeight;"
+ "document.documentElement.style.visibility='';";
+
+ executeJavaScript(refresh_script);
+}
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 80862284ff..19a0f1c208 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -29,7 +29,6 @@
#ifndef LL_LLPLUGINCLASSMEDIA_H
#define LL_LLPLUGINCLASSMEDIA_H
-#include "llgltypes.h"
#include "llpluginprocessparent.h"
#include "llrect.h"
#include "llpluginclassmediaowner.h"
@@ -135,7 +134,7 @@ public:
// Text may be unicode (utf8 encoded)
bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
-#if LL_LINUX
+#if LL_LINUX || __FreeBSD__
void enablePipeWireVolumeCatcher( bool enable );
#endif
@@ -170,6 +169,11 @@ public:
std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
+ int getProcessID() { return mPlugin ? (int)mPlugin->getProcessID() : 0; };
+
+ // 0 means remote debugging is disabled for this plugin instance.
+ U32 getCefRemoteDebuggingPort() const { return mCefRemoteDebuggingPort; };
+
bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
@@ -205,6 +209,12 @@ public:
LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
+ void undo();
+ bool canUndo() const { return mCanUndo; };
+
+ void redo();
+ bool canRedo() const { return mCanRedo; };
+
void cut();
bool canCut() const { return mCanCut; };
@@ -214,6 +224,14 @@ public:
void paste();
bool canPaste() const { return mCanPaste; };
+ void doDelete();
+ bool canDoDelete() const { return mCanDoDelete; };
+
+ void selectAll();
+ bool canSelectAll() const { return mCanSelectAll; };
+
+ void showPageSource();
+
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log);
void setLanguageCode(const std::string &language_code);
@@ -343,6 +361,8 @@ public:
std::shared_ptr<LLPluginClassMedia> getSharedPtr() { return std::dynamic_pointer_cast<LLPluginClassMedia>(shared_from_this()); } // due to enable_shared_from_this
+ void forceRenderRefresh();
+
protected:
LLPluginClassMediaOwner *mOwner;
@@ -357,9 +377,9 @@ protected:
bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
S32 mRequestedTextureDepth;
- LLGLenum mRequestedTextureInternalFormat;
- LLGLenum mRequestedTextureFormat;
- LLGLenum mRequestedTextureType;
+ U32 mRequestedTextureInternalFormat;
+ U32 mRequestedTextureFormat;
+ U32 mRequestedTextureType;
bool mRequestedTextureSwapBytes;
bool mRequestedTextureCoordsOpenGL;
@@ -425,9 +445,15 @@ protected:
F64 mSleepTime;
+ U32 mCefRemoteDebuggingPort {0};
+
+ bool mCanUndo;
+ bool mCanRedo;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
+ bool mCanDoDelete;
+ bool mCanSelectAll;
std::string mMediaName;
std::string mMediaTitle;
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 085afc0944..1e58e6c49b 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -121,8 +121,9 @@ bool LLPluginMessagePipe::addMessage(const std::string &message)
mOutputStartIndex = 0;
}
+ mOutput.reserve(mOutput.size() + message.size() + 1);
mOutput += message;
- mOutput += MESSAGE_DELIMITER; // message separator
+ mOutput.push_back(MESSAGE_DELIMITER); // message separator
return true;
}
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 19a0ce639a..f1fd69df2b 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -275,6 +275,9 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcessParams.executable = launcher_filename;
mProcessParams.cwd = plugin_dir;
+#if LL_WINDOWS
+ mProcessParams.envs.add(llformat("SYSTEMROOT=%s", getenv("SYSTEMROOT")));
+#endif
mPluginFile = plugin_filename;
mPluginDir = plugin_dir;
mCPUUsage = 0.0f;
@@ -508,6 +511,16 @@ void LLPluginProcessParent::idle(void)
else if (!mProcess && !mProcessCreationRequested)
{
mProcessCreationRequested = true;
+#if LL_DARWIN
+ // On darwin process should be created from main thread, otherwise it can
+ // cause a fork-lock deadlock. Relevant to both, boost and apr.
+ // Alternatively can remake process creation to use posix_spawn
+ if (!(mProcess = LLProcess::create(mProcessParams)))
+ {
+ mProcessCreationRequested = false;
+ errorState();
+ }
+#else
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
// *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak
// pointer
@@ -558,6 +571,7 @@ void LLPluginProcessParent::idle(void)
errorState();
}
}
+#endif
}
if (mProcess)
@@ -575,7 +589,7 @@ void LLPluginProcessParent::idle(void)
params.args.add("-e");
params.args.add("tell application \"Terminal\"");
params.args.add("-e");
- params.args.add(STRINGIZE("set win to do script \"lldb -pid "
+ params.args.add(STRINGIZE("set win to do script \"lldb -p "
<< mProcess->getProcessID() << "\""));
params.args.add("-e");
params.args.add("do script \"continue\" in win");
@@ -982,14 +996,18 @@ void LLPluginProcessParent::poll(F64 timeout)
}
}
- // Remove instances in the done state from the sInstances map.
- mapInstances_t::iterator itClean = sInstances.begin();
- while (itClean != sInstances.end())
+ if (sInstancesMutex)
{
- if ((*itClean).second->isDone())
- itClean = sInstances.erase(itClean);
- else
- ++itClean;
+ // Remove instances in the done state from the sInstances map.
+ LLCoros::LockType lock(*sInstancesMutex);
+ mapInstances_t::iterator itClean = sInstances.begin();
+ while (itClean != sInstances.end())
+ {
+ if ((*itClean).second->isDone())
+ itClean = sInstances.erase(itClean);
+ else
+ ++itClean;
+ }
}
}
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 334f1411af..3cfd4211d7 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -30,7 +30,6 @@
#define LL_LLPLUGINPROCESSPARENT_H
#include <queue>
-#include <boost/enable_shared_from_this.hpp>
#include "llapr.h"
#include "llprocess.h"
@@ -120,6 +119,8 @@ public:
bool getDisableTimeout() { return mDisableTimeout; };
void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
+ LLProcess::id getProcessID() const { return mProcess ? mProcess->getProcessID() : 0; }
+
void setLaunchTimeout(F32 timeout) { mPluginLaunchTimeout = timeout; };
void setLockupTimeout(F32 timeout) { mPluginLockupTimeout = timeout; };
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index d29731894f..a32dc4cbe6 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -18,6 +18,12 @@ if (DARWIN)
list(APPEND SLPlugin_HEADER_FILES
slplugin-objc.h
)
+
+ set_source_files_properties(
+ slplugin-objc.mm
+ PROPERTIES
+ SKIP_PRECOMPILE_HEADERS TRUE
+ )
endif (DARWIN)
if (SLPlugin_HEADER_FILES)
@@ -30,18 +36,6 @@ add_executable(SLPlugin
${SLPlugin_SOURCE_FILES}
)
-if (WINDOWS)
-set_target_properties(SLPlugin
- PROPERTIES
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
- )
-else ()
-set_target_properties(SLPlugin
- PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
- )
-endif ()
-
target_link_libraries(SLPlugin
llplugin
llmessage
@@ -49,7 +43,24 @@ target_link_libraries(SLPlugin
ll::pluginlibraries
)
-if (DARWIN)
+if (USE_PRECOMPILED_HEADERS)
+ target_precompile_headers(SLPlugin REUSE_FROM llprecompiled)
+endif ()
+
+if (WINDOWS)
+ set_target_properties(SLPlugin
+ PROPERTIES
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
+ )
+elseif (DARWIN)
+ set_target_properties(SLPlugin
+ PROPERTIES
+ BUILD_WITH_INSTALL_RPATH 1
+ INSTALL_RPATH "@executable_path/../../../../Frameworks;@executable_path/../Frameworks;@executable_path/../Frameworks/plugins"
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
+ XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
+ )
+
# 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
@@ -58,7 +69,14 @@ if (DARWIN)
-p
${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Frameworks
)
-endif (DARWIN)
+endif ()
+
+if (CMAKE_BUILD_TYPE MATCHES Release AND (CMAKE_CXX_COMPILER_ID STREQUAL Clang OR CMAKE_CXX_COMPILER_ID MATCHES GNU))
+ add_custom_command(
+ TARGET ${PROJECT_NAME} POST_BUILD
+ COMMAND ${CMAKE_STRIP} "$<TARGET_FILE:${PROJECT_NAME}>"
+ )
+endif ()
if (BUILD_SHARED_LIBS)
set_target_properties(SLPlugin PROPERTIES LINK_FLAGS_RELEASE
@@ -66,14 +84,16 @@ if (BUILD_SHARED_LIBS)
endif ()
if (INSTALL)
- if (DARWIN)
+ if (DARWIN OR WINDOWS)
install(TARGETS ${PROJECT_NAME} DESTINATION .)
+ elseif (${LINUX_DISTRO} MATCHES freedesktop)
+ install(TARGETS ${PROJECT_NAME} DESTINATION libexec)
elseif (${LINUX_DISTRO} MATCHES arch)
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${VIEWER_BINARY_NAME})
- else (DARWIN)
+ else ()
install(TARGETS ${PROJECT_NAME} DESTINATION libexec/${VIEWER_BINARY_NAME})
- endif (DARWIN)
-endif (INSTALL)
+ endif ()
+endif ()
if (LL_TESTS)
ll_deploy_sharedlibs_command(SLPlugin)
diff --git a/indra/llplugin/slplugin/slplugin-objc.mm b/indra/llplugin/slplugin/slplugin-objc.mm
index 68ff196eaf..adde594b59 100644
--- a/indra/llplugin/slplugin/slplugin-objc.mm
+++ b/indra/llplugin/slplugin/slplugin-objc.mm
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
@@ -38,51 +38,51 @@
void LLCocoaPlugin::setupCocoa()
{
- static bool inited = false;
-
- if(!inited)
- {
- createAutoReleasePool();
-
- // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
- // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
- // when init'ing the Cocoa App window.
- [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
-
- // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
- // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
-
- // Needed for Carbon based applications which call into Cocoa
- NSApplicationLoad();
+ static bool inited = false;
+
+ if(!inited)
+ {
+ createAutoReleasePool();
+
+ // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents.
+ // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr'
+ // when init'ing the Cocoa App window.
+ [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
+
+ // This is a bit of voodoo taken from the Apple sample code "CarbonCocoa_PictureCursor":
+ // http://developer.apple.com/samplecode/CarbonCocoa_PictureCursor/index.html
+
+ // Needed for Carbon based applications which call into Cocoa
+ NSApplicationLoad();
+
+ // 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];
- // 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;
- }
+
+ deleteAutoReleasePool();
+
+ inited = true;
+ }
}
static NSAutoreleasePool *sPool = NULL;
void LLCocoaPlugin::createAutoReleasePool()
{
- if(!sPool)
- {
- sPool = [[NSAutoreleasePool alloc] init];
- }
+ if(!sPool)
+ {
+ sPool = [[NSAutoreleasePool alloc] init];
+ }
}
void LLCocoaPlugin::deleteAutoReleasePool()
{
- if(sPool)
- {
- [sPool release];
- sPool = NULL;
- }
+ if(sPool)
+ {
+ [sPool release];
+ sPool = NULL;
+ }
}
LLCocoaPlugin::LLCocoaPlugin():mHackState(0)
@@ -110,12 +110,12 @@ void LLCocoaPlugin::setupGroup()
// {
// // 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);
+ // SetWindowGroupLevel(layer_group, kCGOverlayWindowLevel);
// }
-
+
}
-void LLCocoaPlugin::updateWindows()
+void LLCocoaPlugin::updateWindows()
{
// NSArray* window_list = [NSApp orderedWindows];
// NSWindow* current_window = [window_list objectAtIndex:0];
@@ -123,38 +123,38 @@ void LLCocoaPlugin::updateWindows()
// 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
@@ -171,7 +171,7 @@ void LLCocoaPlugin::updateWindows()
//// }
// mHackState = 2;
// }
-//
+//
// mFrontWindow = [window_list objectAtIndex:0];
// }
}