summaryrefslogtreecommitdiff
path: root/indra/media_plugins
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-15 16:35:49 +0300
committerGitHub <noreply@github.com>2024-05-15 16:35:49 +0300
commite49dcb8d0c9f539997effb640e350d9d0689aae6 (patch)
tree1bf99eaccce6de17c62f13c6595f7f497548dc5c /indra/media_plugins
parent531cd34f670170ade57f8813fe48012b61a1d3c2 (diff)
parent5f8a7374b9f18e0112d6749a9c845bd077a81acb (diff)
Merge pull request #1476 from secondlife/marchcat/x-b-merge
Maint X -> Maint B merge
Diffstat (limited to 'indra/media_plugins')
-rw-r--r--indra/media_plugins/base/media_plugin_base.cpp154
-rw-r--r--indra/media_plugins/base/media_plugin_base.h118
-rwxr-xr-xindra/media_plugins/cef/linux_volume_catcher.cpp514
-rw-r--r--indra/media_plugins/cef/mac_volume_catcher.cpp322
-rw-r--r--indra/media_plugins/cef/mac_volume_catcher_null.cpp50
-rw-r--r--indra/media_plugins/cef/media_plugin_cef.cpp1410
-rw-r--r--indra/media_plugins/cef/volume_catcher.h30
-rw-r--r--indra/media_plugins/cef/windows_volume_catcher.cpp62
-rw-r--r--indra/media_plugins/example/media_plugin_example.cpp618
-rw-r--r--indra/media_plugins/gstreamer10/llmediaimplgstreamer.h14
-rw-r--r--indra/media_plugins/libvlc/media_plugin_libvlc.cpp906
11 files changed, 2099 insertions, 2099 deletions
diff --git a/indra/media_plugins/base/media_plugin_base.cpp b/indra/media_plugins/base/media_plugin_base.cpp
index dbbc973f00..3c603440df 100644
--- a/indra/media_plugins/base/media_plugin_base.cpp
+++ b/indra/media_plugins/base/media_plugin_base.cpp
@@ -1,28 +1,28 @@
-/**
+/**
* @file media_plugin_base.cpp
* @brief Media plugin base class for LLMedia API plugin system
*
- * All plugins should be a subclass of MediaPluginBase.
+ * All plugins should be a subclass of MediaPluginBase.
*
* @cond
* $LicenseInfo:firstyear=2008&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$
* @endcond
@@ -40,102 +40,102 @@
/// @param[in] host_user_data Message data for messages from plugin to plugin loader shell
MediaPluginBase::MediaPluginBase(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data )
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data )
{
- mHostSendFunction = host_send_func;
- mHostUserData = host_user_data;
- mDeleteMe = false;
- mPixels = 0;
- mWidth = 0;
- mHeight = 0;
- mTextureWidth = 0;
- mTextureHeight = 0;
- mDepth = 0;
- mStatus = STATUS_NONE;
+ mHostSendFunction = host_send_func;
+ mHostUserData = host_user_data;
+ mDeleteMe = false;
+ mPixels = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mTextureWidth = 0;
+ mTextureHeight = 0;
+ mDepth = 0;
+ mStatus = STATUS_NONE;
}
/**
* Converts current media status enum value into string (STATUS_LOADING into "loading", etc.)
- *
+ *
* @return Media status string ("loading", "playing", "paused", etc)
*
*/
std::string MediaPluginBase::statusString()
{
- std::string result;
-
- switch(mStatus)
- {
- case STATUS_LOADING: result = "loading"; break;
- case STATUS_LOADED: result = "loaded"; break;
- case STATUS_ERROR: result = "error"; break;
- case STATUS_PLAYING: result = "playing"; break;
- case STATUS_PAUSED: result = "paused"; break;
- case STATUS_DONE: result = "done"; break;
- default:
- // keep the empty string
- break;
- }
-
- return result;
+ std::string result;
+
+ switch(mStatus)
+ {
+ case STATUS_LOADING: result = "loading"; break;
+ case STATUS_LOADED: result = "loaded"; break;
+ case STATUS_ERROR: result = "error"; break;
+ case STATUS_PLAYING: result = "playing"; break;
+ case STATUS_PAUSED: result = "paused"; break;
+ case STATUS_DONE: result = "done"; break;
+ default:
+ // keep the empty string
+ break;
+ }
+
+ return result;
}
-
+
/**
* Set media status.
- *
+ *
* @param[in] status Media status (STATUS_LOADING, STATUS_PLAYING, STATUS_PAUSED, etc)
*
*/
void MediaPluginBase::setStatus(EStatus status)
{
- if(mStatus != status)
- {
- mStatus = status;
- sendStatus();
- }
+ if(mStatus != status)
+ {
+ mStatus = status;
+ sendStatus();
+ }
}
/**
* Receive message from plugin loader shell.
- *
+ *
* @param[in] message_string Message string
* @param[in] user_data Message data
*
*/
void MediaPluginBase::staticReceiveMessage(const char *message_string, void **user_data)
{
- MediaPluginBase *self = (MediaPluginBase*)*user_data;
-
- if(self != NULL)
- {
- self->receiveMessage(message_string);
-
- // If the plugin has processed the delete message, delete it.
- if(self->mDeleteMe)
- {
- delete self;
- *user_data = NULL;
- }
- }
+ MediaPluginBase *self = (MediaPluginBase*)*user_data;
+
+ if(self != NULL)
+ {
+ self->receiveMessage(message_string);
+
+ // If the plugin has processed the delete message, delete it.
+ if(self->mDeleteMe)
+ {
+ delete self;
+ *user_data = NULL;
+ }
+ }
}
/**
* Send message to plugin loader shell.
- *
+ *
* @param[in] message Message data being sent to plugin loader shell
*
*/
void MediaPluginBase::sendMessage(const LLPluginMessage &message)
{
- std::string output = message.generate();
- mHostSendFunction(output.c_str(), &mHostUserData);
+ std::string output = message.generate();
+ mHostSendFunction(output.c_str(), &mHostUserData);
}
/**
* Notifies plugin loader shell that part of display area needs to be redrawn.
- *
+ *
* @param[in] left Left X coordinate of area to redraw (0,0 is at top left corner)
* @param[in] top Top Y coordinate of area to redraw (0,0 is at top left corner)
* @param[in] right Right X-coordinate of area to redraw (0,0 is at top left corner)
@@ -144,27 +144,27 @@ void MediaPluginBase::sendMessage(const LLPluginMessage &message)
*/
void MediaPluginBase::setDirty(int left, int top, int right, int bottom)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
-
- message.setValueS32("left", left);
- message.setValueS32("top", top);
- message.setValueS32("right", right);
- message.setValueS32("bottom", bottom);
-
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+
+ message.setValueS32("left", left);
+ message.setValueS32("top", top);
+ message.setValueS32("right", right);
+ message.setValueS32("bottom", bottom);
+
+ sendMessage(message);
}
/**
* Sends "media_status" message to plugin loader shell ("loading", "playing", "paused", etc.)
- *
+ *
*/
void MediaPluginBase::sendStatus()
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status");
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "media_status");
+
+ message.setValue("status", statusString());
- message.setValue("status", statusString());
-
- sendMessage(message);
+ sendMessage(message);
}
#if LL_LINUX
@@ -228,12 +228,12 @@ void SymbolGrabber::ungrabSymbols()
extern "C"
{
- LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data);
+ LLSYMEXPORT int LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data);
}
/**
* Plugin initialization and entry point. Establishes communication channel for messages between plugin and plugin loader shell. TODO:DOC - Please check!
- *
+ *
* @param[in] host_send_func Function for sending messages from plugin to plugin loader shell
* @param[in] host_user_data Message data for messages from plugin to plugin loader shell
* @param[out] plugin_send_func Function for plugin to receive messages from plugin loader shell
@@ -245,12 +245,12 @@ extern "C"
LLSYMEXPORT int
LLPluginInitEntryPoint(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data)
{
- return init_media_plugin(host_send_func, host_user_data, plugin_send_func, plugin_user_data);
+ return init_media_plugin(host_send_func, host_user_data, plugin_send_func, plugin_user_data);
}
#ifdef WIN32
int WINAPI DllEntryPoint( HINSTANCE hInstance, unsigned long reason, void* params )
{
- return 1;
+ return 1;
}
#endif
diff --git a/indra/media_plugins/base/media_plugin_base.h b/indra/media_plugins/base/media_plugin_base.h
index 2e975a5bf2..d5cb5ac550 100644
--- a/indra/media_plugins/base/media_plugin_base.h
+++ b/indra/media_plugins/base/media_plugin_base.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file media_plugin_base.h
* @brief Media plugin base class for LLMedia API plugin system
*
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2008&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$
* @endcond
@@ -64,93 +64,93 @@ extern SymbolGrabber gSymbolGrabber;
class MediaPluginBase
{
public:
- MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ MediaPluginBase(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
/** Media plugin destructor. */
- virtual ~MediaPluginBase() {}
+ virtual ~MediaPluginBase() {}
/** Handle received message from plugin loader shell. */
- virtual void receiveMessage(const char *message_string) = 0;
-
- static void staticReceiveMessage(const char *message_string, void **user_data);
+ virtual void receiveMessage(const char *message_string) = 0;
+
+ static void staticReceiveMessage(const char *message_string, void **user_data);
protected:
/** Plugin status. */
- typedef enum
- {
- STATUS_NONE,
- STATUS_LOADING,
- STATUS_LOADED,
- STATUS_ERROR,
- STATUS_PLAYING,
- STATUS_PAUSED,
- STATUS_DONE
- } EStatus;
+ typedef enum
+ {
+ STATUS_NONE,
+ STATUS_LOADING,
+ STATUS_LOADED,
+ STATUS_ERROR,
+ STATUS_PLAYING,
+ STATUS_PAUSED,
+ STATUS_DONE
+ } EStatus;
/** Plugin shared memory. */
- class SharedSegmentInfo
- {
- public:
+ class SharedSegmentInfo
+ {
+ public:
/** Shared memory address. */
- void *mAddress;
+ void *mAddress;
/** Shared memory size. */
- size_t mSize;
- };
+ size_t mSize;
+ };
+
+ void sendMessage(const LLPluginMessage &message);
+ void sendStatus();
+ std::string statusString();
+ void setStatus(EStatus status);
- void sendMessage(const LLPluginMessage &message);
- void sendStatus();
- std::string statusString();
- void setStatus(EStatus status);
-
- /// Note: The quicktime plugin overrides this to add current time and duration to the message.
- virtual void setDirty(int left, int top, int right, int bottom);
+ /// Note: The quicktime plugin overrides this to add current time and duration to the message.
+ virtual void setDirty(int left, int top, int right, int bottom);
/** Map of shared memory names to shared memory. */
- typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap;
+ typedef std::map<std::string, SharedSegmentInfo> SharedSegmentMap;
+
-
/** Function to send message from plugin to plugin loader shell. */
- LLPluginInstance::sendMessageFunction mHostSendFunction;
+ LLPluginInstance::sendMessageFunction mHostSendFunction;
/** Message data being sent to plugin loader shell by mHostSendFunction. */
- void *mHostUserData;
+ void *mHostUserData;
/** Flag to delete plugin instance (self). */
- bool mDeleteMe;
+ bool mDeleteMe;
/** Pixel array to display. TODO:DOC are pixels always 24-bit RGB format, aligned on 32-bit boundary? Also: calling this a pixel array may be misleading since 1 pixel > 1 char. */
- unsigned char* mPixels;
+ unsigned char* mPixels;
/** TODO:DOC what's this for -- does a texture have its own piece of shared memory? updated on size_change_request, cleared on shm_remove */
- std::string mTextureSegmentName;
+ std::string mTextureSegmentName;
/** Width of plugin display in pixels. */
- int mWidth;
+ int mWidth;
/** Height of plugin display in pixels. */
- int mHeight;
+ int mHeight;
/** Width of plugin texture. */
- int mTextureWidth;
+ int mTextureWidth;
/** Height of plugin texture. */
- int mTextureHeight;
+ int mTextureHeight;
/** Pixel depth (pixel size in bytes). */
- int mDepth;
+ int mDepth;
/** Current status of plugin. */
- EStatus mStatus;
+ EStatus mStatus;
/** Map of shared memory segments. */
- SharedSegmentMap mSharedSegments;
+ SharedSegmentMap mSharedSegments;
};
/** The plugin <b>must</b> define this function to create its instance.
- * It should look something like this:
+ * It should look something like this:
* @code
- * {
- * MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data);
- * *plugin_send_func = MediaPluginFoo::staticReceiveMessage;
- * *plugin_user_data = (void*)self;
- *
- * return 0;
- * }
+ * {
+ * MediaPluginFoo *self = new MediaPluginFoo(host_send_func, host_user_data);
+ * *plugin_send_func = MediaPluginFoo::staticReceiveMessage;
+ * *plugin_user_data = (void*)self;
+ *
+ * return 0;
+ * }
* @endcode
*/
int init_media_plugin(
- LLPluginInstance::sendMessageFunction host_send_func,
- void *host_user_data,
- LLPluginInstance::sendMessageFunction *plugin_send_func,
- void **plugin_user_data);
+ LLPluginInstance::sendMessageFunction host_send_func,
+ void *host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data);
diff --git a/indra/media_plugins/cef/linux_volume_catcher.cpp b/indra/media_plugins/cef/linux_volume_catcher.cpp
index 9e6fe461a6..982b79f5b3 100755
--- a/indra/media_plugins/cef/linux_volume_catcher.cpp
+++ b/indra/media_plugins/cef/linux_volume_catcher.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file linux_volume_catcher.cpp
* @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources
*
@@ -6,21 +6,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$
* @endcond
@@ -64,361 +64,361 @@ SymbolGrabber gSymbolGrabber;
// PulseAudio requires a chain of callbacks with C linkage
extern "C" {
- void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
- void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
- void callback_context_state(pa_context *context, void *userdata);
+ void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *i, int eol, void *userdata);
+ void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata);
+ void callback_context_state(pa_context *context, void *userdata);
}
class VolumeCatcherImpl
{
public:
- VolumeCatcherImpl();
- ~VolumeCatcherImpl();
+ VolumeCatcherImpl();
+ ~VolumeCatcherImpl();
- void setVolume(F32 volume);
- void pump(void);
+ void setVolume(F32 volume);
+ void pump(void);
- // for internal use - can't be private because used from our C callbacks
+ // for internal use - can't be private because used from our C callbacks
- bool loadsyms(std::string pulse_dso_name);
- void init();
- void cleanup();
+ bool loadsyms(std::string pulse_dso_name);
+ void init();
+ void cleanup();
- void update_all_volumes(F32 volume);
- void update_index_volume(U32 index, F32 volume);
- void connected_okay();
+ void update_all_volumes(F32 volume);
+ void update_index_volume(U32 index, F32 volume);
+ void connected_okay();
- std::set<U32> mSinkInputIndices;
- std::map<U32,U32> mSinkInputNumChannels;
- F32 mDesiredVolume;
- pa_glib_mainloop *mMainloop;
- pa_context *mPAContext;
- bool mConnected;
- bool mGotSyms;
+ std::set<U32> mSinkInputIndices;
+ std::map<U32,U32> mSinkInputNumChannels;
+ F32 mDesiredVolume;
+ pa_glib_mainloop *mMainloop;
+ pa_context *mPAContext;
+ bool mConnected;
+ bool mGotSyms;
};
VolumeCatcherImpl::VolumeCatcherImpl()
- : mDesiredVolume(0.0f),
- mMainloop(nullptr),
- mPAContext(nullptr),
- mConnected(false),
- mGotSyms(false)
+ : mDesiredVolume(0.0f),
+ mMainloop(nullptr),
+ mPAContext(nullptr),
+ mConnected(false),
+ mGotSyms(false)
{
- init();
+ init();
}
VolumeCatcherImpl::~VolumeCatcherImpl()
{
- cleanup();
+ cleanup();
}
bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name)
{
- //return grab_pa_syms({pulse_dso_name});
+ //return grab_pa_syms({pulse_dso_name});
return gSymbolGrabber.grabSymbols( { pulse_dso_name }) ;
}
void VolumeCatcherImpl::init()
{
- // try to be as defensive as possible because PA's interface is a
- // bit fragile and (for our purposes) we'd rather simply not function
- // than crash
-
- // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
- // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
- // probably be loaded separately. Our Linux DSO framework needs refactoring,
- // we do this sort of thing a lot with practically identical logic...
- mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
- if (!mGotSyms) return;
-
- mMainloop = llpa_glib_mainloop_new(g_main_context_default());
-
- if (mMainloop)
- {
- pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
-
- if (api)
- {
- pa_proplist *proplist = llpa_proplist_new();
-
- if (proplist)
- {
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
- llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
-
- // plain old pa_context_new() is broken!
- mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);
-
- llpa_proplist_free(proplist);
- }
- }
- }
-
- // Now we've set up a PA context and mainloop, try connecting the
- // PA context to a PA daemon.
- if (mPAContext)
- {
- llpa_context_set_state_callback(mPAContext, callback_context_state, this);
- pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
- if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
- {
- // Okay! We haven't definitely connected, but we
- // haven't definitely failed yet.
- }
- else
- {
- // Failed to connect to PA manager... we'll leave
- // things like that. Perhaps we should try again later.
- }
- }
+ // try to be as defensive as possible because PA's interface is a
+ // bit fragile and (for our purposes) we'd rather simply not function
+ // than crash
+
+ // we cheat and rely upon libpulse-mainloop-glib.so.0 to pull-in
+ // libpulse.so.0 - this isn't a great assumption, and the two DSOs should
+ // probably be loaded separately. Our Linux DSO framework needs refactoring,
+ // we do this sort of thing a lot with practically identical logic...
+ mGotSyms = loadsyms("libpulse-mainloop-glib.so.0");
+ if (!mGotSyms) return;
+
+ mMainloop = llpa_glib_mainloop_new(g_main_context_default());
+
+ if (mMainloop)
+ {
+ pa_mainloop_api *api = llpa_glib_mainloop_get_api(mMainloop);
+
+ if (api)
+ {
+ pa_proplist *proplist = llpa_proplist_new();
+
+ if (proplist)
+ {
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ICON_NAME, "multimedia-player");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_ID, "com.secondlife.viewer.mediaplugvoladjust");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_NAME, "SL Plugin Volume Adjuster");
+ llpa_proplist_sets(proplist, PA_PROP_APPLICATION_VERSION, "1");
+
+ // plain old pa_context_new() is broken!
+ mPAContext = llpa_context_new_with_proplist(api, nullptr, proplist);
+
+ llpa_proplist_free(proplist);
+ }
+ }
+ }
+
+ // Now we've set up a PA context and mainloop, try connecting the
+ // PA context to a PA daemon.
+ if (mPAContext)
+ {
+ llpa_context_set_state_callback(mPAContext, callback_context_state, this);
+ pa_context_flags_t cflags = (pa_context_flags)0; // maybe add PA_CONTEXT_NOAUTOSPAWN?
+ if (llpa_context_connect(mPAContext, nullptr, cflags, nullptr) >= 0)
+ {
+ // Okay! We haven't definitely connected, but we
+ // haven't definitely failed yet.
+ }
+ else
+ {
+ // Failed to connect to PA manager... we'll leave
+ // things like that. Perhaps we should try again later.
+ }
+ }
}
void VolumeCatcherImpl::cleanup()
{
- mConnected = false;
+ mConnected = false;
- if (mGotSyms && mPAContext)
- {
- llpa_context_disconnect(mPAContext);
- llpa_context_unref(mPAContext);
- }
+ if (mGotSyms && mPAContext)
+ {
+ llpa_context_disconnect(mPAContext);
+ llpa_context_unref(mPAContext);
+ }
- mPAContext = nullptr;
+ mPAContext = nullptr;
- if (mGotSyms && mMainloop)
- llpa_glib_mainloop_free(mMainloop);
+ if (mGotSyms && mMainloop)
+ llpa_glib_mainloop_free(mMainloop);
- mMainloop = nullptr;
+ mMainloop = nullptr;
}
void VolumeCatcherImpl::setVolume(F32 volume)
{
- mDesiredVolume = volume;
-
- if (!mGotSyms) return;
+ mDesiredVolume = volume;
+
+ if (!mGotSyms) return;
- if (mConnected && mPAContext)
- {
- update_all_volumes(mDesiredVolume);
- }
+ if (mConnected && mPAContext)
+ {
+ update_all_volumes(mDesiredVolume);
+ }
- pump();
+ pump();
}
void VolumeCatcherImpl::pump()
{
- gboolean may_block = FALSE;
- g_main_context_iteration(g_main_context_default(), may_block);
+ gboolean may_block = FALSE;
+ g_main_context_iteration(g_main_context_default(), may_block);
}
void VolumeCatcherImpl::connected_okay()
{
- pa_operation *op;
-
- // fetch global list of existing sinkinputs
- if ((op = llpa_context_get_sink_input_info_list(mPAContext,
- callback_discovered_sinkinput,
- this)))
- {
- llpa_operation_unref(op);
- }
-
- // subscribe to future global sinkinput changes
- llpa_context_set_subscribe_callback(mPAContext,
- callback_subscription_alert,
- this);
- if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
- (PA_SUBSCRIPTION_MASK_SINK_INPUT),
+ pa_operation *op;
+
+ // fetch global list of existing sinkinputs
+ if ((op = llpa_context_get_sink_input_info_list(mPAContext,
+ callback_discovered_sinkinput,
+ this)))
+ {
+ llpa_operation_unref(op);
+ }
+
+ // subscribe to future global sinkinput changes
+ llpa_context_set_subscribe_callback(mPAContext,
+ callback_subscription_alert,
+ this);
+ if ((op = llpa_context_subscribe(mPAContext, (pa_subscription_mask_t)
+ (PA_SUBSCRIPTION_MASK_SINK_INPUT),
nullptr, nullptr)))
- {
- llpa_operation_unref(op);
- }
+ {
+ llpa_operation_unref(op);
+ }
}
void VolumeCatcherImpl::update_all_volumes(F32 volume)
{
- for (std::set<U32>::iterator it = mSinkInputIndices.begin();
- it != mSinkInputIndices.end(); ++it)
- {
- update_index_volume(*it, volume);
- }
+ for (std::set<U32>::iterator it = mSinkInputIndices.begin();
+ it != mSinkInputIndices.end(); ++it)
+ {
+ update_index_volume(*it, volume);
+ }
}
void VolumeCatcherImpl::update_index_volume(U32 index, F32 volume)
{
- static pa_cvolume cvol;
- llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
- llpa_sw_volume_from_linear(volume));
-
- pa_context *c = mPAContext;
- uint32_t idx = index;
- const pa_cvolume *cvolumep = &cvol;
- pa_context_success_cb_t cb = nullptr; // okay as null
- void *userdata = nullptr; // okay as null
-
- pa_operation *op;
- if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
- llpa_operation_unref(op);
+ static pa_cvolume cvol;
+ llpa_cvolume_set(&cvol, mSinkInputNumChannels[index],
+ llpa_sw_volume_from_linear(volume));
+
+ pa_context *c = mPAContext;
+ uint32_t idx = index;
+ const pa_cvolume *cvolumep = &cvol;
+ pa_context_success_cb_t cb = nullptr; // okay as null
+ void *userdata = nullptr; // okay as null
+
+ pa_operation *op;
+ if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata)))
+ llpa_operation_unref(op);
}
pid_t getParentPid( pid_t aPid )
{
- std::stringstream strm;
- strm << "/proc/" << aPid << "/status";
- std::ifstream in{ strm.str() };
-
- if( !in.is_open() )
- return 0;
-
- pid_t res {0};
- while( !in.eof() && res == 0 )
- {
- std::string line;
- line.resize( 1024, 0 );
- in.getline( &line[0], line.length() );
-
- auto i = line.find( "PPid:" );
-
- if( i == std::string::npos )
- continue;
-
- char const *pIn = line.c_str() + 5; // Skip over pid;
- while( *pIn != 0 && isspace( *pIn ) )
- ++pIn;
-
- if( *pIn )
- res = atoll( pIn );
- }
- return res;
+ std::stringstream strm;
+ strm << "/proc/" << aPid << "/status";
+ std::ifstream in{ strm.str() };
+
+ if( !in.is_open() )
+ return 0;
+
+ pid_t res {0};
+ while( !in.eof() && res == 0 )
+ {
+ std::string line;
+ line.resize( 1024, 0 );
+ in.getline( &line[0], line.length() );
+
+ auto i = line.find( "PPid:" );
+
+ if( i == std::string::npos )
+ continue;
+
+ char const *pIn = line.c_str() + 5; // Skip over pid;
+ while( *pIn != 0 && isspace( *pIn ) )
+ ++pIn;
+
+ if( *pIn )
+ res = atoll( pIn );
+ }
+ return res;
}
bool isPluginPid( pid_t aPid )
{
- auto myPid = getpid();
+ auto myPid = getpid();
- do
- {
- if( aPid == myPid )
- return true;
- aPid = getParentPid( aPid );
- } while( aPid > 1 );
+ do
+ {
+ if( aPid == myPid )
+ return true;
+ aPid = getParentPid( aPid );
+ } while( aPid > 1 );
- return false;
+ return false;
}
void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata)
{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- if (0 == eol)
- {
- pa_proplist *proplist = sii->proplist;
- pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
-
- if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
- {
- bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
-
- impl->mSinkInputIndices.insert(sii->index);
- impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
-
- if (is_new)
- {
- // new!
- impl->update_index_volume(sii->index, impl->mDesiredVolume);
- }
- else
- {
- // seen it already, do nothing.
- }
- }
- }
+ VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
+ llassert(impl);
+
+ if (0 == eol)
+ {
+ pa_proplist *proplist = sii->proplist;
+ pid_t sinkpid = atoll(llpa_proplist_gets(proplist, PA_PROP_APPLICATION_PROCESS_ID));
+
+ if (isPluginPid( sinkpid )) // does the discovered sinkinput belong to this process?
+ {
+ bool is_new = (impl->mSinkInputIndices.find(sii->index) == impl->mSinkInputIndices.end());
+
+ impl->mSinkInputIndices.insert(sii->index);
+ impl->mSinkInputNumChannels[sii->index] = sii->channel_map.channels;
+
+ if (is_new)
+ {
+ // new!
+ impl->update_index_volume(sii->index, impl->mDesiredVolume);
+ }
+ else
+ {
+ // seen it already, do nothing.
+ }
+ }
+ }
}
void callback_subscription_alert(pa_context *context, pa_subscription_event_type_t t, uint32_t index, void *userdata)
{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
+ VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
+ llassert(impl);
- switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
- {
+ switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
+ {
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
- if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
- {
- // forget this sinkinput, if we were caring about it
- impl->mSinkInputIndices.erase(index);
- impl->mSinkInputNumChannels.erase(index);
- }
- else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
- {
- // ask for more info about this new sinkinput
- pa_operation *op;
- if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
- {
- llpa_operation_unref(op);
- }
- }
- else
- {
- // property change on this sinkinput - we don't care.
- }
- break;
-
- default:;
- }
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
+ {
+ // forget this sinkinput, if we were caring about it
+ impl->mSinkInputIndices.erase(index);
+ impl->mSinkInputNumChannels.erase(index);
+ }
+ else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
+ {
+ // ask for more info about this new sinkinput
+ pa_operation *op;
+ if ((op = llpa_context_get_sink_input_info(impl->mPAContext, index, callback_discovered_sinkinput, impl)))
+ {
+ llpa_operation_unref(op);
+ }
+ }
+ else
+ {
+ // property change on this sinkinput - we don't care.
+ }
+ break;
+
+ default:;
+ }
}
void callback_context_state(pa_context *context, void *userdata)
{
- VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
- llassert(impl);
-
- switch (llpa_context_get_state(context))
- {
- case PA_CONTEXT_READY:
- impl->mConnected = true;
- impl->connected_okay();
- break;
- case PA_CONTEXT_TERMINATED:
- impl->mConnected = false;
- break;
- case PA_CONTEXT_FAILED:
- impl->mConnected = false;
- break;
- default:;
- }
+ VolumeCatcherImpl *impl = dynamic_cast<VolumeCatcherImpl*>((VolumeCatcherImpl*)userdata);
+ llassert(impl);
+
+ switch (llpa_context_get_state(context))
+ {
+ case PA_CONTEXT_READY:
+ impl->mConnected = true;
+ impl->connected_okay();
+ break;
+ case PA_CONTEXT_TERMINATED:
+ impl->mConnected = false;
+ break;
+ case PA_CONTEXT_FAILED:
+ impl->mConnected = false;
+ break;
+ default:;
+ }
}
/////////////////////////////////////////////////////
VolumeCatcher::VolumeCatcher()
{
- pimpl = new VolumeCatcherImpl();
+ pimpl = new VolumeCatcherImpl();
}
VolumeCatcher::~VolumeCatcher()
{
- delete pimpl;
- pimpl = nullptr;
+ delete pimpl;
+ pimpl = nullptr;
}
void VolumeCatcher::setVolume(F32 volume)
{
- llassert(pimpl);
- pimpl->setVolume(volume);
+ llassert(pimpl);
+ pimpl->setVolume(volume);
}
void VolumeCatcher::setPan(F32 pan)
{
- // TODO: implement this (if possible)
+ // TODO: implement this (if possible)
}
void VolumeCatcher::pump()
{
- llassert(pimpl);
- pimpl->pump();
+ llassert(pimpl);
+ pimpl->pump();
}
diff --git a/indra/media_plugins/cef/mac_volume_catcher.cpp b/indra/media_plugins/cef/mac_volume_catcher.cpp
index dddb9c2077..32251c0999 100644
--- a/indra/media_plugins/cef/mac_volume_catcher.cpp
+++ b/indra/media_plugins/cef/mac_volume_catcher.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file mac_volume_catcher.cpp
* @brief A Mac OS X specific hack to control the volume level of all audio channels opened by a process.
*
@@ -11,26 +11,26 @@
* 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$
* @endcond
*/
/**************************************************************************************************************
- This code works by using CaptureComponent to capture the "Default Output" audio component
- (kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component.
- It does this just to keep track of all instances of the default output component, so that it can set the
- kHALOutputParam_Volume parameter on all of them to adjust the output volume.
+ This code works by using CaptureComponent to capture the "Default Output" audio component
+ (kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput) and delegating all calls to the original component.
+ It does this just to keep track of all instances of the default output component, so that it can set the
+ kHALOutputParam_Volume parameter on all of them to adjust the output volume.
**************************************************************************************************************/
#include "volume_catcher.h"
@@ -49,35 +49,35 @@ class VolumeCatcherImpl
{
public:
- void setVolume(F32 volume);
- void setPan(F32 pan);
-
- void setInstanceVolume(VolumeCatcherStorage *instance);
-
- std::list<VolumeCatcherStorage*> mComponentInstances;
- Component mOriginalDefaultOutput;
- Component mVolumeAdjuster;
-
- static VolumeCatcherImpl *getInstance();
+ void setVolume(F32 volume);
+ void setPan(F32 pan);
+
+ void setInstanceVolume(VolumeCatcherStorage *instance);
+
+ std::list<VolumeCatcherStorage*> mComponentInstances;
+ Component mOriginalDefaultOutput;
+ Component mVolumeAdjuster;
+
+ static VolumeCatcherImpl *getInstance();
private:
- // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
- VolumeCatcherImpl();
- static VolumeCatcherImpl *sInstance;
-
- // The singlar instance of this class is expected to last until the process exits.
- // To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link.
- ~VolumeCatcherImpl();
-
- F32 mVolume;
- F32 mPan;
+ // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+ VolumeCatcherImpl();
+ static VolumeCatcherImpl *sInstance;
+
+ // The singlar instance of this class is expected to last until the process exits.
+ // To ensure this, we declare the destructor here but never define it, so any code which attempts to destroy the instance will not link.
+ ~VolumeCatcherImpl();
+
+ F32 mVolume;
+ F32 mPan;
};
VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;;
struct VolumeCatcherStorage
{
- ComponentInstance self;
- ComponentInstance delegate;
+ ComponentInstance self;
+ ComponentInstance delegate;
};
static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage);
@@ -86,188 +86,188 @@ static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *stor
VolumeCatcherImpl *VolumeCatcherImpl::getInstance()
{
- if(!sInstance)
- {
- sInstance = new VolumeCatcherImpl;
- }
-
- return sInstance;
+ if(!sInstance)
+ {
+ sInstance = new VolumeCatcherImpl;
+ }
+
+ return sInstance;
}
VolumeCatcherImpl::VolumeCatcherImpl()
{
- mVolume = 1.0; // default to full volume
- mPan = 0.0; // and center pan
-
- ComponentDescription desc;
- desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = kAudioUnitSubType_DefaultOutput;
- desc.componentManufacturer = kAudioUnitManufacturer_Apple;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
-
- // Find the original default output component
- mOriginalDefaultOutput = FindNextComponent(NULL, &desc);
-
- // Register our own output component with the same parameters
- mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL);
-
- // Capture the original component, so we always get found instead.
- CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster);
+ mVolume = 1.0; // default to full volume
+ mPan = 0.0; // and center pan
+
+ ComponentDescription desc;
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_DefaultOutput;
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+
+ // Find the original default output component
+ mOriginalDefaultOutput = FindNextComponent(NULL, &desc);
+
+ // Register our own output component with the same parameters
+ mVolumeAdjuster = RegisterComponent(&desc, NewComponentRoutineUPP(volume_catcher_component_entry), 0, NULL, NULL, NULL);
+
+ // Capture the original component, so we always get found instead.
+ CaptureComponent(mOriginalDefaultOutput, mVolumeAdjuster);
}
static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage)
{
- ComponentResult result = badComponentSelector;
- VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage;
-
- switch(cp->what)
- {
- case kComponentOpenSelect:
-// std::cerr << "kComponentOpenSelect" << std::endl;
- result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo);
- break;
-
- case kComponentCloseSelect:
-// std::cerr << "kComponentCloseSelect" << std::endl;
- result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo);
- // CallComponentFunctionWithStorageProcInfo
- break;
-
- default:
-// std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl;
- result = DelegateComponentCall(cp, storage->delegate);
- break;
- }
-
- return result;
+ ComponentResult result = badComponentSelector;
+ VolumeCatcherStorage *storage = (VolumeCatcherStorage*)componentStorage;
+
+ switch(cp->what)
+ {
+ case kComponentOpenSelect:
+// std::cerr << "kComponentOpenSelect" << std::endl;
+ result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_open, uppCallComponentOpenProcInfo);
+ break;
+
+ case kComponentCloseSelect:
+// std::cerr << "kComponentCloseSelect" << std::endl;
+ result = CallComponentFunctionWithStorageProcInfo((Handle)storage, cp, (ProcPtr)volume_catcher_component_close, uppCallComponentCloseProcInfo);
+ // CallComponentFunctionWithStorageProcInfo
+ break;
+
+ default:
+// std::cerr << "Delegating selector: " << cp->what << " to component instance " << storage->delegate << std::endl;
+ result = DelegateComponentCall(cp, storage->delegate);
+ break;
+ }
+
+ return result;
}
static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self)
{
- ComponentResult result = noErr;
- VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
-
- storage = new VolumeCatcherStorage;
-
- storage->self = self;
- storage->delegate = NULL;
-
- result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate));
-
- if(result != noErr)
- {
-// std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl;
-
- // If we failed to open the delagate component, our open is going to fail. Clean things up.
- delete storage;
- }
- else
- {
- // Success -- set up this component's storage
- SetComponentInstanceStorage(self, (Handle)storage);
-
- // add this instance to the global list
- impl->mComponentInstances.push_back(storage);
-
- // and set up the initial volume
- impl->setInstanceVolume(storage);
- }
-
- return result;
+ ComponentResult result = noErr;
+ VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
+
+ storage = new VolumeCatcherStorage;
+
+ storage->self = self;
+ storage->delegate = NULL;
+
+ result = OpenAComponent(impl->mOriginalDefaultOutput, &(storage->delegate));
+
+ if(result != noErr)
+ {
+// std::cerr << "OpenAComponent result = " << result << ", component ref = " << storage->delegate << std::endl;
+
+ // If we failed to open the delagate component, our open is going to fail. Clean things up.
+ delete storage;
+ }
+ else
+ {
+ // Success -- set up this component's storage
+ SetComponentInstanceStorage(self, (Handle)storage);
+
+ // add this instance to the global list
+ impl->mComponentInstances.push_back(storage);
+
+ // and set up the initial volume
+ impl->setInstanceVolume(storage);
+ }
+
+ return result;
}
static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self)
{
- ComponentResult result = noErr;
-
- if(storage)
- {
- if(storage->delegate)
- {
- CloseComponent(storage->delegate);
- storage->delegate = NULL;
- }
-
- VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
- impl->mComponentInstances.remove(storage);
- delete[] storage;
- }
-
- return result;
+ ComponentResult result = noErr;
+
+ if(storage)
+ {
+ if(storage->delegate)
+ {
+ CloseComponent(storage->delegate);
+ storage->delegate = NULL;
+ }
+
+ VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
+ impl->mComponentInstances.remove(storage);
+ delete[] storage;
+ }
+
+ return result;
}
void VolumeCatcherImpl::setVolume(F32 volume)
{
- VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
- impl->mVolume = volume;
-
- // Iterate through all known instances, setting the volume on each.
- for(std::list<VolumeCatcherStorage*>::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter)
- {
- impl->setInstanceVolume(*iter);
- }
+ VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
+ impl->mVolume = volume;
+
+ // Iterate through all known instances, setting the volume on each.
+ for(std::list<VolumeCatcherStorage*>::iterator iter = mComponentInstances.begin(); iter != mComponentInstances.end(); ++iter)
+ {
+ impl->setInstanceVolume(*iter);
+ }
}
void VolumeCatcherImpl::setPan(F32 pan)
{
- VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
- impl->mPan = pan;
-
- // TODO: implement this.
- // This will probably require adding a "panner" audio unit to the chain somehow.
- // There's also a "3d mixer" component that we might be able to use...
+ VolumeCatcherImpl *impl = VolumeCatcherImpl::getInstance();
+ impl->mPan = pan;
+
+ // TODO: implement this.
+ // This will probably require adding a "panner" audio unit to the chain somehow.
+ // There's also a "3d mixer" component that we might be able to use...
}
void VolumeCatcherImpl::setInstanceVolume(VolumeCatcherStorage *instance)
{
-// std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl;
-
- OSStatus err = noErr;
-
- if(instance && instance->delegate)
- {
- err = AudioUnitSetParameter(
- instance->delegate,
- kHALOutputParam_Volume,
- kAudioUnitScope_Global,
- 0,
- mVolume,
- 0);
- }
-
- if(err)
- {
-// std::cerr << " AudioUnitSetParameter returned " << err << std::endl;
- }
+// std::cerr << "Setting volume on component instance: " << (instance->delegate) << " to " << mVolume << std::endl;
+
+ OSStatus err = noErr;
+
+ if(instance && instance->delegate)
+ {
+ err = AudioUnitSetParameter(
+ instance->delegate,
+ kHALOutputParam_Volume,
+ kAudioUnitScope_Global,
+ 0,
+ mVolume,
+ 0);
+ }
+
+ if(err)
+ {
+// std::cerr << " AudioUnitSetParameter returned " << err << std::endl;
+ }
}
/////////////////////////////////////////////////////
VolumeCatcher::VolumeCatcher()
{
- pimpl = VolumeCatcherImpl::getInstance();
+ pimpl = VolumeCatcherImpl::getInstance();
}
VolumeCatcher::~VolumeCatcher()
{
- // Let the instance persist until exit.
+ // Let the instance persist until exit.
}
void VolumeCatcher::setVolume(F32 volume)
{
- pimpl->setVolume(volume);
+ pimpl->setVolume(volume);
}
void VolumeCatcher::setPan(F32 pan)
{
- pimpl->setPan(pan);
+ pimpl->setPan(pan);
}
void VolumeCatcher::pump()
{
- // No periodic tasks are necessary for this implementation.
+ // No periodic tasks are necessary for this implementation.
}
#if LL_DARWIN
diff --git a/indra/media_plugins/cef/mac_volume_catcher_null.cpp b/indra/media_plugins/cef/mac_volume_catcher_null.cpp
index f4fcef71aa..c479e24a95 100644
--- a/indra/media_plugins/cef/mac_volume_catcher_null.cpp
+++ b/indra/media_plugins/cef/mac_volume_catcher_null.cpp
@@ -1,28 +1,28 @@
-/**
+/**
* @file windows_volume_catcher.cpp
* @brief A null implementation of volume level control of all audio channels opened by a process.
- * We are using this for the macOS version for now until we can understand how to make the
+ * We are using this for the macOS version for now until we can understand how to make the
* exitising mac_volume_catcher.cpp work without the (now, non-existant) QuickTime dependency
*
* @cond
* $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$
* @endcond
@@ -32,24 +32,24 @@
#include "llsingleton.h"
class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
{
- LLSINGLETON(VolumeCatcherImpl);
- // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
- ~VolumeCatcherImpl();
+ LLSINGLETON(VolumeCatcherImpl);
+ // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+ ~VolumeCatcherImpl();
public:
- void setVolume(F32 volume);
- void setPan(F32 pan);
-
+ void setVolume(F32 volume);
+ void setPan(F32 pan);
+
private:
- F32 mVolume;
- F32 mPan;
- bool mSystemIsVistaOrHigher;
+ F32 mVolume;
+ F32 mPan;
+ bool mSystemIsVistaOrHigher;
};
VolumeCatcherImpl::VolumeCatcherImpl()
-: mVolume(1.0f), // default volume is max
- mPan(0.f) // default pan is centered
+: mVolume(1.0f), // default volume is max
+ mPan(0.f) // default pan is centered
{
}
@@ -59,37 +59,37 @@ VolumeCatcherImpl::~VolumeCatcherImpl()
void VolumeCatcherImpl::setVolume(F32 volume)
{
- mVolume = volume;
+ mVolume = volume;
}
void VolumeCatcherImpl::setPan(F32 pan)
-{ // remember pan for calculating individual channel levels later
- mPan = pan;
+{ // remember pan for calculating individual channel levels later
+ mPan = pan;
}
/////////////////////////////////////////////////////
VolumeCatcher::VolumeCatcher()
{
- pimpl = VolumeCatcherImpl::getInstance();
+ pimpl = VolumeCatcherImpl::getInstance();
}
VolumeCatcher::~VolumeCatcher()
{
- // Let the instance persist until exit.
+ // Let the instance persist until exit.
}
void VolumeCatcher::setVolume(F32 volume)
{
- pimpl->setVolume(volume);
+ pimpl->setVolume(volume);
}
void VolumeCatcher::setPan(F32 pan)
{
- pimpl->setPan(pan);
+ pimpl->setPan(pan);
}
void VolumeCatcher::pump()
{
- // No periodic tasks are necessary for this implementation.
+ // No periodic tasks are necessary for this implementation.
}
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 60d91753d0..c1bba0fdd1 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -43,74 +43,74 @@
////////////////////////////////////////////////////////////////////////////////
//
class MediaPluginCEF :
- public MediaPluginBase
+ public MediaPluginBase
{
public:
- MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginCEF();
+ MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginCEF();
- /*virtual*/
- void receiveMessage(const char* message_string);
+ /*virtual*/
+ void receiveMessage(const char* message_string);
private:
- bool init();
-
- void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
- void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
- void onConsoleMessageCallback(std::string message, std::string source, int line);
- void onStatusMessageCallback(std::string value);
- void onTitleChangeCallback(std::string title);
- void onTooltipCallback(std::string text);
- void onLoadStartCallback();
- void onRequestExitCallback();
- void onLoadEndCallback(int httpStatusCode, std::string url);
- void onLoadError(int status, const std::string error_text);
- void onAddressChangeCallback(std::string url);
- void onOpenPopupCallback(std::string url, std::string target);
- bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
- void onCursorChangedCallback(dullahan::ECursorType type);
- const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);
- bool onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text);
- bool onJSBeforeUnloadCallback();
-
- void postDebugMessage(const std::string& msg);
- void authResponse(LLPluginMessage &message);
-
- void keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_data);
- void unicodeInput(std::string event, LLSD native_key_data);
-
- void checkEditState();
+ bool init();
+
+ void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
+ void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect);
+ void onConsoleMessageCallback(std::string message, std::string source, int line);
+ void onStatusMessageCallback(std::string value);
+ void onTitleChangeCallback(std::string title);
+ void onTooltipCallback(std::string text);
+ void onLoadStartCallback();
+ void onRequestExitCallback();
+ void onLoadEndCallback(int httpStatusCode, std::string url);
+ void onLoadError(int status, const std::string error_text);
+ void onAddressChangeCallback(std::string url);
+ void onOpenPopupCallback(std::string url, std::string target);
+ bool onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password);
+ void onCursorChangedCallback(dullahan::ECursorType type);
+ const std::vector<std::string> onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, const std::string dialog_accept_filter, bool& use_default);
+ bool onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text);
+ bool onJSBeforeUnloadCallback();
+
+ void postDebugMessage(const std::string& msg);
+ void authResponse(LLPluginMessage &message);
+
+ void keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_data);
+ void unicodeInput(std::string event, LLSD native_key_data);
+
+ void checkEditState();
void setVolume();
- bool mEnableMediaPluginDebugging;
- std::string mHostLanguage;
- bool mCookiesEnabled;
- bool mPluginsEnabled;
- bool mJavascriptEnabled;
+ bool mEnableMediaPluginDebugging;
+ std::string mHostLanguage;
+ bool mCookiesEnabled;
+ bool mPluginsEnabled;
+ bool mJavascriptEnabled;
bool mProxyEnabled;
std::string mProxyHost;
int mProxyPort;
- bool mDisableGPU;
- bool mDisableNetworkService;
- bool mUseMockKeyChain;
- bool mDisableWebSecurity;
- bool mFileAccessFromFileUrls;
- std::string mUserAgentSubtring;
- std::string mAuthUsername;
- std::string mAuthPassword;
- bool mAuthOK;
- bool mCanCut;
- bool mCanCopy;
- bool mCanPaste;
+ bool mDisableGPU;
+ bool mDisableNetworkService;
+ bool mUseMockKeyChain;
+ bool mDisableWebSecurity;
+ bool mFileAccessFromFileUrls;
+ std::string mUserAgentSubtring;
+ std::string mAuthUsername;
+ std::string mAuthPassword;
+ bool mAuthOK;
+ bool mCanCut;
+ bool mCanCopy;
+ bool mCanPaste;
std::string mRootCachePath;
- std::string mCachePath;
- std::string mContextCachePath;
- std::string mCefLogFile;
- bool mCefLogVerbose;
- std::vector<std::string> mPickedFiles;
- VolumeCatcher mVolumeCatcher;
- F32 mCurVolume;
- dullahan* mCEFLib;
+ std::string mCachePath;
+ std::string mContextCachePath;
+ std::string mCefLogFile;
+ bool mCefLogVerbose;
+ std::vector<std::string> mPickedFiles;
+ VolumeCatcher mVolumeCatcher;
+ F32 mCurVolume;
+ dullahan* mCEFLib;
};
////////////////////////////////////////////////////////////////////////////////
@@ -118,109 +118,109 @@ private:
MediaPluginCEF::MediaPluginCEF(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
MediaPluginBase(host_send_func, host_user_data)
{
- mWidth = 0;
- mHeight = 0;
- mDepth = 4;
- mPixels = 0;
- mEnableMediaPluginDebugging = true;
- mHostLanguage = "en";
- mCookiesEnabled = true;
- mPluginsEnabled = false;
- mJavascriptEnabled = true;
+ mWidth = 0;
+ mHeight = 0;
+ mDepth = 4;
+ mPixels = 0;
+ mEnableMediaPluginDebugging = true;
+ mHostLanguage = "en";
+ mCookiesEnabled = true;
+ mPluginsEnabled = false;
+ mJavascriptEnabled = true;
mProxyEnabled = false;
mProxyHost = "";
mProxyPort = 0;
- mDisableGPU = false;
- mDisableNetworkService = true;
- mUseMockKeyChain = true;
- mDisableWebSecurity = false;
- mFileAccessFromFileUrls = false;
- mUserAgentSubtring = "";
- mAuthUsername = "";
- mAuthPassword = "";
- mAuthOK = false;
- mCanCut = false;
- mCanCopy = false;
- mCanPaste = false;
- mCachePath = "";
- mCefLogFile = "";
- mCefLogVerbose = false;
- mPickedFiles.clear();
- mCurVolume = 0.0;
-
- mCEFLib = new dullahan();
-
- setVolume();
+ mDisableGPU = false;
+ mDisableNetworkService = true;
+ mUseMockKeyChain = true;
+ mDisableWebSecurity = false;
+ mFileAccessFromFileUrls = false;
+ mUserAgentSubtring = "";
+ mAuthUsername = "";
+ mAuthPassword = "";
+ mAuthOK = false;
+ mCanCut = false;
+ mCanCopy = false;
+ mCanPaste = false;
+ mCachePath = "";
+ mCefLogFile = "";
+ mCefLogVerbose = false;
+ mPickedFiles.clear();
+ mCurVolume = 0.0;
+
+ mCEFLib = new dullahan();
+
+ setVolume();
}
////////////////////////////////////////////////////////////////////////////////
//
MediaPluginCEF::~MediaPluginCEF()
{
- mCEFLib->shutdown();
+ mCEFLib->shutdown();
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::postDebugMessage(const std::string& msg)
{
- if (mEnableMediaPluginDebugging)
- {
- std::stringstream str;
- str << "@Media Msg> " << msg;
-
- LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
- debug_message.setValue("message_text", str.str());
- debug_message.setValue("message_level", "info");
- sendMessage(debug_message);
- }
+ if (mEnableMediaPluginDebugging)
+ {
+ std::stringstream str;
+ str << "@Media Msg> " << msg;
+
+ LLPluginMessage debug_message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "debug_message");
+ debug_message.setValue("message_text", str.str());
+ debug_message.setValue("message_level", "info");
+ sendMessage(debug_message);
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height)
{
- if( mPixels && pixels )
- {
- if (mWidth == width && mHeight == height)
- {
- memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
- }
- else
- {
- mCEFLib->setSize(mWidth, mHeight);
- }
- setDirty(0, 0, mWidth, mHeight);
- }
+ if( mPixels && pixels )
+ {
+ if (mWidth == width && mHeight == height)
+ {
+ memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
+ }
+ else
+ {
+ mCEFLib->setSize(mWidth, mHeight);
+ }
+ setDirty(0, 0, mWidth, mHeight);
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onConsoleMessageCallback(std::string message, std::string source, int line)
{
- std::stringstream str;
- str << "Console message: " << message << " in file(" << source << ") at line " << line;
- postDebugMessage(str.str());
+ std::stringstream str;
+ str << "Console message: " << message << " in file(" << source << ") at line " << line;
+ postDebugMessage(str.str());
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onStatusMessageCallback(std::string value)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
- message.setValue("status", value);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text");
+ message.setValue("status", value);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onTitleChangeCallback(std::string title)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", title);
- message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
- message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", title);
+ message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
+ sendMessage(message);
}
void MediaPluginCEF::onTooltipCallback(std::string text)
@@ -233,183 +233,183 @@ void MediaPluginCEF::onTooltipCallback(std::string text)
//
void MediaPluginCEF::onLoadStartCallback()
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
- //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
- message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
- message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
+ sendMessage(message);
}
/////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onLoadError(int status, const std::string error_text)
{
- std::stringstream msg;
+ std::stringstream msg;
- msg << "<b>Loading error!</b>";
- msg << "<p>";
- msg << "Message: " << error_text;
- msg << "<br>";
- msg << "Code: " << status;
+ msg << "<b>Loading error!</b>";
+ msg << "<p>";
+ msg << "Message: " << error_text;
+ msg << "<br>";
+ msg << "Code: " << status;
- mCEFLib->showBrowserMessage(msg.str());
+ mCEFLib->showBrowserMessage(msg.str());
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onRequestExitCallback()
{
- LLPluginMessage message("base", "goodbye");
- sendMessage(message);
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
- // Will trigger delete on next staticReceiveMessage()
- mDeleteMe = true;
+ // Will trigger delete on next staticReceiveMessage()
+ mDeleteMe = true;
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onLoadEndCallback(int httpStatusCode, std::string url)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
- //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
- message.setValueS32("result_code", httpStatusCode);
- message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
- message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
- message.setValue("uri", url);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
+ //message.setValue("uri", event.getEventUri()); // not easily available here in CEF - needed?
+ message.setValueS32("result_code", httpStatusCode);
+ message.setValueBoolean("history_back_available", mCEFLib->canGoBack());
+ message.setValueBoolean("history_forward_available", mCEFLib->canGoForward());
+ message.setValue("uri", url);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onAddressChangeCallback(std::string url)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
- message.setValue("uri", url);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+ message.setValue("uri", url);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
- message.setValue("uri", url);
- message.setValue("target", target);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href");
+ message.setValue("uri", url);
+ message.setValue("target", target);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow");
message.setValue("uri", url);
- // indicate if this interaction was from a user click (okay on a SLAPP) or
+ // indicate if this interaction was from a user click (okay on a SLAPP) or
// via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP)
const std::string nav_type = user_gesture ? "clicked" : "navigated";
- message.setValue("nav_type", nav_type);
+ message.setValue("nav_type", nav_type);
message.setValueBoolean("is_redirect", is_redirect);
- sendMessage(message);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
bool MediaPluginCEF::onHTTPAuthCallback(const std::string host, const std::string realm, std::string& username, std::string& password)
{
- mAuthOK = false;
+ mAuthOK = false;
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
- message.setValue("url", host);
- message.setValue("realm", realm);
- message.setValueBoolean("blocking_request", true);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
+ message.setValue("url", host);
+ message.setValue("realm", realm);
+ message.setValueBoolean("blocking_request", true);
- // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
- sendMessage(message);
+ // The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+ sendMessage(message);
- if (mAuthOK)
- {
- username = mAuthUsername;
- password = mAuthPassword;
- }
+ if (mAuthOK)
+ {
+ username = mAuthUsername;
+ password = mAuthPassword;
+ }
- return mAuthOK;
+ return mAuthOK;
}
////////////////////////////////////////////////////////////////////////////////
//
const std::vector<std::string> MediaPluginCEF::onFileDialog(dullahan::EFileDialogType dialog_type, const std::string dialog_title, const std::string default_file, std::string dialog_accept_filter, bool& use_default)
{
- // do not use the default CEF file picker
- use_default = false;
+ // do not use the default CEF file picker
+ use_default = false;
- if (dialog_type == dullahan::FD_OPEN_FILE)
- {
- mPickedFiles.clear();
+ if (dialog_type == dullahan::FD_OPEN_FILE)
+ {
+ mPickedFiles.clear();
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
- message.setValueBoolean("blocking_request", true);
- message.setValueBoolean("multiple_files", false);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
+ message.setValueBoolean("blocking_request", true);
+ message.setValueBoolean("multiple_files", false);
- sendMessage(message);
+ sendMessage(message);
- return mPickedFiles;
- }
- else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
- {
- mPickedFiles.clear();
+ return mPickedFiles;
+ }
+ else if (dialog_type == dullahan::FD_OPEN_MULTIPLE_FILES)
+ {
+ mPickedFiles.clear();
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
- message.setValueBoolean("blocking_request", true);
- message.setValueBoolean("multiple_files", true);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file");
+ message.setValueBoolean("blocking_request", true);
+ message.setValueBoolean("multiple_files", true);
- sendMessage(message);
+ sendMessage(message);
- return mPickedFiles;
- }
- else if (dialog_type == dullahan::FD_SAVE_FILE)
- {
- mPickedFiles.clear();
- mAuthOK = false;
+ return mPickedFiles;
+ }
+ else if (dialog_type == dullahan::FD_SAVE_FILE)
+ {
+ mPickedFiles.clear();
+ mAuthOK = false;
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
- message.setValueBoolean("blocking_request", true);
- message.setValue("filename", default_file);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "file_download");
+ message.setValueBoolean("blocking_request", true);
+ message.setValue("filename", default_file);
- sendMessage(message);
+ sendMessage(message);
- return mPickedFiles;
- }
+ return mPickedFiles;
+ }
- return std::vector<std::string>();
+ return std::vector<std::string>();
}
////////////////////////////////////////////////////////////////////////////////
//
bool MediaPluginCEF::onJSDialogCallback(const std::string origin_url, const std::string message_text, const std::string default_prompt_text)
{
- // return true indicates we suppress the JavaScript alert UI entirely
- return true;
+ // return true indicates we suppress the JavaScript alert UI entirely
+ return true;
}
////////////////////////////////////////////////////////////////////////////////
//
bool MediaPluginCEF::onJSBeforeUnloadCallback()
{
- // return true indicates we suppress the JavaScript UI entirely
- return true;
+ // return true indicates we suppress the JavaScript UI entirely
+ return true;
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
{
- std::string name = "";
+ std::string name = "";
- switch (type)
- {
+ switch (type)
+ {
case dullahan::CT_POINTER:
name = "UI_CURSOR_ARROW";
break;
@@ -419,9 +419,9 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
case dullahan::CT_HAND:
name = "UI_CURSOR_HAND";
break;
- case dullahan::CT_IBEAM:
- name = "UI_CURSOR_IBEAM";
- break;
+ case dullahan::CT_IBEAM:
+ name = "UI_CURSOR_IBEAM";
+ break;
case dullahan::CT_WAIT:
name = "UI_CURSOR_WAIT";
break;
@@ -491,111 +491,111 @@ void MediaPluginCEF::onCursorChangedCallback(dullahan::ECursorType type)
//case dullahan::CT_GRABING:
//case dullahan::CT_CUSTOM:
- default:
- LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
- break;
- }
+ default:
+ LL_WARNS() << "Unknown cursor ID: " << (int)type << LL_ENDL;
+ break;
+ }
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
- message.setValue("name", name);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed");
+ message.setValue("name", name);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::authResponse(LLPluginMessage &message)
{
- mAuthOK = message.getValueBoolean("ok");
- if (mAuthOK)
- {
- mAuthUsername = message.getValue("username");
- mAuthPassword = message.getValue("password");
- }
+ mAuthOK = message.getValueBoolean("ok");
+ if (mAuthOK)
+ {
+ mAuthUsername = message.getValue("username");
+ mAuthPassword = message.getValue("password");
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginCEF::receiveMessage(const char* message_string)
{
- // std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
- LLPluginMessage message_in;
-
- if (message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if (message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
- message.setValueLLSD("versions", versions);
-
- std::string plugin_version = "CEF plugin 1.1.412";
- message.setValue("plugin_version", plugin_version);
- sendMessage(message);
- }
- else if (message_name == "idle")
- {
- mCEFLib->update();
-
- mVolumeCatcher.pump();
-
- // this seems bad but unless the state changes (it won't until we figure out
- // how to get CEF to tell us if copy/cut/paste is available) then this function
- // will return immediately
- checkEditState();
- }
- else if (message_name == "cleanup")
- {
- mCEFLib->requestExit();
- }
- else if (message_name == "force_exit")
- {
- mDeleteMe = true;
- }
- else if (message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if (message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- if (mPixels == iter->second.mAddress)
- {
- mPixels = NULL;
- mTextureSegmentName.clear();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
- }
-
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
- }
- }
- else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
+ // std::cerr << "MediaPluginCEF::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if (message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if (message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::string plugin_version = "CEF plugin 1.1.412";
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+ }
+ else if (message_name == "idle")
+ {
+ mCEFLib->update();
+
+ mVolumeCatcher.pump();
+
+ // this seems bad but unless the state changes (it won't until we figure out
+ // how to get CEF to tell us if copy/cut/paste is available) then this function
+ // will return immediately
+ checkEditState();
+ }
+ else if (message_name == "cleanup")
+ {
+ mCEFLib->requestExit();
+ }
+ else if (message_name == "force_exit")
+ {
+ mDeleteMe = true;
+ }
+ else if (message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if (message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ if (mPixels == iter->second.mAddress)
+ {
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ }
+
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
if (message_name == "init")
{
// event callbacks from Dullahan
@@ -619,10 +619,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
dullahan::dullahan_settings settings;
#if LL_WINDOWS
- // As of CEF version 83+, for Windows versions, we need to tell CEF
+ // As of CEF version 83+, for Windows versions, we need to tell CEF
// where the host helper process is since this DLL is not in the same
- // dir as the executable that loaded it (SLPlugin.exe). The code in
- // Dullahan that tried to figure out the location automatically uses
+ // dir as the executable that loaded it (SLPlugin.exe). The code in
+ // Dullahan that tried to figure out the location automatically uses
// the location of the exe which isn't helpful so we tell it explicitly.
std::vector<wchar_t> buffer(MAX_PATH + 1);
GetCurrentDirectoryW(MAX_PATH, &buffer[0]);
@@ -633,7 +633,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
// SL-15560: Product team overruled my change to set the default
// embedded background color to match the floater background
// and set it to white
- settings.background_color = 0xffffffff; // white
+ settings.background_color = 0xffffffff; // white
settings.cache_enabled = true;
settings.root_cache_path = mRootCachePath;
@@ -648,88 +648,88 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
proxy_url << mProxyHost << ":" << mProxyPort;
settings.proxy_host_port = proxy_url.str();
}
- settings.disable_gpu = mDisableGPU;
+ settings.disable_gpu = mDisableGPU;
#if LL_DARWIN
- settings.disable_network_service = mDisableNetworkService;
- settings.use_mock_keychain = mUseMockKeyChain;
+ settings.disable_network_service = mDisableNetworkService;
+ settings.use_mock_keychain = mUseMockKeyChain;
#endif
// these were added to facilitate loading images directly into a local
- // web page for the prototype 360 project in 2017 - something that is
+ // web page for the prototype 360 project in 2017 - something that is
// disallowed normally by the browser security model. Now the the source
// (cubemap) images are stores as JavaScript, we can avoid opening up
- // this security hole (it was only set for the 360 floater but still
- // a concern). Leaving them here, explicitly turn off vs removing
- // entirely from this source file so that others are aware of them
+ // this security hole (it was only set for the 360 floater but still
+ // a concern). Leaving them here, explicitly turn off vs removing
+ // entirely from this source file so that others are aware of them
// in the future.
settings.disable_web_security = false;
settings.file_access_from_file_urls = false;
settings.flash_enabled = mPluginsEnabled;
- // This setting applies to all plugins, not just Flash
- // Regarding, SL-15559 PDF files do not load in CEF v91,
- // it turns out that on Windows, PDF support is treated
- // as a plugin on Windows only so turning all plugins
- // off, disabled built in PDF support. (Works okay in
- // macOS surprisingly). To mitigrate this, we set the global
- // media enabled flag to whatever the consumer wants and
- // explicitly disable Flash with a different setting (below)
- settings.plugins_enabled = mPluginsEnabled;
-
- // SL-14897 Disable Flash support in the embedded browser
- settings.flash_enabled = false;
-
- settings.flip_mouse_y = false;
- settings.flip_pixels_y = true;
- settings.frame_rate = 60;
- settings.force_wave_audio = true;
- settings.initial_height = 1024;
- settings.initial_width = 1024;
- settings.java_enabled = false;
- settings.javascript_enabled = mJavascriptEnabled;
- settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granularity/query UI
-
- settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
- settings.webgl_enabled = true;
- settings.log_file = mCefLogFile;
- settings.log_verbose = mCefLogVerbose;
- settings.autoplay_without_gesture = true;
-
- std::vector<std::string> custom_schemes(1, "secondlife");
- mCEFLib->setCustomSchemes(custom_schemes);
-
- bool result = mCEFLib->init(settings);
+ // This setting applies to all plugins, not just Flash
+ // Regarding, SL-15559 PDF files do not load in CEF v91,
+ // it turns out that on Windows, PDF support is treated
+ // as a plugin on Windows only so turning all plugins
+ // off, disabled built in PDF support. (Works okay in
+ // macOS surprisingly). To mitigrate this, we set the global
+ // media enabled flag to whatever the consumer wants and
+ // explicitly disable Flash with a different setting (below)
+ settings.plugins_enabled = mPluginsEnabled;
+
+ // SL-14897 Disable Flash support in the embedded browser
+ settings.flash_enabled = false;
+
+ settings.flip_mouse_y = false;
+ settings.flip_pixels_y = true;
+ settings.frame_rate = 60;
+ settings.force_wave_audio = true;
+ settings.initial_height = 1024;
+ settings.initial_width = 1024;
+ settings.java_enabled = false;
+ settings.javascript_enabled = mJavascriptEnabled;
+ settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granularity/query UI
+
+ settings.user_agent_substring = mCEFLib->makeCompatibleUserAgentString(mUserAgentSubtring);
+ settings.webgl_enabled = true;
+ settings.log_file = mCefLogFile;
+ settings.log_verbose = mCefLogVerbose;
+ settings.autoplay_without_gesture = true;
+
+ std::vector<std::string> custom_schemes(1, "secondlife");
+ mCEFLib->setCustomSchemes(custom_schemes);
+
+ bool result = mCEFLib->init(settings);
if (!result)
{
// if this fails, the media system in viewer will put up a message
}
- // now we can set page zoom factor
- F32 factor = (F32)message_in.getValueReal("factor");
+ // now we can set page zoom factor
+ F32 factor = (F32)message_in.getValueReal("factor");
#if LL_DARWIN
- //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
- factor*=1.001;
+ //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+ factor*=1.001;
#endif
- mCEFLib->setPageZoom(factor);
-
- // Plugin gets to decide the texture parameters to use.
- mDepth = 4;
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 1024);
- message.setValueS32("default_height", 1024);
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGB);
- message.setValueU32("format", GL_BGRA);
- message.setValueU32("type", GL_UNSIGNED_BYTE);
- message.setValueBoolean("coords_opengl", true);
- sendMessage(message);
- }
- else if (message_name == "set_user_data_path")
- {
- std::string user_data_path_cache = message_in.getValue("cache_path");
- std::string subfolder = message_in.getValue("username");
-
- mRootCachePath = user_data_path_cache + "cef_cache";
+ mCEFLib->setPageZoom(factor);
+
+ // Plugin gets to decide the texture parameters to use.
+ mDepth = 4;
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueU32("format", GL_BGRA);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if (message_name == "set_user_data_path")
+ {
+ std::string user_data_path_cache = message_in.getValue("cache_path");
+ std::string subfolder = message_in.getValue("username");
+
+ mRootCachePath = user_data_path_cache + "cef_cache";
if (!subfolder.empty())
{
std::string delim;
@@ -746,132 +746,132 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
mCachePath = mRootCachePath;
}
mContextCachePath = ""; // disabled by ""
- mCefLogFile = message_in.getValue("cef_log_file");
- mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
- }
- else if (message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
-
- if (!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- mPixels = (unsigned char*)iter->second.mAddress;
- mWidth = width;
- mHeight = height;
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
-
- mCEFLib->setSize(mWidth, mHeight);
- };
- };
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- }
- else if (message_name == "set_language_code")
- {
- mHostLanguage = message_in.getValue("language");
- }
- else if (message_name == "load_uri")
- {
- std::string uri = message_in.getValue("uri");
- mCEFLib->navigate(uri);
- }
- else if (message_name == "execute_javascript")
- {
- std::string code = message_in.getValue("code");
- mCEFLib->executeJavaScript(code);
- }
- else if (message_name == "set_cookie")
- {
- std::string uri = message_in.getValue("uri");
- std::string name = message_in.getValue("name");
- std::string value = message_in.getValue("value");
- std::string domain = message_in.getValue("domain");
- std::string path = message_in.getValue("path");
- bool httponly = message_in.getValueBoolean("httponly");
- bool secure = message_in.getValueBoolean("secure");
- mCEFLib->setCookie(uri, name, value, domain, path, httponly, secure);
- }
- else if (message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
-
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
-
- // only even send left mouse button events to the CEF library
- // (partially prompted by crash in OS X CEF when sending right button events)
- // we catch the right click in viewer and display our own context menu anyway
- S32 button = message_in.getValueS32("button");
- dullahan::EMouseButton btn = dullahan::MB_MOUSE_BUTTON_LEFT;
-
- if (event == "down" && button == 0)
- {
- mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_DOWN, x, y);
- mCEFLib->setFocus();
-
- std::stringstream str;
- str << "Mouse down at = " << x << ", " << y;
- postDebugMessage(str.str());
- }
- else if (event == "up" && button == 0)
- {
- mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_UP, x, y);
-
- std::stringstream str;
- str << "Mouse up at = " << x << ", " << y;
- postDebugMessage(str.str());
- }
- else if (event == "double_click")
- {
- mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_DOUBLE_CLICK, x, y);
- }
- else
- {
- mCEFLib->mouseMove(x, y);
- }
- }
- else if (message_name == "scroll_event")
- {
- // Mouse coordinates for cef to be able to scroll 'containers'
- S32 x = message_in.getValueS32("x");
- S32 y = message_in.getValueS32("y");
-
- // Wheel's clicks
- S32 delta_x = message_in.getValueS32("clicks_x");
- S32 delta_y = message_in.getValueS32("clicks_y");
- const int scaling_factor = 40;
- delta_x *= -scaling_factor;
- delta_y *= -scaling_factor;
-
- mCEFLib->mouseWheel(x, y, delta_x, delta_y);
- }
- else if (message_name == "text_event")
- {
- std::string event = message_in.getValue("event");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
- unicodeInput(event, native_key_data);
- }
- else if (message_name == "key_event")
- {
+ mCefLogFile = message_in.getValue("cef_log_file");
+ mCefLogVerbose = message_in.getValueBoolean("cef_verbose_log");
+ }
+ else if (message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if (!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+
+ mCEFLib->setSize(mWidth, mHeight);
+ };
+ };
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ }
+ else if (message_name == "set_language_code")
+ {
+ mHostLanguage = message_in.getValue("language");
+ }
+ else if (message_name == "load_uri")
+ {
+ std::string uri = message_in.getValue("uri");
+ mCEFLib->navigate(uri);
+ }
+ else if (message_name == "execute_javascript")
+ {
+ std::string code = message_in.getValue("code");
+ mCEFLib->executeJavaScript(code);
+ }
+ else if (message_name == "set_cookie")
+ {
+ std::string uri = message_in.getValue("uri");
+ std::string name = message_in.getValue("name");
+ std::string value = message_in.getValue("value");
+ std::string domain = message_in.getValue("domain");
+ std::string path = message_in.getValue("path");
+ bool httponly = message_in.getValueBoolean("httponly");
+ bool secure = message_in.getValueBoolean("secure");
+ mCEFLib->setCookie(uri, name, value, domain, path, httponly, secure);
+ }
+ else if (message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ // only even send left mouse button events to the CEF library
+ // (partially prompted by crash in OS X CEF when sending right button events)
+ // we catch the right click in viewer and display our own context menu anyway
+ S32 button = message_in.getValueS32("button");
+ dullahan::EMouseButton btn = dullahan::MB_MOUSE_BUTTON_LEFT;
+
+ if (event == "down" && button == 0)
+ {
+ mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_DOWN, x, y);
+ mCEFLib->setFocus();
+
+ std::stringstream str;
+ str << "Mouse down at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "up" && button == 0)
+ {
+ mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_UP, x, y);
+
+ std::stringstream str;
+ str << "Mouse up at = " << x << ", " << y;
+ postDebugMessage(str.str());
+ }
+ else if (event == "double_click")
+ {
+ mCEFLib->mouseButton(btn, dullahan::ME_MOUSE_DOUBLE_CLICK, x, y);
+ }
+ else
+ {
+ mCEFLib->mouseMove(x, y);
+ }
+ }
+ else if (message_name == "scroll_event")
+ {
+ // Mouse coordinates for cef to be able to scroll 'containers'
+ S32 x = message_in.getValueS32("x");
+ S32 y = message_in.getValueS32("y");
+
+ // Wheel's clicks
+ S32 delta_x = message_in.getValueS32("clicks_x");
+ S32 delta_y = message_in.getValueS32("clicks_y");
+ const int scaling_factor = 40;
+ delta_x *= -scaling_factor;
+ delta_y *= -scaling_factor;
+
+ mCEFLib->mouseWheel(x, y, delta_x, delta_y);
+ }
+ else if (message_name == "text_event")
+ {
+ std::string event = message_in.getValue("event");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+ unicodeInput(event, native_key_data);
+ }
+ else if (message_name == "key_event")
+ {
#if LL_DARWIN
- std::string event = message_in.getValue("event");
+ std::string event = message_in.getValue("event");
LLSD native_key_data = message_in.getValueLLSD("native_key_data");
dullahan::EKeyEvent key_event = dullahan::KE_KEY_UP;
@@ -887,139 +887,139 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
keyEvent(key_event, native_key_data);
#else
- std::string event = message_in.getValue("event");
- LLSD native_key_data = message_in.getValueLLSD("native_key_data");
-
- // Treat unknown events as key-up for safety.
- dullahan::EKeyEvent key_event = dullahan::KE_KEY_UP;
- if (event == "down")
- {
- key_event = dullahan::KE_KEY_DOWN;
- }
- else if (event == "repeat")
- {
- key_event = dullahan::KE_KEY_REPEAT;
- }
-
- keyEvent(key_event, native_key_data);
+ std::string event = message_in.getValue("event");
+ LLSD native_key_data = message_in.getValueLLSD("native_key_data");
+
+ // Treat unknown events as key-up for safety.
+ dullahan::EKeyEvent key_event = dullahan::KE_KEY_UP;
+ if (event == "down")
+ {
+ key_event = dullahan::KE_KEY_DOWN;
+ }
+ else if (event == "repeat")
+ {
+ key_event = dullahan::KE_KEY_REPEAT;
+ }
+
+ keyEvent(key_event, native_key_data);
#endif
- }
- else if (message_name == "enable_media_plugin_debugging")
- {
- mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
- }
- if (message_name == "pick_file_response")
- {
- LLSD file_list_llsd = message_in.getValueLLSD("file_list");
-
- LLSD::array_const_iterator iter = file_list_llsd.beginArray();
- LLSD::array_const_iterator end = file_list_llsd.endArray();
- for (; iter != end; ++iter)
- {
- mPickedFiles.push_back(((*iter).asString()));
- }
- }
- if (message_name == "auth_response")
- {
- authResponse(message_in);
- }
- if (message_name == "edit_cut")
- {
- mCEFLib->editCut();
- }
- if (message_name == "edit_copy")
- {
- mCEFLib->editCopy();
- }
- if (message_name == "edit_paste")
- {
- mCEFLib->editPaste();
- }
- }
- else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
- {
- if (message_name == "set_page_zoom_factor")
- {
- F32 factor = (F32)message_in.getValueReal("factor");
+ }
+ else if (message_name == "enable_media_plugin_debugging")
+ {
+ mEnableMediaPluginDebugging = message_in.getValueBoolean("enable");
+ }
+ if (message_name == "pick_file_response")
+ {
+ LLSD file_list_llsd = message_in.getValueLLSD("file_list");
+
+ LLSD::array_const_iterator iter = file_list_llsd.beginArray();
+ LLSD::array_const_iterator end = file_list_llsd.endArray();
+ for (; iter != end; ++iter)
+ {
+ mPickedFiles.push_back(((*iter).asString()));
+ }
+ }
+ if (message_name == "auth_response")
+ {
+ authResponse(message_in);
+ }
+ if (message_name == "edit_cut")
+ {
+ mCEFLib->editCut();
+ }
+ if (message_name == "edit_copy")
+ {
+ mCEFLib->editCopy();
+ }
+ if (message_name == "edit_paste")
+ {
+ mCEFLib->editPaste();
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
+ {
+ if (message_name == "set_page_zoom_factor")
+ {
+ F32 factor = (F32)message_in.getValueReal("factor");
#if LL_DARWIN
- //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
- factor*=1.001;
+ //temporary fix for SL-10473: issue with displaying checkboxes on Mojave
+ factor*=1.001;
#endif
- mCEFLib->setPageZoom(factor);
- }
- if (message_name == "browse_stop")
- {
- mCEFLib->stop();
- }
- else if (message_name == "browse_reload")
- {
- bool ignore_cache = true;
- mCEFLib->reload(ignore_cache);
- }
- else if (message_name == "browse_forward")
- {
- mCEFLib->goForward();
- }
- else if (message_name == "browse_back")
- {
- mCEFLib->goBack();
- }
- else if (message_name == "cookies_enabled")
- {
- mCookiesEnabled = message_in.getValueBoolean("enable");
- }
- else if (message_name == "clear_cookies")
- {
- mCEFLib->deleteAllCookies();
- }
- else if (message_name == "set_user_agent")
- {
- mUserAgentSubtring = message_in.getValue("user_agent");
- }
- else if (message_name == "show_web_inspector")
- {
- mCEFLib->showDevTools();
- }
- else if (message_name == "plugins_enabled")
- {
- mPluginsEnabled = message_in.getValueBoolean("enable");
- }
- else if (message_name == "javascript_enabled")
- {
- mJavascriptEnabled = message_in.getValueBoolean("enable");
- }
- else if (message_name == "gpu_disabled")
- {
- mDisableGPU = message_in.getValueBoolean("disable");
- }
+ mCEFLib->setPageZoom(factor);
+ }
+ if (message_name == "browse_stop")
+ {
+ mCEFLib->stop();
+ }
+ else if (message_name == "browse_reload")
+ {
+ bool ignore_cache = true;
+ mCEFLib->reload(ignore_cache);
+ }
+ else if (message_name == "browse_forward")
+ {
+ mCEFLib->goForward();
+ }
+ else if (message_name == "browse_back")
+ {
+ mCEFLib->goBack();
+ }
+ else if (message_name == "cookies_enabled")
+ {
+ mCookiesEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "clear_cookies")
+ {
+ mCEFLib->deleteAllCookies();
+ }
+ else if (message_name == "set_user_agent")
+ {
+ mUserAgentSubtring = message_in.getValue("user_agent");
+ }
+ else if (message_name == "show_web_inspector")
+ {
+ mCEFLib->showDevTools();
+ }
+ else if (message_name == "plugins_enabled")
+ {
+ mPluginsEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "javascript_enabled")
+ {
+ mJavascriptEnabled = message_in.getValueBoolean("enable");
+ }
+ else if (message_name == "gpu_disabled")
+ {
+ mDisableGPU = message_in.getValueBoolean("disable");
+ }
else if (message_name == "proxy_setup")
{
mProxyEnabled = message_in.getValueBoolean("enable");
mProxyHost = message_in.getValue("host");
mProxyPort = message_in.getValueS32("port");
}
- else if (message_name == "web_security_disabled")
- {
- mDisableWebSecurity = message_in.getValueBoolean("disabled");
- }
- else if (message_name == "file_access_from_file_urls")
- {
- mFileAccessFromFileUrls = message_in.getValueBoolean("enabled");
- }
- }
+ else if (message_name == "web_security_disabled")
+ {
+ mDisableWebSecurity = message_in.getValueBoolean("disabled");
+ }
+ else if (message_name == "file_access_from_file_urls")
+ {
+ mFileAccessFromFileUrls = message_in.getValueBoolean("enabled");
+ }
+ }
else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
{
if (message_name == "set_volume")
{
- F32 volume = (F32)message_in.getValueReal("volume");
- mCurVolume = volume;
+ F32 volume = (F32)message_in.getValueReal("volume");
+ mCurVolume = volume;
setVolume();
}
}
else
- {
- };
- }
+ {
+ };
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -1027,49 +1027,49 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_data = LLSD::emptyMap())
{
#if LL_DARWIN
- U32 event_modifiers = native_key_data["event_modifiers"].asInteger();
- U32 event_keycode = native_key_data["event_keycode"].asInteger();
- U32 event_chars = native_key_data["event_chars"].asInteger();
- U32 event_umodchars = native_key_data["event_umodchars"].asInteger();
- bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean();
-
- // adding new code below in unicodeInput means we don't send ascii chars
- // here too or we get double key presses on a mac.
- bool esc_key = (event_umodchars == 27);
- bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP);
- if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up)
- {
- mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
- event_keycode, event_chars,
- event_umodchars, event_isrepeat);
- }
+ U32 event_modifiers = native_key_data["event_modifiers"].asInteger();
+ U32 event_keycode = native_key_data["event_keycode"].asInteger();
+ U32 event_chars = native_key_data["event_chars"].asInteger();
+ U32 event_umodchars = native_key_data["event_umodchars"].asInteger();
+ bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean();
+
+ // adding new code below in unicodeInput means we don't send ascii chars
+ // here too or we get double key presses on a mac.
+ bool esc_key = (event_umodchars == 27);
+ bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP);
+ if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up)
+ {
+ mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
+ event_keycode, event_chars,
+ event_umodchars, event_isrepeat);
+ }
#elif LL_WINDOWS
- U32 msg = ll_U32_from_sd(native_key_data["msg"]);
- U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
- U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
- mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
+ mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
#endif
#if LL_LINUX
- uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); // this is actually the SDL event.key.keysym.sym;
- uint32_t native_virtual_key_win = (uint32_t)(native_key_data["virtual_key_win"].asInteger());
- uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+ uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); // this is actually the SDL event.key.keysym.sym;
+ uint32_t native_virtual_key_win = (uint32_t)(native_key_data["virtual_key_win"].asInteger());
+ uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
- // only for non-printable keysyms, the actual text input is done in unicodeInput() below
- if (native_virtual_key <= 0x1b || native_virtual_key >= 0x7f)
- {
- // set keypad flag, not sure if this even does anything
- bool keypad = false;
- if (native_virtual_key_win >= 0x60 && native_virtual_key_win <= 0x6f)
- {
- keypad = true;
- }
+ // only for non-printable keysyms, the actual text input is done in unicodeInput() below
+ if (native_virtual_key <= 0x1b || native_virtual_key >= 0x7f)
+ {
+ // set keypad flag, not sure if this even does anything
+ bool keypad = false;
+ if (native_virtual_key_win >= 0x60 && native_virtual_key_win <= 0x6f)
+ {
+ keypad = true;
+ }
- // yes, we send native_virtual_key_win twice because native_virtual_key breaks it
- mCEFLib->nativeKeyboardEventSDL2(key_event, native_virtual_key, native_modifiers, keypad);
- }
+ // yes, we send native_virtual_key_win twice because native_virtual_key breaks it
+ mCEFLib->nativeKeyboardEventSDL2(key_event, native_virtual_key, native_modifiers, keypad);
+ }
#endif // LL_LINUX
};
@@ -1077,14 +1077,14 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat
void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD::emptyMap())
{
#if LL_DARWIN
- // i didn't think this code was needed for macOS but without it, the IME
- // input in japanese (and likely others too) doesn't work correctly.
- // see maint-7654
- U32 event_modifiers = native_key_data["event_modifiers"].asInteger();
- U32 event_keycode = native_key_data["event_keycode"].asInteger();
- U32 event_chars = native_key_data["event_chars"].asInteger();
- U32 event_umodchars = native_key_data["event_umodchars"].asInteger();
- bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean();
+ // i didn't think this code was needed for macOS but without it, the IME
+ // input in japanese (and likely others too) doesn't work correctly.
+ // see maint-7654
+ U32 event_modifiers = native_key_data["event_modifiers"].asInteger();
+ U32 event_keycode = native_key_data["event_keycode"].asInteger();
+ U32 event_chars = native_key_data["event_chars"].asInteger();
+ U32 event_umodchars = native_key_data["event_umodchars"].asInteger();
+ bool event_isrepeat = native_key_data["event_isrepeat"].asBoolean();
dullahan::EKeyEvent key_event = dullahan::KE_KEY_UP;
if (event == "down")
@@ -1092,24 +1092,24 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD
key_event = dullahan::KE_KEY_DOWN;
}
- mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
- event_keycode, event_chars,
- event_umodchars, event_isrepeat);
+ mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers,
+ event_keycode, event_chars,
+ event_umodchars, event_isrepeat);
#elif LL_WINDOWS
- event = ""; // not needed here but prevents unused var warning as error
- U32 msg = ll_U32_from_sd(native_key_data["msg"]);
- U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
- U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
- mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
+ event = ""; // not needed here but prevents unused var warning as error
+ U32 msg = ll_U32_from_sd(native_key_data["msg"]);
+ U32 wparam = ll_U32_from_sd(native_key_data["w_param"]);
+ U64 lparam = ll_U32_from_sd(native_key_data["l_param"]);
+ mCEFLib->nativeKeyboardEventWin(msg, wparam, lparam);
#endif
#if LL_LINUX
- uint32_t native_scan_code = (uint32_t)(native_key_data["sdl_sym"].asInteger());
- uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
- uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
+ uint32_t native_scan_code = (uint32_t)(native_key_data["sdl_sym"].asInteger());
+ uint32_t native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger());
+ uint32_t native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger());
- mCEFLib->nativeKeyboardEvent(dullahan::KE_KEY_DOWN, native_scan_code, native_virtual_key, native_modifiers);
+ mCEFLib->nativeKeyboardEvent(dullahan::KE_KEY_DOWN, native_scan_code, native_virtual_key, native_modifiers);
#endif // LL_LINUX
};
@@ -1118,62 +1118,62 @@ void MediaPluginCEF::unicodeInput(std::string event, LLSD native_key_data = LLSD
//
void MediaPluginCEF::checkEditState()
{
- bool can_cut = mCEFLib->editCanCut();
- bool can_copy = mCEFLib->editCanCopy();
- bool can_paste = mCEFLib->editCanPaste();
-
- if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
-
- if (can_cut != mCanCut)
- {
- mCanCut = can_cut;
- message.setValueBoolean("cut", can_cut);
- }
-
- if (can_copy != mCanCopy)
- {
- mCanCopy = can_copy;
- message.setValueBoolean("copy", can_copy);
- }
-
- if (can_paste != mCanPaste)
- {
- mCanPaste = can_paste;
- message.setValueBoolean("paste", can_paste);
- }
-
- sendMessage(message);
- }
+ bool can_cut = mCEFLib->editCanCut();
+ bool can_copy = mCEFLib->editCanCopy();
+ bool can_paste = mCEFLib->editCanPaste();
+
+ if ((can_cut != mCanCut) || (can_copy != mCanCopy) || (can_paste != mCanPaste))
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_state");
+
+ if (can_cut != mCanCut)
+ {
+ mCanCut = can_cut;
+ message.setValueBoolean("cut", can_cut);
+ }
+
+ if (can_copy != mCanCopy)
+ {
+ mCanCopy = can_copy;
+ message.setValueBoolean("copy", can_copy);
+ }
+
+ if (can_paste != mCanPaste)
+ {
+ mCanPaste = can_paste;
+ message.setValueBoolean("paste", can_paste);
+ }
+
+ sendMessage(message);
+ }
}
void MediaPluginCEF::setVolume()
{
- mVolumeCatcher.setVolume(mCurVolume);
+ mVolumeCatcher.setVolume(mCurVolume);
}
////////////////////////////////////////////////////////////////////////////////
//
bool MediaPluginCEF::init()
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", "CEF Plugin");
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", "CEF Plugin");
+ sendMessage(message);
- return true;
+ return true;
};
////////////////////////////////////////////////////////////////////////////////
//
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
- void* host_user_data,
- LLPluginInstance::sendMessageFunction *plugin_send_func,
- void **plugin_user_data)
+ void* host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data)
{
- MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginCEF::staticReceiveMessage;
- *plugin_user_data = (void*)self;
+ MediaPluginCEF* self = new MediaPluginCEF(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginCEF::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
- return 0;
+ return 0;
}
diff --git a/indra/media_plugins/cef/volume_catcher.h b/indra/media_plugins/cef/volume_catcher.h
index 337f2913d3..ea97a24947 100644
--- a/indra/media_plugins/cef/volume_catcher.h
+++ b/indra/media_plugins/cef/volume_catcher.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file volume_catcher.h
* @brief Interface to a class with platform-specific implementations that allows control of the audio volume of all sources in the current process.
*
@@ -6,21 +6,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$
* @endcond
@@ -36,19 +36,19 @@ class VolumeCatcherImpl;
class VolumeCatcher
{
public:
- VolumeCatcher();
- ~VolumeCatcher();
+ VolumeCatcher();
+ ~VolumeCatcher();
+
+ void setVolume(F32 volume); // 0.0 - 1.0
+
+ // Set the left-right pan of audio sources
+ // where -1.0 = left, 0 = center, and 1.0 = right
+ void setPan(F32 pan);
- void setVolume(F32 volume); // 0.0 - 1.0
-
- // Set the left-right pan of audio sources
- // where -1.0 = left, 0 = center, and 1.0 = right
- void setPan(F32 pan);
+ void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
- void pump(); // call this at least a few times a second if you can - it affects how quickly we can 'catch' a new audio source and adjust its volume
-
private:
- VolumeCatcherImpl *pimpl;
+ VolumeCatcherImpl *pimpl;
};
#endif // VOLUME_CATCHER_H
diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
index 7a36123a11..e7daeb5f74 100644
--- a/indra/media_plugins/cef/windows_volume_catcher.cpp
+++ b/indra/media_plugins/cef/windows_volume_catcher.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file windows_volume_catcher.cpp
* @brief A Windows implementation of volume level control of all audio channels opened by a process.
*
@@ -6,21 +6,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$
* @endcond
@@ -32,24 +32,24 @@
#include <mmeapi.h>
class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
{
- LLSINGLETON(VolumeCatcherImpl);
- // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
- ~VolumeCatcherImpl();
+ LLSINGLETON(VolumeCatcherImpl);
+ // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+ ~VolumeCatcherImpl();
public:
- void setVolume(F32 volume);
- void setPan(F32 pan);
-
+ void setVolume(F32 volume);
+ void setPan(F32 pan);
+
private:
- F32 mVolume;
- F32 mPan;
- bool mSystemIsVistaOrHigher;
+ F32 mVolume;
+ F32 mPan;
+ bool mSystemIsVistaOrHigher;
};
VolumeCatcherImpl::VolumeCatcherImpl()
-: mVolume(1.0f), // default volume is max
- mPan(0.f) // default pan is centered
+: mVolume(1.0f), // default volume is max
+ mPan(0.f) // default pan is centered
{
}
@@ -59,46 +59,46 @@ VolumeCatcherImpl::~VolumeCatcherImpl()
void VolumeCatcherImpl::setVolume(F32 volume)
{
- mVolume = volume;
-
- // set both left/right to same volume
- // TODO: use pan value to set independently
- DWORD left_channel = (DWORD)(mVolume * 65535.0f);
- DWORD right_channel = (DWORD)(mVolume * 65535.0f);
- DWORD hw_volume = left_channel << 16 | right_channel;
- ::waveOutSetVolume(NULL, hw_volume);
+ mVolume = volume;
+
+ // set both left/right to same volume
+ // TODO: use pan value to set independently
+ DWORD left_channel = (DWORD)(mVolume * 65535.0f);
+ DWORD right_channel = (DWORD)(mVolume * 65535.0f);
+ DWORD hw_volume = left_channel << 16 | right_channel;
+ ::waveOutSetVolume(NULL, hw_volume);
}
void VolumeCatcherImpl::setPan(F32 pan)
-{ // remember pan for calculating individual channel levels later
- mPan = pan;
+{ // remember pan for calculating individual channel levels later
+ mPan = pan;
}
/////////////////////////////////////////////////////
VolumeCatcher::VolumeCatcher()
{
- pimpl = VolumeCatcherImpl::getInstance();
+ pimpl = VolumeCatcherImpl::getInstance();
}
VolumeCatcher::~VolumeCatcher()
{
- // Let the instance persist until exit.
+ // Let the instance persist until exit.
}
void VolumeCatcher::setVolume(F32 volume)
{
- pimpl->setVolume(volume);
+ pimpl->setVolume(volume);
}
void VolumeCatcher::setPan(F32 pan)
{
- pimpl->setPan(pan);
+ pimpl->setPan(pan);
}
void VolumeCatcher::pump()
{
- // No periodic tasks are necessary for this implementation.
+ // No periodic tasks are necessary for this implementation.
}
diff --git a/indra/media_plugins/example/media_plugin_example.cpp b/indra/media_plugins/example/media_plugin_example.cpp
index 650685fb94..0b22b7833f 100644
--- a/indra/media_plugins/example/media_plugin_example.cpp
+++ b/indra/media_plugins/example/media_plugin_example.cpp
@@ -39,30 +39,30 @@
////////////////////////////////////////////////////////////////////////////////
//
class mediaPluginExample :
- public MediaPluginBase
+ public MediaPluginBase
{
public:
- mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~mediaPluginExample();
+ mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~mediaPluginExample();
- /*virtual*/ void receiveMessage(const char* message_string);
+ /*virtual*/ void receiveMessage(const char* message_string);
private:
- bool init();
- void update(F64 milliseconds);
- bool mFirstTime;
-
- time_t mLastUpdateTime;
- enum Constants { ENumObjects = 64 };
- unsigned char* mBackgroundPixels;
- int mColorR[ENumObjects];
- int mColorG[ENumObjects];
- int mColorB[ENumObjects];
- int mXpos[ENumObjects];
- int mYpos[ENumObjects];
- int mXInc[ENumObjects];
- int mYInc[ENumObjects];
- int mBlockSize[ENumObjects];
+ bool init();
+ void update(F64 milliseconds);
+ bool mFirstTime;
+
+ time_t mLastUpdateTime;
+ enum Constants { ENumObjects = 64 };
+ unsigned char* mBackgroundPixels;
+ int mColorR[ENumObjects];
+ int mColorG[ENumObjects];
+ int mColorB[ENumObjects];
+ int mXpos[ENumObjects];
+ int mYpos[ENumObjects];
+ int mXInc[ENumObjects];
+ int mYInc[ENumObjects];
+ int mBlockSize[ENumObjects];
};
////////////////////////////////////////////////////////////////////////////////
@@ -70,15 +70,15 @@ private:
mediaPluginExample::mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
MediaPluginBase(host_send_func, host_user_data)
{
- mFirstTime = true;
- mTextureWidth = 0;
- mTextureHeight = 0;
- mWidth = 0;
- mHeight = 0;
- mDepth = 4;
- mPixels = 0;
- mLastUpdateTime = 0;
- mBackgroundPixels = 0;
+ mFirstTime = true;
+ mTextureWidth = 0;
+ mTextureHeight = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mDepth = 4;
+ mPixels = 0;
+ mLastUpdateTime = 0;
+ mBackgroundPixels = 0;
}
////////////////////////////////////////////////////////////////////////////////
@@ -91,305 +91,305 @@ mediaPluginExample::~mediaPluginExample()
//
void mediaPluginExample::receiveMessage(const char* message_string)
{
- // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
- LLPluginMessage message_in;
-
- if (message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if (message_name == "init")
- {
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
- message.setValueLLSD("versions", versions);
-
- std::string plugin_version = "Example plugin 0.0.0";
- message.setValue("plugin_version", plugin_version);
- sendMessage(message);
- }
- else if (message_name == "idle")
- {
- // no response is necessary here.
- F64 time = message_in.getValueReal("time");
-
- // Convert time to milliseconds for update()
- update((int)(time * 1000.0f));
- }
- else if (message_name == "cleanup")
- {
- LLPluginMessage message("base", "goodbye");
- sendMessage(message);
-
- mDeleteMe = true;
- }
- else if (message_name == "force_exit")
- {
- mDeleteMe = true;
- }
- else if (message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if (message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- if (mPixels == iter->second.mAddress)
- {
- // This is the currently active pixel buffer. Make sure we stop drawing to it.
- mPixels = NULL;
- mTextureSegmentName.clear();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
- // std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
- // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
- }
- }
- else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if (message_name == "init")
- {
- // Plugin gets to decide the texture parameters to use.
- mDepth = 4;
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 1024);
- message.setValueS32("default_height", 1024);
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGB);
- message.setValueU32("format", GL_RGBA);
- message.setValueU32("type", GL_UNSIGNED_BYTE);
- message.setValueBoolean("coords_opengl", true);
- sendMessage(message);
- }
- else if (message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
-
- if (!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- mPixels = (unsigned char*)iter->second.mAddress;
- mWidth = width;
- mHeight = height;
-
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
- };
- };
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
-
- mFirstTime = true;
- mLastUpdateTime = 0;
-
- }
- else if (message_name == "load_uri")
- {
- }
- else if (message_name == "mouse_event")
- {
- std::string event = message_in.getValue("event");
- if (event == "down")
- {
-
- }
- else if (event == "up")
- {
- }
- else if (event == "double_click")
- {
- }
- }
- }
- else
- {
- };
- }
+ // std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+ LLPluginMessage message_in;
+
+ if (message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if (message_name == "init")
+ {
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::string plugin_version = "Example plugin 0.0.0";
+ message.setValue("plugin_version", plugin_version);
+ sendMessage(message);
+ }
+ else if (message_name == "idle")
+ {
+ // no response is necessary here.
+ F64 time = message_in.getValueReal("time");
+
+ // Convert time to milliseconds for update()
+ update((int)(time * 1000.0f));
+ }
+ else if (message_name == "cleanup")
+ {
+ LLPluginMessage message("base", "goodbye");
+ sendMessage(message);
+
+ mDeleteMe = true;
+ }
+ else if (message_name == "force_exit")
+ {
+ mDeleteMe = true;
+ }
+ else if (message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if (message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ if (mPixels == iter->second.mAddress)
+ {
+ // This is the currently active pixel buffer. Make sure we stop drawing to it.
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ // std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ // std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if (message_name == "init")
+ {
+ // Plugin gets to decide the texture parameters to use.
+ mDepth = 4;
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueU32("format", GL_RGBA);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if (message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if (!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
+ };
+ };
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+
+ mFirstTime = true;
+ mLastUpdateTime = 0;
+
+ }
+ else if (message_name == "load_uri")
+ {
+ }
+ else if (message_name == "mouse_event")
+ {
+ std::string event = message_in.getValue("event");
+ if (event == "down")
+ {
+
+ }
+ else if (event == "up")
+ {
+ }
+ else if (event == "double_click")
+ {
+ }
+ }
+ }
+ else
+ {
+ };
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void mediaPluginExample::update(F64 milliseconds)
{
- if (mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048)
- return;
-
- if (mPixels == 0)
- return;
-
- if (mFirstTime)
- {
- for (int n = 0; n < ENumObjects; ++n)
- {
- mXpos[n] = (mWidth / 2) + rand() % (mWidth / 16) - (mWidth / 32);
- mYpos[n] = (mHeight / 2) + rand() % (mHeight / 16) - (mHeight / 32);
-
- mColorR[n] = rand() % 0x60 + 0x60;
- mColorG[n] = rand() % 0x60 + 0x60;
- mColorB[n] = rand() % 0x60 + 0x60;
-
- mXInc[n] = 0;
- while (mXInc[n] == 0)
- mXInc[n] = rand() % 7 - 3;
-
- mYInc[n] = 0;
- while (mYInc[n] == 0)
- mYInc[n] = rand() % 9 - 4;
-
- mBlockSize[n] = rand() % 0x30 + 0x10;
- };
-
- delete[] mBackgroundPixels;
-
- mBackgroundPixels = new unsigned char[mWidth * mHeight * mDepth];
-
- mFirstTime = false;
- };
-
- if (time(NULL) > mLastUpdateTime + 3)
- {
- const int num_squares = rand() % 20 + 4;
- int sqr1_r = rand() % 0x80 + 0x20;
- int sqr1_g = rand() % 0x80 + 0x20;
- int sqr1_b = rand() % 0x80 + 0x20;
- int sqr2_r = rand() % 0x80 + 0x20;
- int sqr2_g = rand() % 0x80 + 0x20;
- int sqr2_b = rand() % 0x80 + 0x20;
-
- for (int y1 = 0; y1 < num_squares; ++y1)
- {
- for (int x1 = 0; x1 < num_squares; ++x1)
- {
- int px_start = mWidth * x1 / num_squares;
- int px_end = (mWidth * (x1 + 1)) / num_squares;
- int py_start = mHeight * y1 / num_squares;
- int py_end = (mHeight * (y1 + 1)) / num_squares;
-
- for (int y2 = py_start; y2 < py_end; ++y2)
- {
- for (int x2 = px_start; x2 < px_end; ++x2)
- {
- int rowspan = mWidth * mDepth;
-
- if ((y1 % 2) ^ (x1 % 2))
- {
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr1_r;
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr1_g;
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr1_b;
- }
- else
- {
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr2_r;
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr2_g;
- mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr2_b;
- };
- };
- };
- };
- };
-
- time(&mLastUpdateTime);
- };
-
- memcpy(mPixels, mBackgroundPixels, mWidth * mHeight * mDepth);
-
- for (int n = 0; n < ENumObjects; ++n)
- {
- if (rand() % 50 == 0)
- {
- mXInc[n] = 0;
- while (mXInc[n] == 0)
- mXInc[n] = rand() % 7 - 3;
-
- mYInc[n] = 0;
- while (mYInc[n] == 0)
- mYInc[n] = rand() % 9 - 4;
- };
-
- if (mXpos[n] + mXInc[n] < 0 || mXpos[n] + mXInc[n] >= mWidth - mBlockSize[n])
- mXInc[n] = -mXInc[n];
-
- if (mYpos[n] + mYInc[n] < 0 || mYpos[n] + mYInc[n] >= mHeight - mBlockSize[n])
- mYInc[n] = -mYInc[n];
-
- mXpos[n] += mXInc[n];
- mYpos[n] += mYInc[n];
-
- for (int y = 0; y < mBlockSize[n]; ++y)
- {
- for (int x = 0; x < mBlockSize[n]; ++x)
- {
- mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 0] = mColorR[n];
- mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 1] = mColorG[n];
- mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 2] = mColorB[n];
- };
- };
- };
-
- setDirty(0, 0, mWidth, mHeight);
+ if (mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048)
+ return;
+
+ if (mPixels == 0)
+ return;
+
+ if (mFirstTime)
+ {
+ for (int n = 0; n < ENumObjects; ++n)
+ {
+ mXpos[n] = (mWidth / 2) + rand() % (mWidth / 16) - (mWidth / 32);
+ mYpos[n] = (mHeight / 2) + rand() % (mHeight / 16) - (mHeight / 32);
+
+ mColorR[n] = rand() % 0x60 + 0x60;
+ mColorG[n] = rand() % 0x60 + 0x60;
+ mColorB[n] = rand() % 0x60 + 0x60;
+
+ mXInc[n] = 0;
+ while (mXInc[n] == 0)
+ mXInc[n] = rand() % 7 - 3;
+
+ mYInc[n] = 0;
+ while (mYInc[n] == 0)
+ mYInc[n] = rand() % 9 - 4;
+
+ mBlockSize[n] = rand() % 0x30 + 0x10;
+ };
+
+ delete[] mBackgroundPixels;
+
+ mBackgroundPixels = new unsigned char[mWidth * mHeight * mDepth];
+
+ mFirstTime = false;
+ };
+
+ if (time(NULL) > mLastUpdateTime + 3)
+ {
+ const int num_squares = rand() % 20 + 4;
+ int sqr1_r = rand() % 0x80 + 0x20;
+ int sqr1_g = rand() % 0x80 + 0x20;
+ int sqr1_b = rand() % 0x80 + 0x20;
+ int sqr2_r = rand() % 0x80 + 0x20;
+ int sqr2_g = rand() % 0x80 + 0x20;
+ int sqr2_b = rand() % 0x80 + 0x20;
+
+ for (int y1 = 0; y1 < num_squares; ++y1)
+ {
+ for (int x1 = 0; x1 < num_squares; ++x1)
+ {
+ int px_start = mWidth * x1 / num_squares;
+ int px_end = (mWidth * (x1 + 1)) / num_squares;
+ int py_start = mHeight * y1 / num_squares;
+ int py_end = (mHeight * (y1 + 1)) / num_squares;
+
+ for (int y2 = py_start; y2 < py_end; ++y2)
+ {
+ for (int x2 = px_start; x2 < px_end; ++x2)
+ {
+ int rowspan = mWidth * mDepth;
+
+ if ((y1 % 2) ^ (x1 % 2))
+ {
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr1_r;
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr1_g;
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr1_b;
+ }
+ else
+ {
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr2_r;
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr2_g;
+ mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr2_b;
+ };
+ };
+ };
+ };
+ };
+
+ time(&mLastUpdateTime);
+ };
+
+ memcpy(mPixels, mBackgroundPixels, mWidth * mHeight * mDepth);
+
+ for (int n = 0; n < ENumObjects; ++n)
+ {
+ if (rand() % 50 == 0)
+ {
+ mXInc[n] = 0;
+ while (mXInc[n] == 0)
+ mXInc[n] = rand() % 7 - 3;
+
+ mYInc[n] = 0;
+ while (mYInc[n] == 0)
+ mYInc[n] = rand() % 9 - 4;
+ };
+
+ if (mXpos[n] + mXInc[n] < 0 || mXpos[n] + mXInc[n] >= mWidth - mBlockSize[n])
+ mXInc[n] = -mXInc[n];
+
+ if (mYpos[n] + mYInc[n] < 0 || mYpos[n] + mYInc[n] >= mHeight - mBlockSize[n])
+ mYInc[n] = -mYInc[n];
+
+ mXpos[n] += mXInc[n];
+ mYpos[n] += mYInc[n];
+
+ for (int y = 0; y < mBlockSize[n]; ++y)
+ {
+ for (int x = 0; x < mBlockSize[n]; ++x)
+ {
+ mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 0] = mColorR[n];
+ mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 1] = mColorG[n];
+ mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 2] = mColorB[n];
+ };
+ };
+ };
+
+ setDirty(0, 0, mWidth, mHeight);
};
////////////////////////////////////////////////////////////////////////////////
//
bool mediaPluginExample::init()
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", "Example Plugin");
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", "Example Plugin");
+ sendMessage(message);
- return true;
+ return true;
};
////////////////////////////////////////////////////////////////////////////////
//
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
- void* host_user_data,
- LLPluginInstance::sendMessageFunction *plugin_send_func,
- void **plugin_user_data)
+ void* host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data)
{
- mediaPluginExample* self = new mediaPluginExample(host_send_func, host_user_data);
- *plugin_send_func = mediaPluginExample::staticReceiveMessage;
- *plugin_user_data = (void*)self;
+ mediaPluginExample* self = new mediaPluginExample(host_send_func, host_user_data);
+ *plugin_send_func = mediaPluginExample::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
- return 0;
+ return 0;
}
diff --git a/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h
index 6bc272c009..cae11a5cb3 100644
--- a/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h
+++ b/indra/media_plugins/gstreamer10/llmediaimplgstreamer.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file llmediaimplgstreamer.h
* @author Tofu Linden
* @brief implementation that supports media playback via GStreamer.
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2007&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$
* @endcond
@@ -44,8 +44,8 @@ extern "C" {
extern "C" {
gboolean llmediaimplgstreamer_bus_callback (GstBus *bus,
- GstMessage *message,
- gpointer data);
+ GstMessage *message,
+ gpointer data);
}
#endif // LL_GSTREAMER010_ENABLED
diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
index 89144922cc..a5d8f885fd 100644
--- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
+++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp
@@ -50,53 +50,53 @@ typedef SSIZE_T ssize_t;
////////////////////////////////////////////////////////////////////////////////
//
class MediaPluginLibVLC :
- public MediaPluginBase
+ public MediaPluginBase
{
public:
- MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
- ~MediaPluginLibVLC();
+ MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+ ~MediaPluginLibVLC();
- /*virtual*/ void receiveMessage(const char* message_string);
+ /*virtual*/ void receiveMessage(const char* message_string);
private:
- bool init();
+ bool init();
- void initVLC();
- void playMedia();
- void resetVLC();
- void setVolume(const F64 volume);
- void setVolumeVLC();
- void updateTitle(const char* title);
+ void initVLC();
+ void playMedia();
+ void resetVLC();
+ void setVolume(const F64 volume);
+ void setVolumeVLC();
+ void updateTitle(const char* title);
- static void* lock(void* data, void** p_pixels);
- static void unlock(void* data, void* id, void* const* raw_pixels);
- static void display(void* data, void* id);
+ static void* lock(void* data, void** p_pixels);
+ static void unlock(void* data, void* id, void* const* raw_pixels);
+ static void display(void* data, void* id);
- /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
+ /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */;
void setDurationDirty();
- static void eventCallbacks(const libvlc_event_t* event, void* ptr);
+ static void eventCallbacks(const libvlc_event_t* event, void* ptr);
- libvlc_instance_t* mLibVLC;
- libvlc_media_t* mLibVLCMedia;
- libvlc_media_player_t* mLibVLCMediaPlayer;
+ libvlc_instance_t* mLibVLC;
+ libvlc_media_t* mLibVLCMedia;
+ libvlc_media_player_t* mLibVLCMediaPlayer;
- struct mLibVLCContext
- {
- unsigned char* texture_pixels;
- libvlc_media_player_t* mp;
- MediaPluginLibVLC* parent;
- };
- struct mLibVLCContext mLibVLCCallbackContext;
+ struct mLibVLCContext
+ {
+ unsigned char* texture_pixels;
+ libvlc_media_player_t* mp;
+ MediaPluginLibVLC* parent;
+ };
+ struct mLibVLCContext mLibVLCCallbackContext;
- std::string mURL;
- F64 mCurVolume;
+ std::string mURL;
+ F64 mCurVolume;
- bool mIsLooping;
+ bool mIsLooping;
- F64 mCurTime;
- F64 mDuration;
- EStatus mVlcStatus;
+ F64 mCurTime;
+ F64 mDuration;
+ EStatus mVlcStatus;
};
////////////////////////////////////////////////////////////////////////////////
@@ -104,28 +104,28 @@ private:
MediaPluginLibVLC::MediaPluginLibVLC(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
MediaPluginBase(host_send_func, host_user_data)
{
- mTextureWidth = 0;
- mTextureHeight = 0;
- mWidth = 0;
- mHeight = 0;
- mDepth = 4;
- mPixels = 0;
+ mTextureWidth = 0;
+ mTextureHeight = 0;
+ mWidth = 0;
+ mHeight = 0;
+ mDepth = 4;
+ mPixels = 0;
- mLibVLC = 0;
- mLibVLCMedia = 0;
- mLibVLCMediaPlayer = 0;
+ mLibVLC = 0;
+ mLibVLCMedia = 0;
+ mLibVLCMediaPlayer = 0;
- mCurVolume = 0.0;
+ mCurVolume = 0.0;
- mIsLooping = false;
+ mIsLooping = false;
- mCurTime = 0.0;
- mDuration = 0.0;
+ mCurTime = 0.0;
+ mDuration = 0.0;
- mURL = std::string();
+ mURL = std::string();
- mVlcStatus = STATUS_NONE;
- setStatus(STATUS_NONE);
+ mVlcStatus = STATUS_NONE;
+ setStatus(STATUS_NONE);
}
////////////////////////////////////////////////////////////////////////////////
@@ -138,80 +138,80 @@ MediaPluginLibVLC::~MediaPluginLibVLC()
//
void* MediaPluginLibVLC::lock(void* data, void** p_pixels)
{
- struct mLibVLCContext* context = (mLibVLCContext*)data;
+ struct mLibVLCContext* context = (mLibVLCContext*)data;
- *p_pixels = context->texture_pixels;
+ *p_pixels = context->texture_pixels;
- return NULL;
+ return NULL;
}
/////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::unlock(void* data, void* id, void* const* raw_pixels)
{
- // nothing to do here for the moment
- // we *could* modify pixels here to, for example, Y flip, but this is done with
- // a VLC video filter transform.
+ // nothing to do here for the moment
+ // we *could* modify pixels here to, for example, Y flip, but this is done with
+ // a VLC video filter transform.
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::display(void* data, void* id)
{
- struct mLibVLCContext* context = (mLibVLCContext*)data;
+ struct mLibVLCContext* context = (mLibVLCContext*)data;
- context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight);
+ context->parent->setDirty(0, 0, context->parent->mWidth, context->parent->mHeight);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::initVLC()
{
- char const* vlc_argv[] =
- {
- "--no-xlib",
- "--video-filter=transform{type=vflip}", // MAINT-6578 Y flip textures in plugin vs client
- };
+ char const* vlc_argv[] =
+ {
+ "--no-xlib",
+ "--video-filter=transform{type=vflip}", // MAINT-6578 Y flip textures in plugin vs client
+ };
#if LL_DARWIN
- setenv("VLC_PLUGIN_PATH", ".", 1);
+ setenv("VLC_PLUGIN_PATH", ".", 1);
#endif
- int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
- mLibVLC = libvlc_new(vlc_argc, vlc_argv);
+ int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
+ mLibVLC = libvlc_new(vlc_argc, vlc_argv);
- if (!mLibVLC)
- {
- // for the moment, if this fails, the plugin will fail and
- // the media sub-system will tell the viewer something went wrong.
- }
+ if (!mLibVLC)
+ {
+ // for the moment, if this fails, the plugin will fail and
+ // the media sub-system will tell the viewer something went wrong.
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::resetVLC()
{
- libvlc_media_player_stop(mLibVLCMediaPlayer);
- libvlc_media_player_release(mLibVLCMediaPlayer);
- libvlc_release(mLibVLC);
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ libvlc_media_player_release(mLibVLCMediaPlayer);
+ libvlc_release(mLibVLC);
}
////////////////////////////////////////////////////////////////////////////////
// *virtual*
void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated");
- message.setValueS32("left", left);
- message.setValueS32("top", top);
- message.setValueS32("right", right);
- message.setValueS32("bottom", bottom);
+ message.setValueS32("left", left);
+ message.setValueS32("top", top);
+ message.setValueS32("right", right);
+ message.setValueS32("bottom", bottom);
- message.setValueReal("current_time", mCurTime);
- message.setValueReal("duration", mDuration);
- message.setValueReal("current_rate", 1.0f);
+ message.setValueReal("current_time", mCurTime);
+ message.setValueReal("duration", mDuration);
+ message.setValueReal("current_rate", 1.0f);
- sendMessage(message);
+ sendMessage(message);
}
////////////////////////////////////////////////////////////////////////////////
@@ -231,363 +231,363 @@ void MediaPluginLibVLC::setDurationDirty()
//
void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr)
{
- MediaPluginLibVLC* parent = (MediaPluginLibVLC*)ptr;
- if (parent == 0)
- {
- return;
- }
-
- switch (event->type)
- {
- case libvlc_MediaPlayerOpening:
- parent->mVlcStatus = STATUS_LOADING;
- break;
-
- case libvlc_MediaPlayerPlaying:
- parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
- parent->mVlcStatus = STATUS_PLAYING;
- parent->setVolumeVLC();
+ MediaPluginLibVLC* parent = (MediaPluginLibVLC*)ptr;
+ if (parent == 0)
+ {
+ return;
+ }
+
+ switch (event->type)
+ {
+ case libvlc_MediaPlayerOpening:
+ parent->mVlcStatus = STATUS_LOADING;
+ break;
+
+ case libvlc_MediaPlayerPlaying:
+ parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f;
+ parent->mVlcStatus = STATUS_PLAYING;
+ parent->setVolumeVLC();
parent->setDurationDirty();
- break;
+ break;
- case libvlc_MediaPlayerPaused:
- parent->mVlcStatus = STATUS_PAUSED;
- break;
+ case libvlc_MediaPlayerPaused:
+ parent->mVlcStatus = STATUS_PAUSED;
+ break;
- case libvlc_MediaPlayerStopped:
- parent->mVlcStatus = STATUS_DONE;
- break;
+ case libvlc_MediaPlayerStopped:
+ parent->mVlcStatus = STATUS_DONE;
+ break;
- case libvlc_MediaPlayerEndReached:
- parent->mVlcStatus = STATUS_DONE;
+ case libvlc_MediaPlayerEndReached:
+ parent->mVlcStatus = STATUS_DONE;
parent->mCurTime = parent->mDuration;
parent->setDurationDirty();
- break;
+ break;
- case libvlc_MediaPlayerEncounteredError:
- parent->mVlcStatus = STATUS_ERROR;
- break;
+ case libvlc_MediaPlayerEncounteredError:
+ parent->mVlcStatus = STATUS_ERROR;
+ break;
- case libvlc_MediaPlayerTimeChanged:
- parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
+ case libvlc_MediaPlayerTimeChanged:
+ parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f;
if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer))
{
parent->mVlcStatus = STATUS_PLAYING;
}
parent->setDurationDirty();
- break;
+ break;
- case libvlc_MediaPlayerPositionChanged:
- break;
+ case libvlc_MediaPlayerPositionChanged:
+ break;
- case libvlc_MediaPlayerLengthChanged:
- parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
+ case libvlc_MediaPlayerLengthChanged:
+ parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f;
parent->setDurationDirty();
- break;
-
- case libvlc_MediaPlayerTitleChanged:
- {
- char* title = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_Title);
- if (title)
- {
- parent->updateTitle(title);
- }
- }
- break;
- }
+ break;
+
+ case libvlc_MediaPlayerTitleChanged:
+ {
+ char* title = libvlc_media_get_meta(parent->mLibVLCMedia, libvlc_meta_Title);
+ if (title)
+ {
+ parent->updateTitle(title);
+ }
+ }
+ break;
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::playMedia()
{
- if (mURL.length() == 0)
- {
- return;
- }
-
- // A new call to play the media is received after the initial one. Typically
- // this is due to a size change request either as the media naturally resizes
- // to the size of the prim container, or else, as a 2D window is resized by the
- // user. Stopping the media, helps avoid a race condition where the media pixel
- // buffer size is out of sync with the declared size (width/height) for a frame
- // or two and the plugin crashes as VLC tries to decode a frame into unallocated
- // memory.
- if (mLibVLCMediaPlayer)
- {
- libvlc_media_player_stop(mLibVLCMediaPlayer);
- }
-
- mLibVLCMedia = libvlc_media_new_location(mLibVLC, mURL.c_str());
- if (!mLibVLCMedia)
- {
- mLibVLCMediaPlayer = 0;
- setStatus(STATUS_ERROR);
- return;
- }
-
- mLibVLCMediaPlayer = libvlc_media_player_new_from_media(mLibVLCMedia);
- if (!mLibVLCMediaPlayer)
- {
- setStatus(STATUS_ERROR);
- return;
- }
-
- // listen to events
- libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer);
- if (em)
- {
- libvlc_event_attach(em, libvlc_MediaPlayerOpening, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerPlaying, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerPaused, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerStopped, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerEndReached, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, this);
- libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, this);
- }
-
- libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext);
- libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth);
-
- mLibVLCCallbackContext.parent = this;
- mLibVLCCallbackContext.texture_pixels = mPixels;
- mLibVLCCallbackContext.mp = mLibVLCMediaPlayer;
-
- // Send a "navigate begin" event.
- // This is really a browser message but the QuickTime plugin did it and
- // the media system relies on this message to update internal state so we must send it too
- // Note: see "navigate_complete" message below too
- // https://jira.secondlife.com/browse/MAINT-6528
- LLPluginMessage message_begin(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
- message_begin.setValue("uri", mURL);
- message_begin.setValueBoolean("history_back_available", false);
- message_begin.setValueBoolean("history_forward_available", false);
- sendMessage(message_begin);
-
- // volume level gets set before VLC is initialized (thanks media system) so we have to record
- // it in mCurVolume and set it again here so that volume levels are correctly initialized
- setVolume(mCurVolume);
-
- setStatus(STATUS_LOADED);
-
- // note this relies on the "set_loop" message arriving before the "start" (play) one
- // but that appears to always be the case
- if (mIsLooping)
- {
- libvlc_media_add_option(mLibVLCMedia, "input-repeat=65535");
- }
-
- libvlc_media_player_play(mLibVLCMediaPlayer);
-
- // send a "location_changed" message - this informs the media system
- // that a new URL is the 'current' one and is used extensively.
- // Again, this is really a browser message but we will use it here.
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
- message.setValue("uri", mURL);
- sendMessage(message);
-
- // Send a "navigate complete" event.
- // This is really a browser message but the QuickTime plugin did it and
- // the media system relies on this message to update internal state so we must send it too
- // Note: see "navigate_begin" message above too
- // https://jira.secondlife.com/browse/MAINT-6528
- LLPluginMessage message_complete(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
- message_complete.setValue("uri", mURL);
- message_complete.setValueS32("result_code", 200);
- message_complete.setValue("result_string", "OK");
- sendMessage(message_complete);
+ if (mURL.length() == 0)
+ {
+ return;
+ }
+
+ // A new call to play the media is received after the initial one. Typically
+ // this is due to a size change request either as the media naturally resizes
+ // to the size of the prim container, or else, as a 2D window is resized by the
+ // user. Stopping the media, helps avoid a race condition where the media pixel
+ // buffer size is out of sync with the declared size (width/height) for a frame
+ // or two and the plugin crashes as VLC tries to decode a frame into unallocated
+ // memory.
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ }
+
+ mLibVLCMedia = libvlc_media_new_location(mLibVLC, mURL.c_str());
+ if (!mLibVLCMedia)
+ {
+ mLibVLCMediaPlayer = 0;
+ setStatus(STATUS_ERROR);
+ return;
+ }
+
+ mLibVLCMediaPlayer = libvlc_media_player_new_from_media(mLibVLCMedia);
+ if (!mLibVLCMediaPlayer)
+ {
+ setStatus(STATUS_ERROR);
+ return;
+ }
+
+ // listen to events
+ libvlc_event_manager_t* em = libvlc_media_player_event_manager(mLibVLCMediaPlayer);
+ if (em)
+ {
+ libvlc_event_attach(em, libvlc_MediaPlayerOpening, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerPlaying, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerPaused, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerStopped, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerEndReached, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerEncounteredError, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, eventCallbacks, this);
+ libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, eventCallbacks, this);
+ }
+
+ libvlc_video_set_callbacks(mLibVLCMediaPlayer, lock, unlock, display, &mLibVLCCallbackContext);
+ libvlc_video_set_format(mLibVLCMediaPlayer, "RV32", mWidth, mHeight, mWidth * mDepth);
+
+ mLibVLCCallbackContext.parent = this;
+ mLibVLCCallbackContext.texture_pixels = mPixels;
+ mLibVLCCallbackContext.mp = mLibVLCMediaPlayer;
+
+ // Send a "navigate begin" event.
+ // This is really a browser message but the QuickTime plugin did it and
+ // the media system relies on this message to update internal state so we must send it too
+ // Note: see "navigate_complete" message below too
+ // https://jira.secondlife.com/browse/MAINT-6528
+ LLPluginMessage message_begin(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
+ message_begin.setValue("uri", mURL);
+ message_begin.setValueBoolean("history_back_available", false);
+ message_begin.setValueBoolean("history_forward_available", false);
+ sendMessage(message_begin);
+
+ // volume level gets set before VLC is initialized (thanks media system) so we have to record
+ // it in mCurVolume and set it again here so that volume levels are correctly initialized
+ setVolume(mCurVolume);
+
+ setStatus(STATUS_LOADED);
+
+ // note this relies on the "set_loop" message arriving before the "start" (play) one
+ // but that appears to always be the case
+ if (mIsLooping)
+ {
+ libvlc_media_add_option(mLibVLCMedia, "input-repeat=65535");
+ }
+
+ libvlc_media_player_play(mLibVLCMediaPlayer);
+
+ // send a "location_changed" message - this informs the media system
+ // that a new URL is the 'current' one and is used extensively.
+ // Again, this is really a browser message but we will use it here.
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed");
+ message.setValue("uri", mURL);
+ sendMessage(message);
+
+ // Send a "navigate complete" event.
+ // This is really a browser message but the QuickTime plugin did it and
+ // the media system relies on this message to update internal state so we must send it too
+ // Note: see "navigate_begin" message above too
+ // https://jira.secondlife.com/browse/MAINT-6528
+ LLPluginMessage message_complete(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete");
+ message_complete.setValue("uri", mURL);
+ message_complete.setValueS32("result_code", 200);
+ message_complete.setValue("result_string", "OK");
+ sendMessage(message_complete);
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::updateTitle(const char* title)
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", title);
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", title);
+ sendMessage(message);
}
void MediaPluginLibVLC::setVolumeVLC()
{
- if (mLibVLCMediaPlayer)
- {
- int vlc_vol = (int)(mCurVolume * 100);
-
- int result = libvlc_audio_set_volume(mLibVLCMediaPlayer, vlc_vol);
- if (result == 0)
- {
- // volume change was accepted by LibVLC
- }
- else
- {
- // volume change was NOT accepted by LibVLC and not actioned
- }
+ if (mLibVLCMediaPlayer)
+ {
+ int vlc_vol = (int)(mCurVolume * 100);
+
+ int result = libvlc_audio_set_volume(mLibVLCMediaPlayer, vlc_vol);
+ if (result == 0)
+ {
+ // volume change was accepted by LibVLC
+ }
+ else
+ {
+ // volume change was NOT accepted by LibVLC and not actioned
+ }
#if LL_WINDOWS
- // https ://jira.secondlife.com/browse/MAINT-8119
- // CEF media plugin uses code in media_plugins/cef/windows_volume_catcher.cpp to
- // set the actual output volume of the plugin process since there is no API in
- // CEF to otherwise do this.
- // There are explicit calls to change the volume in LibVLC but sometimes they
- // are ignored SLPlugin.exe process volume is set to 0 so you never heard audio
- // from the VLC media stream.
- // The right way to solve this is to move the volume catcher stuff out of
- // the CEF plugin and into it's own folder under media_plugins and have it referenced
- // by both CEF and VLC. That's for later. The code there boils down to this so for
+ // https ://jira.secondlife.com/browse/MAINT-8119
+ // CEF media plugin uses code in media_plugins/cef/windows_volume_catcher.cpp to
+ // set the actual output volume of the plugin process since there is no API in
+ // CEF to otherwise do this.
+ // There are explicit calls to change the volume in LibVLC but sometimes they
+ // are ignored SLPlugin.exe process volume is set to 0 so you never heard audio
+ // from the VLC media stream.
+ // The right way to solve this is to move the volume catcher stuff out of
+ // the CEF plugin and into it's own folder under media_plugins and have it referenced
+ // by both CEF and VLC. That's for later. The code there boils down to this so for
// now, as we approach a release, the less risky option is to do it directly vs
// calls to volume catcher code.
- DWORD left_channel = (DWORD)(mCurVolume * 65535.0f);
- DWORD right_channel = (DWORD)(mCurVolume * 65535.0f);
- DWORD hw_volume = left_channel << 16 | right_channel;
- waveOutSetVolume(NULL, hw_volume);
+ DWORD left_channel = (DWORD)(mCurVolume * 65535.0f);
+ DWORD right_channel = (DWORD)(mCurVolume * 65535.0f);
+ DWORD hw_volume = left_channel << 16 | right_channel;
+ waveOutSetVolume(NULL, hw_volume);
#endif
- }
- else
- {
- // volume change was requested but VLC wasn't ready.
- // that's okay though because we saved the value in mCurVolume and
- // the next volume change after the VLC system is initilzied will set it
- }
+ }
+ else
+ {
+ // volume change was requested but VLC wasn't ready.
+ // that's okay though because we saved the value in mCurVolume and
+ // the next volume change after the VLC system is initilzied will set it
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::setVolume(const F64 volume)
{
- mCurVolume = volume;
+ mCurVolume = volume;
- setVolumeVLC();
+ setVolumeVLC();
}
////////////////////////////////////////////////////////////////////////////////
//
void MediaPluginLibVLC::receiveMessage(const char* message_string)
{
- LLPluginMessage message_in;
-
- if (message_in.parse(message_string) >= 0)
- {
- std::string message_class = message_in.getClass();
- std::string message_name = message_in.getName();
- if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
- {
- if (message_name == "init")
- {
- initVLC();
-
- LLPluginMessage message("base", "init_response");
- LLSD versions = LLSD::emptyMap();
- versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
- versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
- message.setValueLLSD("versions", versions);
-
- std::ostringstream s;
- s << "LibVLC plugin ";
- s << LIBVLC_VERSION_MAJOR;
- s << ".";
- s << LIBVLC_VERSION_MINOR;
- s << ".";
- s << LIBVLC_VERSION_REVISION;
-
- message.setValue("plugin_version", s.str());
- sendMessage(message);
- }
- else if (message_name == "idle")
- {
- setStatus(mVlcStatus);
- }
- else if (message_name == "cleanup")
- {
- resetVLC();
- }
- else if (message_name == "force_exit")
- {
- mDeleteMe = true;
- }
- else if (message_name == "shm_added")
- {
- SharedSegmentInfo info;
- info.mAddress = message_in.getValuePointer("address");
- info.mSize = (size_t)message_in.getValueS32("size");
- std::string name = message_in.getValue("name");
-
- mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
- }
- else if (message_name == "shm_remove")
- {
- std::string name = message_in.getValue("name");
-
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- if (mPixels == iter->second.mAddress)
- {
- libvlc_media_player_stop(mLibVLCMediaPlayer);
- libvlc_media_player_release(mLibVLCMediaPlayer);
- mLibVLCMediaPlayer = 0;
-
- mPixels = NULL;
- mTextureSegmentName.clear();
- }
- mSharedSegments.erase(iter);
- }
- else
- {
- //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
- }
-
- // Send the response so it can be cleaned up.
- LLPluginMessage message("base", "shm_remove_response");
- message.setValue("name", name);
- sendMessage(message);
- }
- else
- {
- //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
- }
- }
- else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
- {
- if (message_name == "init")
- {
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
- message.setValueS32("default_width", 1024);
- message.setValueS32("default_height", 1024);
- message.setValueS32("depth", mDepth);
- message.setValueU32("internalformat", GL_RGB);
- message.setValueU32("format", GL_BGRA_EXT);
- message.setValueU32("type", GL_UNSIGNED_BYTE);
- message.setValueBoolean("coords_opengl", true);
- sendMessage(message);
- }
- else if (message_name == "size_change")
- {
- std::string name = message_in.getValue("name");
- S32 width = message_in.getValueS32("width");
- S32 height = message_in.getValueS32("height");
- S32 texture_width = message_in.getValueS32("texture_width");
- S32 texture_height = message_in.getValueS32("texture_height");
-
- if (!name.empty())
- {
- // Find the shared memory region with this name
- SharedSegmentMap::iterator iter = mSharedSegments.find(name);
- if (iter != mSharedSegments.end())
- {
- mPixels = (unsigned char*)iter->second.mAddress;
- mWidth = width;
- mHeight = height;
- mTextureWidth = texture_width;
- mTextureHeight = texture_height;
+ LLPluginMessage message_in;
+
+ if (message_in.parse(message_string) >= 0)
+ {
+ std::string message_class = message_in.getClass();
+ std::string message_name = message_in.getName();
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+ {
+ if (message_name == "init")
+ {
+ initVLC();
+
+ LLPluginMessage message("base", "init_response");
+ LLSD versions = LLSD::emptyMap();
+ versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+ versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME] = LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME_VERSION;
+ message.setValueLLSD("versions", versions);
+
+ std::ostringstream s;
+ s << "LibVLC plugin ";
+ s << LIBVLC_VERSION_MAJOR;
+ s << ".";
+ s << LIBVLC_VERSION_MINOR;
+ s << ".";
+ s << LIBVLC_VERSION_REVISION;
+
+ message.setValue("plugin_version", s.str());
+ sendMessage(message);
+ }
+ else if (message_name == "idle")
+ {
+ setStatus(mVlcStatus);
+ }
+ else if (message_name == "cleanup")
+ {
+ resetVLC();
+ }
+ else if (message_name == "force_exit")
+ {
+ mDeleteMe = true;
+ }
+ else if (message_name == "shm_added")
+ {
+ SharedSegmentInfo info;
+ info.mAddress = message_in.getValuePointer("address");
+ info.mSize = (size_t)message_in.getValueS32("size");
+ std::string name = message_in.getValue("name");
+
+ mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+ }
+ else if (message_name == "shm_remove")
+ {
+ std::string name = message_in.getValue("name");
+
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ if (mPixels == iter->second.mAddress)
+ {
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ libvlc_media_player_release(mLibVLCMediaPlayer);
+ mLibVLCMediaPlayer = 0;
+
+ mPixels = NULL;
+ mTextureSegmentName.clear();
+ }
+ mSharedSegments.erase(iter);
+ }
+ else
+ {
+ //std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+ }
+
+ // Send the response so it can be cleaned up.
+ LLPluginMessage message("base", "shm_remove_response");
+ message.setValue("name", name);
+ sendMessage(message);
+ }
+ else
+ {
+ //std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+ }
+ }
+ else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+ {
+ if (message_name == "init")
+ {
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+ message.setValueS32("default_width", 1024);
+ message.setValueS32("default_height", 1024);
+ message.setValueS32("depth", mDepth);
+ message.setValueU32("internalformat", GL_RGB);
+ message.setValueU32("format", GL_BGRA_EXT);
+ message.setValueU32("type", GL_UNSIGNED_BYTE);
+ message.setValueBoolean("coords_opengl", true);
+ sendMessage(message);
+ }
+ else if (message_name == "size_change")
+ {
+ std::string name = message_in.getValue("name");
+ S32 width = message_in.getValueS32("width");
+ S32 height = message_in.getValueS32("height");
+ S32 texture_width = message_in.getValueS32("texture_width");
+ S32 texture_height = message_in.getValueS32("texture_height");
+
+ if (!name.empty())
+ {
+ // Find the shared memory region with this name
+ SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+ if (iter != mSharedSegments.end())
+ {
+ mPixels = (unsigned char*)iter->second.mAddress;
+ mWidth = width;
+ mHeight = height;
+ mTextureWidth = texture_width;
+ mTextureHeight = texture_height;
libvlc_time_t time = 1000.0 * mCurTime;
- playMedia();
+ playMedia();
if (mLibVLCMediaPlayer)
{
@@ -603,37 +603,37 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
mCurTime = (F64)time / 1000.0;
}
}
- };
- };
-
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
- message.setValue("name", name);
- message.setValueS32("width", width);
- message.setValueS32("height", height);
- message.setValueS32("texture_width", texture_width);
- message.setValueS32("texture_height", texture_height);
- sendMessage(message);
- }
- else if (message_name == "load_uri")
- {
- mURL = message_in.getValue("uri");
- playMedia();
- }
- }
- else
- if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
- {
- if (message_name == "stop")
- {
- if (mLibVLCMediaPlayer)
- {
- libvlc_media_player_stop(mLibVLCMediaPlayer);
- }
- }
- else if (message_name == "start")
- {
- if (mLibVLCMediaPlayer)
- {
+ };
+ };
+
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+ message.setValue("name", name);
+ message.setValueS32("width", width);
+ message.setValueS32("height", height);
+ message.setValueS32("texture_width", texture_width);
+ message.setValueS32("texture_height", texture_height);
+ sendMessage(message);
+ }
+ else if (message_name == "load_uri")
+ {
+ mURL = message_in.getValue("uri");
+ playMedia();
+ }
+ }
+ else
+ if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
+ {
+ if (message_name == "stop")
+ {
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_media_player_stop(mLibVLCMediaPlayer);
+ }
+ }
+ else if (message_name == "start")
+ {
+ if (mLibVLCMediaPlayer)
+ {
if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer))
{
// stop or vlc will ignore 'play', it will just
@@ -641,18 +641,18 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
// seek was used
libvlc_media_player_stop(mLibVLCMediaPlayer);
}
- libvlc_media_player_play(mLibVLCMediaPlayer);
- }
- }
- else if (message_name == "pause")
- {
- if (mLibVLCMediaPlayer)
- {
- libvlc_media_player_set_pause(mLibVLCMediaPlayer, 1);
- }
- }
- else if (message_name == "seek")
- {
+ libvlc_media_player_play(mLibVLCMediaPlayer);
+ }
+ }
+ else if (message_name == "pause")
+ {
+ if (mLibVLCMediaPlayer)
+ {
+ libvlc_media_player_set_pause(mLibVLCMediaPlayer, 1);
+ }
+ }
+ else if (message_name == "seek")
+ {
if (mLibVLCMediaPlayer)
{
libvlc_time_t time = 1000.0 * message_in.getValueReal("time");
@@ -674,43 +674,43 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string)
setDurationDirty();
}
}
- }
- else if (message_name == "set_loop")
- {
- bool loop = message_in.getValueBoolean("loop");
- mIsLooping = loop;
- }
- else if (message_name == "set_volume")
- {
- // volume comes in 0 -> 1.0
- F64 volume = message_in.getValueReal("volume");
- setVolume(volume);
- }
- }
- }
+ }
+ else if (message_name == "set_loop")
+ {
+ bool loop = message_in.getValueBoolean("loop");
+ mIsLooping = loop;
+ }
+ else if (message_name == "set_volume")
+ {
+ // volume comes in 0 -> 1.0
+ F64 volume = message_in.getValueReal("volume");
+ setVolume(volume);
+ }
+ }
+ }
}
////////////////////////////////////////////////////////////////////////////////
//
bool MediaPluginLibVLC::init()
{
- LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
- message.setValue("name", "LibVLC Plugin");
- sendMessage(message);
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+ message.setValue("name", "LibVLC Plugin");
+ sendMessage(message);
- return true;
+ return true;
};
////////////////////////////////////////////////////////////////////////////////
//
int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
- void* host_user_data,
- LLPluginInstance::sendMessageFunction *plugin_send_func,
- void **plugin_user_data)
+ void* host_user_data,
+ LLPluginInstance::sendMessageFunction *plugin_send_func,
+ void **plugin_user_data)
{
- MediaPluginLibVLC* self = new MediaPluginLibVLC(host_send_func, host_user_data);
- *plugin_send_func = MediaPluginLibVLC::staticReceiveMessage;
- *plugin_user_data = (void*)self;
+ MediaPluginLibVLC* self = new MediaPluginLibVLC(host_send_func, host_user_data);
+ *plugin_send_func = MediaPluginLibVLC::staticReceiveMessage;
+ *plugin_user_data = (void*)self;
- return 0;
+ return 0;
}