From cb7f84a470d7afeb1501cf5514333c6ee15d96df Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 2 Oct 2015 11:14:28 -0700 Subject: MAINT-5687: Remove old webkit from the make files and the repo. Ensure that it is no longer meaningfully referenced. --- indra/CMakeLists.txt | 7 - indra/cmake/CMakeLists.txt | 1 - indra/cmake/WebKitLibPlugin.cmake | 93 - indra/llplugin/CMakeLists.txt | 1 - indra/media_plugins/webkit/CMakeLists.txt | 132 -- .../media_plugins/webkit/dummy_volume_catcher.cpp | 58 - .../media_plugins/webkit/linux_volume_catcher.cpp | 468 ---- .../webkit/linux_volume_catcher_pa_syms.inc | 21 - .../webkit/linux_volume_catcher_paglib_syms.inc | 6 - indra/media_plugins/webkit/mac_volume_catcher.cpp | 275 --- indra/media_plugins/webkit/media_plugin_webkit.cpp | 1481 ------------ indra/media_plugins/webkit/volume_catcher.h | 54 - .../webkit/windows_volume_catcher.cpp | 147 -- indra/media_plugins/winmmshim/CMakeLists.txt | 3 - indra/newview/CMakeLists.txt | 4 - indra/newview/llappviewer.cpp | 6 + indra/newview/viewer_manifest.py | 2 - indra/test_apps/llfbconnecttest/CMakeLists.txt | 372 --- indra/test_apps/llfbconnecttest/README.Linden | 20 - indra/test_apps/llfbconnecttest/bookmarks.txt | 4 - .../test_apps/llfbconnecttest/llfbconnecttest.cpp | 2394 -------------------- indra/test_apps/llfbconnecttest/llfbconnecttest.h | 173 -- indra/test_apps/llplugintest/CMakeLists.txt | 138 -- indra/test_apps/llplugintest/llmediaplugintest.cpp | 2377 ------------------- indra/test_apps/llplugintest/llmediaplugintest.h | 207 -- 25 files changed, 6 insertions(+), 8438 deletions(-) delete mode 100755 indra/cmake/WebKitLibPlugin.cmake delete mode 100755 indra/media_plugins/webkit/CMakeLists.txt delete mode 100755 indra/media_plugins/webkit/dummy_volume_catcher.cpp delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher.cpp delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc delete mode 100755 indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc delete mode 100755 indra/media_plugins/webkit/mac_volume_catcher.cpp delete mode 100755 indra/media_plugins/webkit/media_plugin_webkit.cpp delete mode 100755 indra/media_plugins/webkit/volume_catcher.h delete mode 100755 indra/media_plugins/webkit/windows_volume_catcher.cpp delete mode 100644 indra/test_apps/llfbconnecttest/CMakeLists.txt delete mode 100644 indra/test_apps/llfbconnecttest/README.Linden delete mode 100644 indra/test_apps/llfbconnecttest/bookmarks.txt delete mode 100644 indra/test_apps/llfbconnecttest/llfbconnecttest.cpp delete mode 100644 indra/test_apps/llfbconnecttest/llfbconnecttest.h delete mode 100755 indra/test_apps/llplugintest/llmediaplugintest.cpp delete mode 100755 indra/test_apps/llplugintest/llmediaplugintest.h diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 2d45bc938e..133c5ee265 100755 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -57,13 +57,6 @@ add_subdirectory(${VIEWER_PREFIX}test) if (ENABLE_MEDIA_PLUGINS) # viewer media plugins add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) - - # llplugin testbed code (is this the right way to include it?) - if (LL_TESTS AND NOT LINUX) - #removed during webkit -> cef update - #add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) - #add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest) - endif (LL_TESTS AND NOT LINUX) endif (ENABLE_MEDIA_PLUGINS) if (LINUX) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 2298b0f284..4dd69649d0 100755 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -103,7 +103,6 @@ set(cmake_SOURCE_FILES Variables.cmake ViewerMiscLibs.cmake VisualLeakDetector.cmake -## WebKitLibPlugin.cmake XmlRpcEpi.cmake ZLIB.cmake ) diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake deleted file mode 100755 index f7c548a2fd..0000000000 --- a/indra/cmake/WebKitLibPlugin.cmake +++ /dev/null @@ -1,93 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) -include(OpenSSL) - -if (USESYSTEMLIBS) - # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny. - find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED) - include(${QT_USE_FILE}) - set(QTDIR $ENV{QTDIR}) - if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") - message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; " - "Qt is found by looking for qmake in your PATH. " - "Please set your PATH such that 'qmake' is found in \$QTDIR/bin, " - "or unset QTDIR if the found Qt is correct.") - endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin") - find_package(LLQtWebkit REQUIRED QUIET) - # Add the plugins. - set(QT_PLUGIN_LIBRARIES) - foreach(qlibname qgif qjpeg) - find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH) - if (QT_PLUGIN_${qlibname}) - list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}}) - else (QT_PLUGIN_${qtlibname}) - message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!") - endif (QT_PLUGIN_${qlibname}) - endforeach(qlibname) - # qjpeg depends on libjpeg - list(APPEND QT_PLUGIN_LIBRARIES jpeg) - set(WEBKITLIBPLUGIN OFF CACHE BOOL - "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") -else (USESYSTEMLIBS) - use_prebuilt_binary(llqtwebkit) - set(WEBKITLIBPLUGIN ON CACHE BOOL - "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.") -endif (USESYSTEMLIBS) - -if (WINDOWS) - set(WEBKIT_PLUGIN_LIBRARIES - debug llqtwebkitd - debug QtWebKitd4 - debug QtOpenGLd4 - debug QtNetworkd4 - debug QtGuid4 - debug QtCored4 - debug qtmaind - optimized llqtwebkit - optimized QtWebKit4 - optimized QtOpenGL4 - optimized QtNetwork4 - optimized QtGui4 - optimized QtCore4 - optimized qtmain - ) -elseif (DARWIN) - set(WEBKIT_PLUGIN_LIBRARIES - ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.a - ${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib - ${ARCH_PREBUILT_DIRS_RELEASE}/libQtOpenGL.4.dylib - ${ARCH_PREBUILT_DIRS_RELEASE}/libQtNetwork.4.dylib - ${ARCH_PREBUILT_DIRS_RELEASE}/libQtGui.4.dylib - ${ARCH_PREBUILT_DIRS_RELEASE}/libQtCore.4.dylib - ) -elseif (LINUX) - # *HUH: What does this do? - set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES}) - set(WEBKIT_PLUGIN_LIBRARIES - llqtwebkit -# qico -# qpng -# qtiff -# qsvg -# QtSvg - QtWebKit - QtOpenGL - QtNetwork - ${OPENSSL_LIBRARIES} - QtGui - QtCore -# jscore -# qgif -# qjpeg -# jpeg - fontconfig - X11 - Xrender - GL - -# sqlite3 -# Xi -# SM - ) -endif (WINDOWS) diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 75d89aac78..8c4ddd524e 100755 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -20,7 +20,6 @@ include_directories( ${LLRENDER_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} - ${LLQTWEBKIT_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt deleted file mode 100755 index 5a8fe90bdd..0000000000 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ /dev/null @@ -1,132 +0,0 @@ -# -*- cmake -*- - -project(media_plugin_webkit) - -include(00-Common) -include(LLCommon) -include(LLImage) -include(LLPlugin) -include(LLMath) -include(LLRender) -include(LLWindow) -include(UI) -include(Linking) -include(PluginAPI) -include(MediaPluginBase) -include(OpenGL) -include(PulseAudio) - -include(WebKitLibPlugin) - -include_directories( - ${PULSEAUDIO_INCLUDE_DIRS} - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLQTWEBKIT_INCLUDE_DIR} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - - -### media_plugin_webkit - -if(NOT WORD_SIZE EQUAL 32) - if(WINDOWS) - add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) -endif(NOT WORD_SIZE EQUAL 32) - -set(media_plugin_webkit_SOURCE_FILES - media_plugin_webkit.cpp - ) - -set(media_plugin_webkit_HEADER_FILES - volume_catcher.h - ) - -set(media_plugin_webkit_LINK_LIBRARIES - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${WEBKIT_PLUGIN_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} - ${PULSEAUDIO_LIBRARIES} -) - -# Select which VolumeCatcher implementation to use -if (LINUX) - if (PULSEAUDIO_FOUND) - list(APPEND media_plugin_webkit_SOURCE_FILES linux_volume_catcher.cpp) - else (PULSEAUDIO_FOUND) - list(APPEND media_plugin_webkit_SOURCE_FILES dummy_volume_catcher.cpp) - endif (PULSEAUDIO_FOUND) - list(APPEND media_plugin_webkit_LINK_LIBRARIES - ${UI_LIBRARIES} # for glib/GTK - ) -elseif (DARWIN) - list(APPEND media_plugin_webkit_SOURCE_FILES mac_volume_catcher.cpp) - find_library(CORESERVICES_LIBRARY CoreServices) - find_library(AUDIOUNIT_LIBRARY AudioUnit) - list(APPEND media_plugin_webkit_LINK_LIBRARIES - ${CORESERVICES_LIBRARY} # for Component Manager calls - ${AUDIOUNIT_LIBRARY} # for AudioUnit calls - ) -elseif (WINDOWS) - list(APPEND media_plugin_webkit_SOURCE_FILES windows_volume_catcher.cpp) -endif (LINUX) - -set_source_files_properties(${media_plugin_webkit_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND media_plugin_webkit_SOURCE_FILES ${media_plugin_webkit_HEADER_FILES}) - -add_library(media_plugin_webkit - SHARED - ${media_plugin_webkit_SOURCE_FILES} -) - -target_link_libraries(media_plugin_webkit ${media_plugin_webkit_LINK_LIBRARIES}) - -add_dependencies(media_plugin_webkit - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} -) - -if (WINDOWS) - set_target_properties( - media_plugin_webkit - PROPERTIES - LINK_FLAGS "/MANIFEST:NO" - ) -endif (WINDOWS) - -if (DARWIN) - # Don't prepend 'lib' to the executable name, and don't embed a full path in the library's install name - set_target_properties( - media_plugin_webkit - PROPERTIES - PREFIX "" - BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path" - LINK_FLAGS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/../base/media_plugin_base.exp" - ) - - # copy the webkit dylib to the build directory -# add_custom_command( -# TARGET media_plugin_webkit POST_BUILD -# # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib -# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ -# DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib -# ) - -endif (DARWIN) - diff --git a/indra/media_plugins/webkit/dummy_volume_catcher.cpp b/indra/media_plugins/webkit/dummy_volume_catcher.cpp deleted file mode 100755 index d54b31b2ae..0000000000 --- a/indra/media_plugins/webkit/dummy_volume_catcher.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file dummy_volume_catcher.cpp - * @brief A null implementation of the "VolumeCatcher" class for platforms where it's not implemented yet. - * - * @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 - */ - -#include "volume_catcher.h" - - -class VolumeCatcherImpl -{ -}; - -///////////////////////////////////////////////////// - -VolumeCatcher::VolumeCatcher() -{ - pimpl = NULL; -} - -VolumeCatcher::~VolumeCatcher() -{ -} - -void VolumeCatcher::setVolume(F32 volume) -{ -} - -void VolumeCatcher::setPan(F32 pan) -{ -} - -void VolumeCatcher::pump() -{ -} - diff --git a/indra/media_plugins/webkit/linux_volume_catcher.cpp b/indra/media_plugins/webkit/linux_volume_catcher.cpp deleted file mode 100755 index 91be3a89e9..0000000000 --- a/indra/media_plugins/webkit/linux_volume_catcher.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/** - * @file linux_volume_catcher.cpp - * @brief A Linux-specific, PulseAudio-specific hack to detect and volume-adjust new audio sources - * - * @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 - */ - -/* - The high-level design is as follows: - 1) Connect to the PulseAudio daemon - 2) Watch for the creation of new audio players connecting to the daemon (this includes ALSA clients running on the PulseAudio emulation layer, such as Flash plugins) - 3) Examine any new audio player's PID to see if it belongs to our own process - 4) If so, tell PA to adjust the volume of that audio player ('sink input' in PA parlance) - 5) Keep a list of all living audio players that we care about, adjust the volumes of all of them when we get a new setVolume() call - */ - -#include "linden_common.h" - -#include "volume_catcher.h" - - -extern "C" { -#include -#include - -#include -#include -#include -#include // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. - -#include "apr_pools.h" -#include "apr_dso.h" -} - -//////////////////////////////////////////////////// - -#define DEBUGMSG(...) do {} while(0) -#define INFOMSG(...) do {} while(0) -#define WARNMSG(...) do {} while(0) - -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) RTN (*ll##PASYM)(__VA_ARGS__) = NULL -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" -#undef LL_PA_SYM - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymPADSOMemoryPool = NULL; -static apr_dso_handle_t *sSymPADSOHandleG = NULL; - -bool grab_pa_syms(std::string pulse_dso_name) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return true; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymPADSOHandle = NULL; - -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) - - //attempt to load the shared library - apr_pool_create(&sSymPADSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, - pulse_dso_name.c_str(), - sSymPADSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); - -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" - - if ( sSymPADSOHandle ) - { - sSymPADSOHandleG = sSymPADSOHandle; - sSymPADSOHandle = NULL; - } - - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", pulse_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in PulseAudio libraries."); - } -#undef LL_PA_SYM - - sSymsGrabbed = rtn; - return rtn; -} - - -void ungrab_pa_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymPADSOHandleG ) - { - apr_dso_unload(sSymPADSOHandleG); - sSymPADSOHandleG = NULL; - } - - if ( sSymPADSOMemoryPool ) - { - apr_pool_destroy(sSymPADSOMemoryPool); - sSymPADSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) -#include "linux_volume_catcher_pa_syms.inc" -#include "linux_volume_catcher_paglib_syms.inc" -#undef LL_PA_SYM - - sSymsGrabbed = false; -} -//////////////////////////////////////////////////// - -// 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); -} - - -class VolumeCatcherImpl -{ -public: - VolumeCatcherImpl(); - ~VolumeCatcherImpl(); - - void setVolume(F32 volume); - void pump(void); - - // for internal use - can't be private because used from our C callbacks - - 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(); - - std::set mSinkInputIndices; - std::map mSinkInputNumChannels; - F32 mDesiredVolume; - pa_glib_mainloop *mMainloop; - pa_context *mPAContext; - bool mConnected; - bool mGotSyms; -}; - -VolumeCatcherImpl::VolumeCatcherImpl() - : mDesiredVolume(0.0f), - mMainloop(NULL), - mPAContext(NULL), - mConnected(false), - mGotSyms(false) -{ - init(); -} - -VolumeCatcherImpl::~VolumeCatcherImpl() -{ - cleanup(); -} - -bool VolumeCatcherImpl::loadsyms(std::string pulse_dso_name) -{ - return grab_pa_syms(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; - - // better make double-sure glib itself is initialized properly. - if (!g_thread_supported ()) g_thread_init (NULL); - g_type_init(); - - 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, NULL, 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, NULL, cflags, NULL) >= 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; - - if (mGotSyms && mPAContext) - { - llpa_context_disconnect(mPAContext); - llpa_context_unref(mPAContext); - } - mPAContext = NULL; - - if (mGotSyms && mMainloop) - { - llpa_glib_mainloop_free(mMainloop); - } - mMainloop = NULL; -} - -void VolumeCatcherImpl::setVolume(F32 volume) -{ - mDesiredVolume = volume; - - if (!mGotSyms) return; - - if (mConnected && mPAContext) - { - update_all_volumes(mDesiredVolume); - } - - pump(); -} - -void VolumeCatcherImpl::pump() -{ - 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), - NULL, NULL))) - { - llpa_operation_unref(op); - } -} - -void VolumeCatcherImpl::update_all_volumes(F32 volume) -{ - for (std::set::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 = NULL; // okay as null - void *userdata = NULL; // okay as null - - pa_operation *op; - if ((op = llpa_context_set_sink_input_volume(c, idx, cvolumep, cb, userdata))) - { - llpa_operation_unref(op); - } -} - - -void callback_discovered_sinkinput(pa_context *context, const pa_sink_input_info *sii, int eol, void *userdata) -{ - VolumeCatcherImpl *impl = dynamic_cast((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 (sinkpid == getpid()) // 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*)userdata); - llassert(impl); - - 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:; - } -} - -void callback_context_state(pa_context *context, void *userdata) -{ - VolumeCatcherImpl *impl = dynamic_cast((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(); -} - -VolumeCatcher::~VolumeCatcher() -{ - delete pimpl; - pimpl = NULL; -} - -void VolumeCatcher::setVolume(F32 volume) -{ - llassert(pimpl); - pimpl->setVolume(volume); -} - -void VolumeCatcher::setPan(F32 pan) -{ - // TODO: implement this (if possible) -} - -void VolumeCatcher::pump() -{ - llassert(pimpl); - pimpl->pump(); -} diff --git a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc deleted file mode 100755 index d806b48428..0000000000 --- a/indra/media_plugins/webkit/linux_volume_catcher_pa_syms.inc +++ /dev/null @@ -1,21 +0,0 @@ -// required symbols to grab -LL_PA_SYM(true, pa_context_connect, int, pa_context *c, const char *server, pa_context_flags_t flags, const pa_spawn_api *api); -LL_PA_SYM(true, pa_context_disconnect, void, pa_context *c); -LL_PA_SYM(true, pa_context_get_sink_input_info, pa_operation*, pa_context *c, uint32_t idx, pa_sink_input_info_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_get_sink_input_info_list, pa_operation*, pa_context *c, pa_sink_input_info_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_get_state, pa_context_state_t, pa_context *c); -LL_PA_SYM(true, pa_context_new_with_proplist, pa_context*, pa_mainloop_api *mainloop, const char *name, pa_proplist *proplist); -LL_PA_SYM(true, pa_context_set_sink_input_volume, pa_operation*, pa_context *c, uint32_t idx, const pa_cvolume *volume, pa_context_success_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_set_state_callback, void, pa_context *c, pa_context_notify_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_set_subscribe_callback, void, pa_context *c, pa_context_subscribe_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_subscribe, pa_operation*, pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata); -LL_PA_SYM(true, pa_context_unref, void, pa_context *c); -LL_PA_SYM(true, pa_cvolume_set, pa_cvolume*, pa_cvolume *a, unsigned channels, pa_volume_t v); -LL_PA_SYM(true, pa_operation_unref, void, pa_operation *o); -LL_PA_SYM(true, pa_proplist_free, void, pa_proplist* p); -LL_PA_SYM(true, pa_proplist_gets, const char*, pa_proplist *p, const char *key); -LL_PA_SYM(true, pa_proplist_new, pa_proplist*, void); -LL_PA_SYM(true, pa_proplist_sets, int, pa_proplist *p, const char *key, const char *value); -LL_PA_SYM(true, pa_sw_volume_from_linear, pa_volume_t, double v); - -// optional symbols to grab diff --git a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc b/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc deleted file mode 100755 index abf628c96c..0000000000 --- a/indra/media_plugins/webkit/linux_volume_catcher_paglib_syms.inc +++ /dev/null @@ -1,6 +0,0 @@ -// required symbols to grab -LL_PA_SYM(true, pa_glib_mainloop_free, void, pa_glib_mainloop* g); -LL_PA_SYM(true, pa_glib_mainloop_get_api, pa_mainloop_api*, pa_glib_mainloop* g); -LL_PA_SYM(true, pa_glib_mainloop_new, pa_glib_mainloop *, GMainContext *c); - -// optional symbols to grab diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp deleted file mode 100755 index 73e5bf3da3..0000000000 --- a/indra/media_plugins/webkit/mac_volume_catcher.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/** - * @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. - * - * @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 - */ - -/************************************************************************************************************** - 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" - -#include -#include -#include - -#if LL_DARWIN -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif - -struct VolumeCatcherStorage; - -class VolumeCatcherImpl -{ -public: - - void setVolume(F32 volume); - void setPan(F32 pan); - - void setInstanceVolume(VolumeCatcherStorage *instance); - - std::list 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; -}; - -VolumeCatcherImpl *VolumeCatcherImpl::sInstance = NULL;; - -struct VolumeCatcherStorage -{ - ComponentInstance self; - ComponentInstance delegate; -}; - -static ComponentResult volume_catcher_component_entry(ComponentParameters *cp, Handle componentStorage); -static ComponentResult volume_catcher_component_open(VolumeCatcherStorage *storage, ComponentInstance self); -static ComponentResult volume_catcher_component_close(VolumeCatcherStorage *storage, ComponentInstance self); - -VolumeCatcherImpl *VolumeCatcherImpl::getInstance() -{ - 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); - -} - -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; -} - -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; -} - -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; -} - -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::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... -} - -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; - } -} - -///////////////////////////////////////////////////// - -VolumeCatcher::VolumeCatcher() -{ - pimpl = VolumeCatcherImpl::getInstance(); -} - -VolumeCatcher::~VolumeCatcher() -{ - // Let the instance persist until exit. -} - -void VolumeCatcher::setVolume(F32 volume) -{ - pimpl->setVolume(volume); -} - -void VolumeCatcher::setPan(F32 pan) -{ - pimpl->setPan(pan); -} - -void VolumeCatcher::pump() -{ - // No periodic tasks are necessary for this implementation. -} - -#if LL_DARWIN -#pragma GCC diagnostic warning "-Wdeprecated-declarations" -#endif diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp deleted file mode 100755 index 3edeef51e3..0000000000 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ /dev/null @@ -1,1481 +0,0 @@ -/** - * @file media_plugin_webkit.cpp - * @brief Webkit plugin for LLMedia API plugin system - * - * @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 - */ -#include "llqtwebkit.h" -#include "linden_common.h" -#include "indra_constants.h" // for indra keyboard codes - -#include "lltimer.h" -#include "llgl.h" - -#include "llplugininstance.h" -#include "llpluginmessage.h" -#include "llpluginmessageclasses.h" -#include "media_plugin_base.h" - -// set to 1 if you're using the version of llqtwebkit that's QPixmap-ified -#if LL_LINUX -# define LL_QTWEBKIT_USES_PIXMAPS 0 -extern "C" { -# include -# include -} -#else -# define LL_QTWEBKIT_USES_PIXMAPS 0 -#endif // LL_LINUX - -# include "volume_catcher.h" - -#if LL_WINDOWS -# include -#else -# include -# include -#endif - -#if LL_WINDOWS - // *NOTE:Mani - This captures the module handle for the dll. This is used below - // to get the path to this dll for webkit initialization. - // I don't know how/if this can be done with apr... - namespace { HMODULE gModuleHandle;}; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) - { - gModuleHandle = (HMODULE) hinstDLL; - return TRUE; - } -#endif - -//////////////////////////////////////////////////////////////////////////////// -// -class MediaPluginWebKit : - public MediaPluginBase, - public LLEmbeddedBrowserWindowObserver -{ -public: - MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data); - ~MediaPluginWebKit(); - - /*virtual*/ void receiveMessage(const char *message_string); - -private: - - std::string mProfileDir; - std::string mHostLanguage; - std::string mUserAgent; - bool mCookiesEnabled; - bool mJavascriptEnabled; - bool mPluginsEnabled; - bool mEnableMediaPluginDebugging; - - enum - { - INIT_STATE_UNINITIALIZED, // LLQtWebkit hasn't been set up yet - INIT_STATE_INITIALIZED, // LLQtWebkit has been set up, but no browser window has been created yet. - INIT_STATE_NAVIGATING, // Browser instance has been set up and initial navigate to about:blank has been issued - INIT_STATE_NAVIGATE_COMPLETE, // initial navigate to about:blank has completed - INIT_STATE_WAIT_REDRAW, // First real navigate begin has been received, waiting for page changed event to start handling redraws - INIT_STATE_WAIT_COMPLETE, // Waiting for first real navigate complete event - INIT_STATE_RUNNING // All initialization gymnastics are complete. - }; - int mBrowserWindowId; - int mInitState; - std::string mInitialNavigateURL; - bool mNeedsUpdate; - - bool mCanCut; - bool mCanCopy; - bool mCanPaste; - int mLastMouseX; - int mLastMouseY; - bool mFirstFocus; - F32 mBackgroundR; - F32 mBackgroundG; - F32 mBackgroundB; - std::string mTarget; - LLTimer mElapsedTime; - - VolumeCatcher mVolumeCatcher; - - void postDebugMessage( const std::string& msg ) - { - if ( mEnableMediaPluginDebugging ) - { - std::stringstream str; - str << "@Media Msg> " << "[" << (double)mElapsedTime.getElapsedTimeF32() << "] -- " << 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 setInitState(int state) - { -// std::cerr << "changing init state to " << state << std::endl; - mInitState = state; - } - - //////////////////////////////////////////////////////////////////////////////// - // - void update(int milliseconds) - { -#if LL_QTLINUX_DOESNT_HAVE_GLIB - // pump glib generously, as Linux browser plugins are on the - // glib main loop, even if the browser itself isn't - ugh - // This is NOT NEEDED if Qt itself was built with glib - // mainloop integration. - GMainContext *mainc = g_main_context_default(); - while(g_main_context_iteration(mainc, FALSE)); -#endif // LL_QTLINUX_DOESNT_HAVE_GLIB - - // pump qt - LLQtWebKit::getInstance()->pump( milliseconds ); - - mVolumeCatcher.pump(); - - checkEditState(); - - if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) - { - if(!mInitialNavigateURL.empty()) - { - // We already have the initial navigate URL -- kick off the navigate. - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, mInitialNavigateURL ); - mInitialNavigateURL.clear(); - } - } - - if ( (mInitState > INIT_STATE_WAIT_REDRAW) && mNeedsUpdate ) - { - const unsigned char* browser_pixels = LLQtWebKit::getInstance()->grabBrowserWindow( mBrowserWindowId ); - - unsigned int rowspan = LLQtWebKit::getInstance()->getBrowserRowSpan( mBrowserWindowId ); - unsigned int height = LLQtWebKit::getInstance()->getBrowserHeight( mBrowserWindowId ); -#if !LL_QTWEBKIT_USES_PIXMAPS - unsigned int buffer_size = rowspan * height; -#endif // !LL_QTWEBKIT_USES_PIXMAPS - -// std::cerr << "webkit plugin: updating" << std::endl; - - // TODO: should get rid of this memcpy if possible - if ( mPixels && browser_pixels ) - { -// std::cerr << " memcopy of " << buffer_size << " bytes" << std::endl; - -#if LL_QTWEBKIT_USES_PIXMAPS - // copy the pixel data upside-down because of the co-ord system - for (int y=0; y 0 && mHeight > 0 ) - { -// std::cerr << "Setting dirty, " << mWidth << " x " << mHeight << std::endl; - setDirty( 0, 0, mWidth, mHeight ); - } - - mNeedsUpdate = false; - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - bool initBrowser() - { - // already initialized - if ( mInitState > INIT_STATE_UNINITIALIZED ) - return true; - - // set up directories - char cwd[ FILENAME_MAX ]; // I *think* this is defined on all platforms we use - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - LL_WARNS() << "Couldn't get cwd - probably too long - failing to init." << LL_ENDL; - return false; - } - std::string application_dir = std::string( cwd ); - -#if LL_LINUX - // take care to initialize glib properly, because some - // versions of Qt don't, and we indirectly need it for (some - // versions of) Flash to not crash the browser. - if (!g_thread_supported ()) g_thread_init (NULL); - g_type_init(); -#endif - -#if LL_DARWIN - // When running under the Xcode debugger, there's a setting called "Break on Debugger()/DebugStr()" which defaults to being turned on. - // This causes the environment variable USERBREAK to be set to 1, which causes these legacy calls to break into the debugger. - // This wouldn't cause any problems except for the fact that the current release version of the Flash plugin has a call to Debugger() in it - // which gets hit when the plugin is probed by webkit. - // Unsetting the environment variable here works around this issue. - unsetenv("USERBREAK"); -#endif - -#if LL_WINDOWS - //*NOTE:Mani - On windows, at least, the component path is the - // location of this dll's image file. - std::string component_dir; - char dll_path[_MAX_PATH]; - DWORD len = GetModuleFileNameA(gModuleHandle, (LPCH)&dll_path, _MAX_PATH); - while(len && dll_path[ len ] != ('\\') ) - { - len--; - } - if(len >= 0) - { - dll_path[len] = 0; - component_dir = dll_path; - } - else - { - // *NOTE:Mani - This case should be an rare exception. - // GetModuleFileNameA should always give you a full path, no? - component_dir = application_dir; - } -#else - std::string component_dir = application_dir; -#endif - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Component dir set to: " + component_dir ); - - // window handle - needed on Windows and must be app window. -#if LL_WINDOWS - char window_title[ MAX_PATH ]; - GetConsoleTitleA( window_title, MAX_PATH ); - void* native_window_handle = (void*)FindWindowA( NULL, window_title ); -#else - void* native_window_handle = 0; -#endif - - // main browser initialization - bool result = LLQtWebKit::getInstance()->init( application_dir, component_dir, mProfileDir, native_window_handle ); - if ( result ) - { - mInitState = INIT_STATE_INITIALIZED; - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "browser initialized okay" ); - - return true; - }; - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "browser nOT initialized." ); - - return false; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - bool initBrowserWindow() - { - // already initialized - if ( mInitState > INIT_STATE_INITIALIZED ) - return true; - - // not enough information to initialize the browser yet. - if ( mWidth < 0 || mHeight < 0 || mDepth < 0 || - mTextureWidth < 0 || mTextureHeight < 0 ) - { - return false; - }; - - // Set up host language before creating browser window - if(!mHostLanguage.empty()) - { - LLQtWebKit::getInstance()->setHostLanguage(mHostLanguage); - postDebugMessage( "Setting language to " + mHostLanguage ); - } - - // turn on/off cookies based on what host app tells us - LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); - - // turn on/off plugins based on what host app tells us - LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); - - // turn on/off Javascript based on what host app tells us -#if LLQTWEBKIT_API_VERSION >= 11 - LLQtWebKit::getInstance()->enableJavaScript( mJavascriptEnabled ); -#else - LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); -#endif - - std::stringstream str; - str << "Cookies enabled = " << mCookiesEnabled << ", plugins enabled = " << mPluginsEnabled << ", Javascript enabled = " << mJavascriptEnabled; - postDebugMessage( str.str() ); - - // create single browser window - mBrowserWindowId = LLQtWebKit::getInstance()->createBrowserWindow( mWidth, mHeight, mTarget); - - str.str(""); - str.clear(); - str << "Setting browser window size to " << mWidth << " x " << mHeight; - postDebugMessage( str.str() ); - - // tell LLQtWebKit about the size of the browser window - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - - // observer events that LLQtWebKit emits - LLQtWebKit::getInstance()->addObserver( mBrowserWindowId, this ); - - // append details to agent string - LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); - postDebugMessage( "Updating user agent with " + mUserAgent ); - -#if !LL_QTWEBKIT_USES_PIXMAPS - // don't flip bitmap - LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true ); -#endif // !LL_QTWEBKIT_USES_PIXMAPS - - // set background color - // convert background color channels from [0.0, 1.0] to [0, 255]; - LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, int(mBackgroundR * 255.0f), int(mBackgroundG * 255.0f), int(mBackgroundB * 255.0f) ); - - // Set state _before_ starting the navigate, since onNavigateBegin might get called before this call returns. - setInitState(INIT_STATE_NAVIGATING); - - // Don't do this here -- it causes the dreaded "white flash" when loading a browser instance. - // FIXME: Re-added this because navigating to a "page" initializes things correctly - especially - // for the HTTP AUTH dialog issues (DEV-41731). Will fix at a later date. - // Build a data URL like this: "data:text/html,%3Chtml%3E%3Cbody bgcolor=%22#RRGGBB%22%3E%3C/body%3E%3C/html%3E" - // where RRGGBB is the background color in HTML style - std::stringstream url; - - url << "data:text/html,%3Chtml%3E%3Cbody%20bgcolor=%22#"; - // convert background color channels from [0.0, 1.0] to [0, 255]; - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundR * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundG * 255.0f); - url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f); - url << "%22%3E%3C/body%3E%3C/html%3E"; - - //LL_DEBUGS() << "data url is: " << url.str() << LL_ENDL; - - // always display loading overlay now -#if LLQTWEBKIT_API_VERSION >= 16 - LLQtWebKit::getInstance()->enableLoadingOverlay(mBrowserWindowId, true); -#else - LL_WARNS() << "Ignoring enableLoadingOverlay() call (llqtwebkit version is too old)." << LL_ENDL; -#endif - str.clear(); - str << "Loading overlay enabled = " << mEnableMediaPluginDebugging << " for mBrowserWindowId = " << mBrowserWindowId; - postDebugMessage( str.str() ); - - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() ); -// LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" ); - - return true; - } - - void setVolume(F32 vol); - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onCursorChanged(const EventType& event) - { - LLQtWebKit::ECursor llqt_cursor = (LLQtWebKit::ECursor)event.getIntValue(); - std::string name; - - switch(llqt_cursor) - { - case LLQtWebKit::C_ARROW: - name = "arrow"; - break; - case LLQtWebKit::C_IBEAM: - name = "ibeam"; - break; - case LLQtWebKit::C_SPLITV: - name = "splitv"; - break; - case LLQtWebKit::C_SPLITH: - name = "splith"; - break; - case LLQtWebKit::C_POINTINGHAND: - name = "hand"; - break; - - default: - LL_WARNS() << "Unknown cursor ID: " << (int)llqt_cursor << LL_ENDL; - break; - } - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "cursor_changed"); - message.setValue("name", name); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onPageChanged( const EventType& event ) - { - if(mInitState == INIT_STATE_WAIT_REDRAW) - { - setInitState(INIT_STATE_WAIT_COMPLETE); - } - - // flag that an update is required - mNeedsUpdate = true; - }; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateBegin(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); - message.setValue("uri", event.getEventUri()); - message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK)); - message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD)); - sendMessage(message); - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Navigate begin event at: " + event.getEventUri() ); - - setStatus(STATUS_LOADING); - } - - if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) - { - // Skip the WAIT_REDRAW state now -- with the right background color set, it should no longer be necessary. -// setInitState(INIT_STATE_WAIT_REDRAW); - setInitState(INIT_STATE_WAIT_COMPLETE); - } - - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateComplete(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - if(mInitState < INIT_STATE_RUNNING) - { - setInitState(INIT_STATE_RUNNING); - - // Clear the history, so the "back" button doesn't take you back to "about:blank". - LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); - } - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_complete"); - message.setValue("uri", event.getEventUri()); - message.setValueS32("result_code", event.getIntValue()); - message.setValue("result_string", event.getStringValue()); - message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK)); - message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD)); - sendMessage(message); - - setStatus(STATUS_LOADED); - } - else if(mInitState == INIT_STATE_NAVIGATING) - { - setInitState(INIT_STATE_NAVIGATE_COMPLETE); - } - - // debug spam sent to viewer and displayed in the log as usual - postDebugMessage( "Navigate complete event at: " + event.getEventUri() ); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onUpdateProgress(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "progress"); - message.setValueS32("percent", event.getIntValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onStatusTextChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "status_text"); - message.setValue("status", event.getStringValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onTitleChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text"); - message.setValue("name", event.getStringValue()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onNavigateErrorPage(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_error_page"); - message.setValueS32("status_code", event.getIntValue()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onLocationChange(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "location_changed"); - message.setValue("uri", event.getEventUri()); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onClickLinkHref(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_href"); - message.setValue("uri", event.getEventUri()); - message.setValue("target", event.getStringValue()); - message.setValue("uuid", event.getStringValue2()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onClickLinkNoFollow(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", event.getEventUri()); -#if LLQTWEBKIT_API_VERSION >= 7 - message.setValue("nav_type", event.getNavigationType()); -#else - message.setValue("nav_type", "clicked"); -#endif - sendMessage(message); - } - - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onCookieChanged(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "cookie_set"); - message.setValue("cookie", event.getStringValue()); - // These could be passed through as well, but aren't really needed. -// message.setValue("uri", event.getEventUri()); -// message.setValueBoolean("dead", (event.getIntValue() != 0)) - - // debug spam - postDebugMessage( "Sending cookie_set message from plugin: " + event.getStringValue() ); - - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onWindowCloseRequested(const EventType& event) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "close_request"); - message.setValue("uuid", event.getStringValue()); - sendMessage(message); - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onWindowGeometryChangeRequested(const EventType& event) - { - int x, y, width, height; - event.getRectValue(x, y, width, height); - - // This sometimes gets called with a zero-size request. Don't pass these along. - if(width > 0 && height > 0) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "geometry_change"); - message.setValue("uuid", event.getStringValue()); - message.setValueS32("x", x); - message.setValueS32("y", y); - message.setValueS32("width", width); - message.setValueS32("height", height); - sendMessage(message); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - std::string onRequestFilePicker( const EventType& eventIn ) - { - return blockingPickFile(); - } - - std::string mAuthUsername; - std::string mAuthPassword; - bool mAuthOK; - - //////////////////////////////////////////////////////////////////////////////// - // virtual - bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password) - { - mAuthOK = false; - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request"); - message.setValue("url", in_url); - message.setValue("realm", in_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); - - if(mAuthOK) - { - out_username = mAuthUsername; - out_password = mAuthPassword; - } - - return mAuthOK; - } - - void authResponse(LLPluginMessage &message) - { - mAuthOK = message.getValueBoolean("ok"); - if(mAuthOK) - { - mAuthUsername = message.getValue("username"); - mAuthPassword = message.getValue("password"); - } - } - - //////////////////////////////////////////////////////////////////////////////// - // virtual - void onLinkHovered(const EventType& event) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered"); - message.setValue("link", event.getEventUri()); - message.setValue("title", event.getStringValue()); - message.setValue("text", event.getStringValue2()); - sendMessage(message); - } - } - - LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers) - { - int result = 0; - - if(modifiers.find("shift") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_SHIFT; - - if(modifiers.find("alt") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_ALT; - - if(modifiers.find("control") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_CONTROL; - - if(modifiers.find("meta") != std::string::npos) - result |= LLQtWebKit::KM_MODIFIER_META; - - return (LLQtWebKit::EKeyboardModifier)result; - } - - //////////////////////////////////////////////////////////////////////////////// - // - void deserializeKeyboardData( LLSD native_key_data, uint32_t& native_scan_code, uint32_t& native_virtual_key, uint32_t& native_modifiers ) - { - native_scan_code = 0; - native_virtual_key = 0; - native_modifiers = 0; - - if( native_key_data.isMap() ) - { -#if LL_DARWIN - native_scan_code = (uint32_t)(native_key_data["char_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["key_code"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#elif LL_WINDOWS - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - // TODO: I don't think we need to do anything with native modifiers here -- please verify -#elif LL_LINUX - native_scan_code = (uint32_t)(native_key_data["scan_code"].asInteger()); - native_virtual_key = (uint32_t)(native_key_data["virtual_key"].asInteger()); - native_modifiers = (uint32_t)(native_key_data["modifiers"].asInteger()); -#else - // Add other platforms here as needed -#endif - }; - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void keyEvent(LLQtWebKit::EKeyEvent key_event, int key, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) - { - // The incoming values for 'key' will be the ones from indra_constants.h - std::string utf8_text; - - if(key < KEY_SPECIAL) - { - // Low-ascii characters need to get passed through. - utf8_text = (char)key; - } - - // Any special-case handling we want to do for particular keys... - switch((KEY)key) - { - // ASCII codes for some standard keys - case LLQtWebKit::KEY_BACKSPACE: utf8_text = (char)8; break; - case LLQtWebKit::KEY_TAB: utf8_text = (char)9; break; - case LLQtWebKit::KEY_RETURN: utf8_text = (char)13; break; - case LLQtWebKit::KEY_PAD_RETURN: utf8_text = (char)13; break; - case LLQtWebKit::KEY_ESCAPE: utf8_text = (char)27; break; - - default: - break; - } - -// std::cerr << "key event " << (int)key_event << ", native_key_data = " << native_key_data << std::endl; - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); - - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, key_event, (uint32_t)key, utf8_text.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - - checkEditState(); - }; - - //////////////////////////////////////////////////////////////////////////////// - // - void unicodeInput( const std::string &utf8str, LLQtWebKit::EKeyboardModifier modifiers, LLSD native_key_data = LLSD::emptyMap()) - { - uint32_t key = LLQtWebKit::KEY_NONE; - -// std::cerr << "unicode input, native_key_data = " << native_key_data << std::endl; - - if(utf8str.size() == 1) - { - // The only way a utf8 string can be one byte long is if it's actually a single 7-bit ascii character. - // In this case, use it as the key value. - key = utf8str[0]; - } - - uint32_t native_scan_code = 0; - uint32_t native_virtual_key = 0; - uint32_t native_modifiers = 0; - deserializeKeyboardData( native_key_data, native_scan_code, native_virtual_key, native_modifiers ); - - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_DOWN, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - LLQtWebKit::getInstance()->keyboardEvent( mBrowserWindowId, LLQtWebKit::KE_KEY_UP, (uint32_t)key, utf8str.c_str(), modifiers, native_scan_code, native_virtual_key, native_modifiers); - - checkEditState(); - }; - - void checkEditState(void) - { - bool can_cut = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT); - bool can_copy = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY); - bool can_paste = LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE); - - 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); - - } - } - - std::string mPickedFile; - - std::string blockingPickFile(void) - { - mPickedFile.clear(); - - LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file"); - 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); - - return mPickedFile; - } - - void onPickFileResponse(const std::string &file) - { - mPickedFile = file; - } - -}; - -MediaPluginWebKit::MediaPluginWebKit(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) : - MediaPluginBase(host_send_func, host_user_data) -{ -// std::cerr << "MediaPluginWebKit constructor" << std::endl; - - mBrowserWindowId = 0; - mInitState = INIT_STATE_UNINITIALIZED; - mNeedsUpdate = true; - mCanCut = false; - mCanCopy = false; - mCanPaste = false; - mLastMouseX = 0; - mLastMouseY = 0; - mFirstFocus = true; - mBackgroundR = 0.0f; - mBackgroundG = 0.0f; - mBackgroundB = 0.0f; - - mHostLanguage = "en"; // default to english - mJavascriptEnabled = true; // default to on - mPluginsEnabled = true; // default to on - mEnableMediaPluginDebugging = false; - mUserAgent = "LLPluginMedia Web Browser"; - - mElapsedTime.reset(); -} - -MediaPluginWebKit::~MediaPluginWebKit() -{ - // unhook observer - LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); - - // clean up - LLQtWebKit::getInstance()->reset(); - -// std::cerr << "MediaPluginWebKit destructor" << std::endl; -} - -void MediaPluginWebKit::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 = "Webkit media plugin, Webkit version "; - plugin_version += LLQtWebKit::getInstance()->getVersion(); - 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") - { - // DTOR most likely won't be called but the recent change to the way this process - // is (not) killed means we see this message and can do what we need to here. - // Note: this cleanup is ultimately what writes cookies to the disk - LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this ); - LLQtWebKit::getInstance()->reset(); - } - 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"); - -// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name -// << ", size: " << info.mSize -// << ", address: " << info.mAddress -// << std::endl; - - mSharedSegments.insert(SharedSegmentMap::value_type(name, info)); - - } - else if(message_name == "shm_remove") - { - std::string name = message_in.getValue("name"); - -// std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl; - - 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_TIME) - { - if(message_name == "set_volume") - { - F32 volume = (F32)message_in.getValueReal("volume"); - setVolume(volume); - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) - { - if(message_name == "init") - { - mTarget = message_in.getValue("target"); - - // This is the media init message -- all necessary data for initialization should have been received. - if(initBrowser()) - { - - // 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_RGBA); - #if LL_QTWEBKIT_USES_PIXMAPS - message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it? If so, we'll have to check the root window's pixel layout or something... yuck. - #else - message.setValueU32("format", GL_RGBA); - #endif // LL_QTWEBKIT_USES_PIXMAPS - message.setValueU32("type", GL_UNSIGNED_BYTE); - message.setValueBoolean("coords_opengl", true); - sendMessage(message); - } - else - { - // if initialization failed, we're done. - mDeleteMe = true; - } - - } - else if(message_name == "set_user_data_path") - { - std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter - mProfileDir = user_data_path + "browser_profile"; - - // FIXME: Should we do anything with this if it comes in after the browser has been initialized? - } - else if(message_name == "set_language_code") - { - mHostLanguage = message_in.getValue("language"); - - // FIXME: Should we do anything with this if it comes in after the browser has been initialized? - } - 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 == "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"); - mBackgroundR = (F32)message_in.getValueReal("background_r"); - mBackgroundG = (F32)message_in.getValueReal("background_g"); - mBackgroundB = (F32)message_in.getValueReal("background_b"); -// mBackgroundA = message_in.setValueReal("background_a"); // Ignore any alpha - - 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; - - if(initBrowserWindow()) - { - - // size changed so tell the browser - LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight ); - - // std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight - // << ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl; - - S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId); - - // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response. - if(real_width <= texture_width) - { - texture_width = real_width; - } - else - { - // This won't work -- it'll be bigger than the allocated memory. This is a fatal error. - // std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl; - mDeleteMe = true; - return; - } - } - else - { - // Setting up the browser window failed. This is a fatal error. - mDeleteMe = true; - } - - - 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); - - } - else if(message_name == "load_uri") - { - std::string uri = message_in.getValue("uri"); - -// std::cout << "loading URI: " << uri << std::endl; - - if(!uri.empty()) - { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) - { - LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri ); - } - else - { - mInitialNavigateURL = uri; - } - } - } - else if(message_name == "mouse_event") - { - std::string event = message_in.getValue("event"); - S32 button = message_in.getValueS32("button"); - mLastMouseX = message_in.getValueS32("x"); - mLastMouseY = message_in.getValueS32("y"); - std::string modifiers = message_in.getValue("modifiers"); - - // Treat unknown mouse events as mouse-moves. - LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE; - if(event == "down") - { - mouse_event = LLQtWebKit::ME_MOUSE_DOWN; - } - else if(event == "up") - { - mouse_event = LLQtWebKit::ME_MOUSE_UP; - } - else if(event == "double_click") - { - mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK; - } - - LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers)); - checkEditState(); - } - else if(message_name == "scroll_event") - { - S32 x = message_in.getValueS32("x"); - S32 y = message_in.getValueS32("y"); - std::string modifiers = message_in.getValue("modifiers"); - - // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit. - // Qt expects 1 detent to be 120 units. - // It also seems that our y scroll direction is inverted vs. what Qt expects. - - x *= 120; - y *= -120; - - LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers)); - } - else if(message_name == "key_event") - { - std::string event = message_in.getValue("event"); - S32 key = message_in.getValueS32("key"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - // Treat unknown events as key-up for safety. - LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP; - if(event == "down") - { - key_event = LLQtWebKit::KE_KEY_DOWN; - } - else if(event == "repeat") - { - key_event = LLQtWebKit::KE_KEY_REPEAT; - } - - keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data); - } - else if(message_name == "text_event") - { - std::string text = message_in.getValue("text"); - std::string modifiers = message_in.getValue("modifiers"); - LLSD native_key_data = message_in.getValueLLSD("native_key_data"); - - unicodeInput(text, decodeModifiers(modifiers), native_key_data); - } - if(message_name == "edit_cut") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT ); - checkEditState(); - } - if(message_name == "edit_copy") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY ); - checkEditState(); - } - if(message_name == "edit_paste") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE ); - checkEditState(); - } - if(message_name == "pick_file_response") - { - onPickFileResponse(message_in.getValue("file")); - } - if(message_name == "auth_response") - { - authResponse(message_in); - } - else - if(message_name == "enable_media_plugin_debugging") - { - mEnableMediaPluginDebugging = message_in.getValueBoolean( "enable" ); - } - else - if(message_name == "js_enable_object") - { -#if LLQTWEBKIT_API_VERSION >= 9 - bool enable = message_in.getValueBoolean( "enable" ); - LLQtWebKit::getInstance()->setSLObjectEnabled( enable ); -#endif - } - else - if(message_name == "js_agent_location") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 x = (F32)message_in.getValueReal("x"); - F32 y = (F32)message_in.getValueReal("y"); - F32 z = (F32)message_in.getValueReal("z"); - LLQtWebKit::getInstance()->setAgentLocation( x, y, z ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_global_location") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 x = (F32)message_in.getValueReal("x"); - F32 y = (F32)message_in.getValueReal("y"); - F32 z = (F32)message_in.getValueReal("z"); - LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_orientation") - { -#if LLQTWEBKIT_API_VERSION >= 9 - F32 angle = (F32)message_in.getValueReal("angle"); - LLQtWebKit::getInstance()->setAgentOrientation( angle ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_region") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& region = message_in.getValue("region"); - LLQtWebKit::getInstance()->setAgentRegion( region ); - LLQtWebKit::getInstance()->emitLocation(); -#endif - } - else - if(message_name == "js_agent_maturity") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& maturity = message_in.getValue("maturity"); - LLQtWebKit::getInstance()->setAgentMaturity( maturity ); - LLQtWebKit::getInstance()->emitMaturity(); -#endif - } - else - if(message_name == "js_agent_language") - { -#if LLQTWEBKIT_API_VERSION >= 9 - const std::string& language = message_in.getValue("language"); - LLQtWebKit::getInstance()->setAgentLanguage( language ); - LLQtWebKit::getInstance()->emitLanguage(); -#endif - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl; - } - } - else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) - { - if(message_name == "focus") - { - bool val = message_in.getValueBoolean("focused"); - LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val ); - - if(mFirstFocus && val) - { - // On the first focus, post a tab key event. This fixes a problem with initial focus. - std::string empty; - keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty)); - keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty)); - mFirstFocus = false; - } - } - else if(message_name == "set_page_zoom_factor") - { -#if LLQTWEBKIT_API_VERSION >= 15 - F32 factor = (F32)message_in.getValueReal("factor"); - LLQtWebKit::getInstance()->setPageZoomFactor(factor); -#else - LL_WARNS() << "Ignoring setPageZoomFactor message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "clear_cache") - { - LLQtWebKit::getInstance()->clearCache(); - } - else if(message_name == "clear_cookies") - { - LLQtWebKit::getInstance()->clearAllCookies(); - } - else if(message_name == "enable_cookies") - { - mCookiesEnabled = message_in.getValueBoolean("enable"); - LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled ); - } - else if(message_name == "enable_plugins") - { - mPluginsEnabled = message_in.getValueBoolean("enable"); - LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled ); - } - else if(message_name == "enable_javascript") - { - mJavascriptEnabled = message_in.getValueBoolean("enable"); - //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled ); - } - else if(message_name == "set_cookies") - { - LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies")); - - // debug spam - postDebugMessage( "Plugin setting cookie: " + message_in.getValue("cookies") ); - } - else if(message_name == "proxy_setup") - { - bool val = message_in.getValueBoolean("enable"); - std::string host = message_in.getValue("host"); - int port = message_in.getValueS32("port"); - LLQtWebKit::getInstance()->enableProxy( val, host, port ); - } - else if(message_name == "browse_stop") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP ); - } - else if(message_name == "browse_reload") - { - // foo = message_in.getValueBoolean("ignore_cache"); - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD ); - } - else if(message_name == "browse_forward") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD ); - } - else if(message_name == "browse_back") - { - LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK ); - } - else if(message_name == "set_status_redirect") - { - int code = message_in.getValueS32("code"); - std::string url = message_in.getValue("url"); - if ( 404 == code ) // browser lib only supports 404 right now - { -#if LLQTWEBKIT_API_VERSION < 8 - LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url ); -#endif - }; - } - else if(message_name == "set_user_agent") - { - mUserAgent = message_in.getValue("user_agent"); - LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent ); - } - else if(message_name == "show_web_inspector") - { -#if LLQTWEBKIT_API_VERSION >= 10 - bool val = message_in.getValueBoolean("show"); - LLQtWebKit::getInstance()->showWebInspector( val ); -#else - LL_WARNS() << "Ignoring showWebInspector message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "ignore_ssl_cert_errors") - { -#if LLQTWEBKIT_API_VERSION >= 3 - LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") ); -#else - LL_WARNS() << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "add_certificate_file_path") - { -#if LLQTWEBKIT_API_VERSION >= 6 - LLQtWebKit::getInstance()->setCAFile( message_in.getValue("path") ); -#else - LL_WARNS() << "Ignoring add_certificate_file_path message (llqtwebkit version is too old)." << LL_ENDL; -#endif - } - else if(message_name == "init_history") - { - // Initialize browser history - LLSD history = message_in.getValueLLSD("history"); - // First, clear the URL history - LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId); - // Then, add the history items in order - LLSD::array_iterator iter_history = history.beginArray(); - LLSD::array_iterator end_history = history.endArray(); - for(; iter_history != end_history; ++iter_history) - { - std::string url = (*iter_history).asString(); - if(! url.empty()) { - LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url); - } - } - } - else if(message_name == "proxy_window_opened") - { - std::string target = message_in.getValue("target"); - std::string uuid = message_in.getValue("uuid"); - LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid); - } - else if(message_name == "proxy_window_closed") - { - std::string uuid = message_in.getValue("uuid"); - LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid); - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl; - }; - } - else - { -// std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl; - }; - } -} - -void MediaPluginWebKit::setVolume(F32 volume) -{ - mVolumeCatcher.setVolume(volume); -} - -int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data, LLPluginInstance::sendMessageFunction *plugin_send_func, void **plugin_user_data) -{ - MediaPluginWebKit *self = new MediaPluginWebKit(host_send_func, host_user_data); - *plugin_send_func = MediaPluginWebKit::staticReceiveMessage; - *plugin_user_data = (void*)self; - - return 0; -} - - diff --git a/indra/media_plugins/webkit/volume_catcher.h b/indra/media_plugins/webkit/volume_catcher.h deleted file mode 100755 index 337f2913d3..0000000000 --- a/indra/media_plugins/webkit/volume_catcher.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @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. - * - * @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 - */ - -#ifndef VOLUME_CATCHER_H -#define VOLUME_CATCHER_H - -#include "linden_common.h" - -class VolumeCatcherImpl; - -class VolumeCatcher -{ - public: - 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 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; -}; - -#endif // VOLUME_CATCHER_H diff --git a/indra/media_plugins/webkit/windows_volume_catcher.cpp b/indra/media_plugins/webkit/windows_volume_catcher.cpp deleted file mode 100755 index 0cfb810906..0000000000 --- a/indra/media_plugins/webkit/windows_volume_catcher.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file windows_volume_catcher.cpp - * @brief A Windows implementation of volume level control of all audio channels opened by a process. - * - * @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 - */ - -#include "volume_catcher.h" -#include -#include "llsingleton.h" -class VolumeCatcherImpl : public LLSingleton -{ -friend LLSingleton; -public: - - void setVolume(F32 volume); - void setPan(F32 pan); - -private: - // This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance. - VolumeCatcherImpl(); - ~VolumeCatcherImpl(); - - typedef void (WINAPI *set_volume_func_t)(F32); - typedef void (WINAPI *set_mute_func_t)(bool); - - set_volume_func_t mSetVolumeFunc; - set_mute_func_t mSetMuteFunc; - - // tests if running on Vista, 7, 8 + once in CTOR - bool isWindowsVistaOrHigher(); - - F32 mVolume; - F32 mPan; - bool mSystemIsVistaOrHigher; -}; - -bool VolumeCatcherImpl::isWindowsVistaOrHigher() -{ - OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); - return osvi.dwMajorVersion >= 6; -} - -VolumeCatcherImpl::VolumeCatcherImpl() -: mVolume(1.0f), // default volume is max - mPan(0.f) // default pan is centered -{ - mSystemIsVistaOrHigher = isWindowsVistaOrHigher(); - - if ( ! mSystemIsVistaOrHigher ) - { - HMODULE handle = ::LoadLibrary(L"winmm.dll"); - if(handle) - { - mSetVolumeFunc = (set_volume_func_t)::GetProcAddress(handle, "setPluginVolume"); - mSetMuteFunc = (set_mute_func_t)::GetProcAddress(handle, "setPluginMute"); - } - } -} - -VolumeCatcherImpl::~VolumeCatcherImpl() -{ -} - -void VolumeCatcherImpl::setVolume(F32 volume) -{ - mVolume = volume; - - if ( mSystemIsVistaOrHigher ) - { - // 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); - } - else - { - if (mSetMuteFunc) - { - mSetMuteFunc(volume == 0.f); - } - if (mSetVolumeFunc) - { - mSetVolumeFunc(mVolume); - } - } -} - -void VolumeCatcherImpl::setPan(F32 pan) -{ // remember pan for calculating individual channel levels later - mPan = pan; -} - -///////////////////////////////////////////////////// - -VolumeCatcher::VolumeCatcher() -{ - pimpl = VolumeCatcherImpl::getInstance(); -} - -VolumeCatcher::~VolumeCatcher() -{ - // Let the instance persist until exit. -} - -void VolumeCatcher::setVolume(F32 volume) -{ - pimpl->setVolume(volume); -} - -void VolumeCatcher::setPan(F32 pan) -{ - pimpl->setPan(pan); -} - -void VolumeCatcher::pump() -{ - // No periodic tasks are necessary for this implementation. -} - - diff --git a/indra/media_plugins/winmmshim/CMakeLists.txt b/indra/media_plugins/winmmshim/CMakeLists.txt index bf74f81809..6890589892 100755 --- a/indra/media_plugins/winmmshim/CMakeLists.txt +++ b/indra/media_plugins/winmmshim/CMakeLists.txt @@ -22,9 +22,6 @@ set(winmm_shim_HEADER_FILES list(APPEND winmm_shim_SOURCE_FILES ${winmm_shim_HEADER_FILES}) -set_source_files_properties(${media_plugin_webkit_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - add_library(winmm_shim SHARED ${winmm_shim_SOURCE_FILES} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d575e5cd8c..087d508c42 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1764,7 +1764,6 @@ if (WINDOWS) ${ARCH_PREBUILT_DIRS_RELEASE}/qtgui4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/qtnetwork4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/qtopengl4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtwebkit4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/qtxmlpatterns4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/ssleay32.dll ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qgif4.dll @@ -1782,7 +1781,6 @@ if (WINDOWS) ${ARCH_PREBUILT_DIRS_DEBUG}/qtguid4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/qtnetworkd4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/qtopengld4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtwebkitd4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/qtxmlpatternsd4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qgifd4.dll @@ -2013,7 +2011,6 @@ if (LINUX) ${VIEWER_BINARY_NAME} linux-crash-logger SLPlugin - media_plugin_webkit media_plugin_gstreamer010 llcommon ) @@ -2185,7 +2182,6 @@ if (PACKAGE) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}") -## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger") set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger") diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 663f1a3550..68976dcfe3 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -124,7 +124,9 @@ #include "llleap.h" #include "stringize.h" #include "llcoros.h" +#if !LL_LINUX #include "cef/llceflib.h" +#endif // Third party library includes #include @@ -3370,7 +3372,11 @@ LLSD LLAppViewer::getViewerInfo() const info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); } +#if !LL_LINUX info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION; +#else + info["LLCEFLIB_VERSION"] = "Undefined"; +#endif S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); if (packets_in > 0) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bc5be822d0..15ec946e63 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1076,7 +1076,6 @@ class LinuxManifest(ViewerManifest): # plugins if self.prefix(src="", dst="bin/llplugin"): - self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so") self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.end_prefix("bin/llplugin") @@ -1224,7 +1223,6 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libQtNetwork.so*") self.path("libQtOpenGL.so*") self.path("libQtSvg.so*") - self.path("libQtWebKit.so*") self.path("libQtXml.so*") self.end_prefix("lib") diff --git a/indra/test_apps/llfbconnecttest/CMakeLists.txt b/indra/test_apps/llfbconnecttest/CMakeLists.txt deleted file mode 100644 index 25aaebb783..0000000000 --- a/indra/test_apps/llfbconnecttest/CMakeLists.txt +++ /dev/null @@ -1,372 +0,0 @@ -# -*- cmake -*- -project(llfbconnecttest) - -include(00-Common) -include(FindOpenGL) -include(LLCommon) -include(LLPlugin) -include(Linking) -include(LLSharedLibs) -include(PluginAPI) -include(LLImage) -include(LLMath) -include(LLMessage) -include(LLRender) -include(LLWindow) -include(Glut) -include(Glui) - -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} -) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(COREFOUNDATION_LIBRARY CoreFoundation) -endif (DARWIN) - -### llfbconnecttest - -set(llfbconnecttest_SOURCE_FILES - llfbconnecttest.cpp - llfbconnecttest.h - bookmarks.txt - ) - -add_executable(llfbconnecttest - WIN32 - MACOSX_BUNDLE - ${llfbconnecttest_SOURCE_FILES} -) - -set_target_properties(llfbconnecttest - PROPERTIES - WIN32_EXECUTABLE - FALSE -) - -target_link_libraries(llfbconnecttest - ${GLUT_LIBRARY} - ${GLUI_LIBRARY} - ${OPENGL_LIBRARIES} - ${LLPLUGIN_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) - -if (DARWIN) - # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app. - target_link_libraries(llfbconnecttest - ${COREFOUNDATION_LIBRARY} - ) -endif (DARWIN) - -add_dependencies(llfbconnecttest - stage_third_party_libs - SLPlugin - media_plugin_webkit - ${LLPLUGIN_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} -) - -# turn off weird GLUI pragma -add_definitions(-DGLUI_NO_LIB_PRAGMA) - -if (DARWIN OR LINUX) - # glui.h contains code that triggers the "overloaded-virtual" warning in gcc. - set_source_files_properties(llfbconnecttest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual") -endif (DARWIN OR LINUX) - -# Gather build products of the various dependencies into the build directory for the testbed. - -if (DARWIN) - # path inside the app bundle where we'll need to copy plugins and other related files - set(PLUGINS_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llfbconnecttest.app/Contents/Resources - ) - - # create the Contents/Resources directory - add_custom_command( - TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - make_directory - ${PLUGINS_DESTINATION_DIR} - COMMENT "Creating Resources directory in app bundle." - ) -else (DARWIN) - set(PLUGINS_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - ) -endif (DARWIN) - -set(BUILT_SLPLUGIN $) -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_SLPLUGIN} -) - -set(BUILT_LLCOMMON $) -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLCOMMON} -) - - -set(BUILT_WEBKIT_PLUGIN $) -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_WEBKIT_PLUGIN} -) - -# copy over bookmarks file if llfbconnecttest gets built -set(BUILT_LLFBCONNECTTEST $) -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ - DEPENDS ${BUILT_LLFBCONNECTTEST} -) - -# also copy it to the same place as SLPlugin, which is what the mac wants... -add_custom_command(TARGET llfbconnecttest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLFBCONNECTTEST} -) - -if(WINDOWS) - #******************** - # Plugin test library deploy - # - # Debug config runtime files required for the FB connect test - set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}") - set(fbconnecttest_debug_files - libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - qtcored4.dll - qtguid4.dll - qtnetworkd4.dll - qtopengld4.dll - qtwebkitd4.dll - ssleay32.dll - ) - copy_if_different( - ${fbconnecttest_debug_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Debug" - out_targets - ${fbconnecttest_debug_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Debug config runtime files required for the FB connect test (Qt image format plugins) - set(fbconecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/imageformats") - set(fbconecttest_debug_files - qgifd4.dll - qicod4.dll - qjpegd4.dll - qmngd4.dll - qsvgd4.dll - qtiffd4.dll - ) - copy_if_different( - ${fbconecttest_debug_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Debug/imageformats" - out_targets - ${fbconecttest_debug_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Debug config runtime files required for the FB connect test (Qt codec plugins) - set(fbconnecttest_debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}/codecs") - set(fbconnecttest_debug_files - qcncodecsd4.dll - qjpcodecsd4.dll - qkrcodecsd4.dll - qtwcodecsd4.dll - ) - copy_if_different( - ${fbconnecttest_debug_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Debug/codecs" - out_targets - ${fbconnecttest_debug_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the FB connect test - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") - set(fbconnecttest_release_files - libeay32.dll - libglib-2.0-0.dll - libgmodule-2.0-0.dll - libgobject-2.0-0.dll - libgthread-2.0-0.dll - qtcore4.dll - qtgui4.dll - qtnetwork4.dll - qtopengl4.dll - qtwebkit4.dll - qtxmlpatterns4.dll - ssleay32.dll - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Release" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins) - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/imageformats") - set(fbconnecttest_release_files - qgif4.dll - qico4.dll - qjpeg4.dll - qmng4.dll - qsvg4.dll - qtiff4.dll - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Release/imageformats" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/imageformats" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins) - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}/codecs") - set(fbconnecttest_release_files - qcncodecs4.dll - qjpcodecs4.dll - qkrcodecs4.dll - qtwcodecs4.dll - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/Release/codecs" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - copy_if_different( - ${fbconnecttest_release_src_dir} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/codecs" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - add_custom_target(copy_fbconnecttest_libs ALL - DEPENDS - ${fbconnect_test_targets} - ) - - add_dependencies(llfbconnecttest copy_fbconnecttest_libs) - -endif(WINDOWS) - -if (DARWIN) - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") - set(fbconnecttest_release_files - libexception_handler.dylib - libaprutil-1.0.dylib - libapr-1.0.dylib - libexpat.1.5.2.dylib - libQtCore.4.7.1.dylib - libQtCore.4.dylib - libQtGui.4.7.1.dylib - libQtGui.4.dylib - libQtNetwork.4.7.1.dylib - libQtNetwork.4.dylib - libQtOpenGL.4.7.1.dylib - libQtOpenGL.4.dylib - libQtWebKit.4.7.1.dylib - libQtWebKit.4.dylib - libQtSvg.4.7.1.dylib - libQtSvg.4.dylib - libQtXml.4.7.1.dylib - libQtXml.4.dylib - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${PLUGINS_DESTINATION_DIR}" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt image format plugins) - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/imageformats") - set(fbconnecttest_release_files - libqgif.dylib - libqico.dylib - libqjpeg.dylib - libqmng.dylib - libqsvg.dylib - libqtiff.dylib - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${PLUGINS_DESTINATION_DIR}/imageformats" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - # Release & ReleaseDebInfo config runtime files required for the FB connect test (Qt codec plugins) - set(fbconnecttest_release_src_dir "${ARCH_PREBUILT_DIRS_PLUGINS}/codecs") - set(fbconnecttest_release_files - libqcncodecs.dylib - libqjpcodecs.dylib - libqkrcodecs.dylib - libqtwcodecs.dylib - ) - copy_if_different( - ${fbconnecttest_release_src_dir} - "${PLUGINS_DESTINATION_DIR}/codecs" - out_targets - ${fbconnecttest_release_files} - ) - set(fbconnect_test_targets ${fbconnect_test_targets} ${out_targets}) - - add_custom_target(copy_fbconnecttest_libs ALL - DEPENDS - ${fbconnect_test_targets} - ) - - add_dependencies(llfbconnecttest copy_fbconnecttest_libs) -endif (DARWIN) - -if (LINUX) - -endif (LINUX) - -ll_deploy_sharedlibs_command(llfbconnecttest) diff --git a/indra/test_apps/llfbconnecttest/README.Linden b/indra/test_apps/llfbconnecttest/README.Linden deleted file mode 100644 index 7488ce680a..0000000000 --- a/indra/test_apps/llfbconnecttest/README.Linden +++ /dev/null @@ -1,20 +0,0 @@ - -1. Description - - Exercises SLPlugin. Specific functions and goals aren't clear - from the source. - -2. Running - - 2.1 Mac - - Make certain '.' is included in PATH. E.g.: - - PATH=.:"$PATH" open build-darwin-i386/test_apps/llfbconnecttest/RelWithDebInfo/llfbconnecttest.app - - Otherwise the program won't find SLPlugin and will timeout and - fail after 30 seconds and give you little information as to why. - - Running 'dtruss' on plugin test applications will give you a great - deal of insight into why they aren't activating. - diff --git a/indra/test_apps/llfbconnecttest/bookmarks.txt b/indra/test_apps/llfbconnecttest/bookmarks.txt deleted file mode 100644 index 3995627ea9..0000000000 --- a/indra/test_apps/llfbconnecttest/bookmarks.txt +++ /dev/null @@ -1,4 +0,0 @@ -# format is description, url (don't put ',' chars in description :) -# if no ',' found, whole line is used for both description and url -Google Home Page,http://www.google.com -Facebook Home Page,http://www.facebook.com diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp b/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp deleted file mode 100644 index 483a15c468..0000000000 --- a/indra/test_apps/llfbconnecttest/llfbconnecttest.cpp +++ /dev/null @@ -1,2394 +0,0 @@ -/** - * @file LLFBConnectTest.cpp - * @brief Facebook Connect Test App - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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$ - */ - -#include "linden_common.h" -#include "indra_constants.h" - -#include "llapr.h" -#include "llerrorcontrol.h" - -#include -#include -#include -#include - -#include "llfbconnecttest.h" - -#if __APPLE__ - #include - #include -#else - #define FREEGLUT_STATIC - #include "GL/freeglut.h" - #define GLUI_FREEGLUT -#endif - -#if LL_WINDOWS -#pragma warning(disable: 4263) -#pragma warning(disable: 4264) -#endif -#include "glui.h" - - -LLFBConnectTest* gApplication = 0; -static void gluiCallbackWrapper( int control_id ); - -//////////////////////////////////////////////////////////////////////////////// -// -static bool isTexture( GLuint texture ) -{ - bool result = false; - - // glIsTexture will sometimes return false for real textures... do this instead. - if(texture != 0) - result = true; - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel::mediaPanel() -{ - mMediaTextureHandle = 0; - mPickTextureHandle = 0; - mMediaSource = NULL; - mPickTexturePixels = NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel::~mediaPanel() -{ - // delete OpenGL texture handles - if ( isTexture( mPickTextureHandle ) ) - { - std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl; - glDeleteTextures( 1, &mPickTextureHandle ); - mPickTextureHandle = 0; - } - - if ( isTexture( mMediaTextureHandle ) ) - { - std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl; - glDeleteTextures( 1, &mMediaTextureHandle ); - mMediaTextureHandle = 0; - } - - if(mPickTexturePixels) - { - delete mPickTexturePixels; - } - - if(mMediaSource) - { - delete mMediaSource; - } - -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLFBConnectTest::LLFBConnectTest( int app_window, int window_width, int window_height ) : - mVersionMajor( 2 ), - mVersionMinor( 0 ), - mVersionPatch( 0 ), - mMaxPanels( 25 ), - mViewportAspect( 0 ), - mAppWindow( app_window ), - mCurMouseX( 0 ), - mCurMouseY( 0 ), - mFuzzyMedia( true ), - mSelectedPanel( 0 ), - mDistanceCameraToSelectedGeometry( 0.0f ), - //mMediaBrowserControlEnableCookies( 0 ), - mMediaBrowserControlBackButton( 0 ), - mMediaBrowserControlForwardButton( 0 ), - //mMediaTimeControlVolume( 100 ), - //mMediaTimeControlSeekSeconds( 0 ), - //mGluiMediaTimeControlWindowFlag( true ), - mGluiMediaBrowserControlWindowFlag( true ), - mMediaBrowserControlBackButtonFlag( true ), - mMediaBrowserControlForwardButtonFlag( true ), - mHomeWebUrl( "https://cryptic-ridge-1632.herokuapp.com/" ) -{ - // debugging spam - std::cout << std::endl << " GLUT version: " << "3.7.6" << std::endl; // no way to get real version from GLUT - std::cout << std::endl << " GLUI version: " << GLUI_Master.get_version() << std::endl; - std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl; - - // bookmark title - mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) ); - - // insert hardcoded URLs here as required for testing - //mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) ); - - // read bookmarks from file. - // note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory - // to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC) - // For example, test_apps\llplugintest and not test_apps\llplugintest\Release - // This may need to be changed for Mac/Linux builds. - // See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI - const std::string bookmarks_filename( "bookmarks.txt" ); - std::ifstream file_handle( bookmarks_filename.c_str() ); - if ( file_handle.is_open() ) - { - std::cout << "Reading bookmarks for test" << std::endl; - while( ! file_handle.eof() ) - { - std::string line; - std::getline( file_handle, line ); - if ( file_handle.eof() ) - break; - - if ( line.substr( 0, 1 ) != "#" ) - { - size_t comma_pos = line.find_first_of( ',' ); - if ( comma_pos != std::string::npos ) - { - std::string description = line.substr( 0, comma_pos ); - std::string url = line.substr( comma_pos + 1 ); - mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) ); - } - else - { - mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) ); - }; - }; - }; - std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl; - } - else - { - std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl; - }; - - // initialize linden lab APR module - ll_init_apr(); - - // Set up llerror logging - { - LLError::initForApplication("."); - LLError::setDefaultLevel(LLError::LEVEL_INFO); - //LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); - } - - // lots of randomness in this app - srand( ( unsigned int )time( 0 ) ); - - // build GUI - makeChrome(); - - // OpenGL initialilzation - glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - glClearDepth( 1.0f ); - glEnable( GL_DEPTH_TEST ); - glEnable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); - glDepthFunc( GL_LEQUAL ); - glEnable( GL_TEXTURE_2D ); - glDisable( GL_BLEND ); - glColor3f( 1.0f, 1.0f, 1.0f ); - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); - - // start with a sane view - resetView(); - - // initial media panel - const int num_initial_panels = 1; - for( int i = 0; i < num_initial_panels; ++i ) - { - //addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - addMediaPanel( mHomeWebUrl ); - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLFBConnectTest::~LLFBConnectTest() -{ - // delete all media panels - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - remMediaPanel( mMediaPanels[ i ] ); - }; - - // Stop the plugin read thread if it's running. - LLPluginProcessParent::setUseReadThread(false); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::reshape( int width, int height ) -{ - // update viewport (the active window inside the chrome) - int viewport_x, viewport_y; - int viewport_height, viewport_width; - GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height ); - mViewportAspect = (float)( viewport_width ) / (float)( viewport_height ); - glViewport( viewport_x, viewport_y, viewport_width, viewport_height ); - - // save these as we'll need them later - mWindowWidth = width; - mWindowHeight = height; - - // adjust size of URL bar so it doesn't get clipped - mUrlEdit->set_w( mWindowWidth - 360 ); - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // trigger re-display - glutPostRedisplay(); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::bindTexture(GLuint texture, GLint row_length, GLint alignment) -{ - glEnable( GL_TEXTURE_2D ); - - glBindTexture( GL_TEXTURE_2D, texture ); - glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length ); - glPixelStorei( GL_UNPACK_ALIGNMENT, alignment ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLFBConnectTest::checkGLError(const char *name) -{ - bool result = false; - GLenum error = glGetError(); - - if(error != GL_NO_ERROR) - { - // For some reason, glGenTextures is returning GL_INVALID_VALUE... - std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl; - result = true; - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -GLfloat LLFBConnectTest::distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z ) -{ - GLdouble camera_pos_x = 0.0f; - GLdouble camera_pos_y = 0.0f; - GLdouble camera_pos_z = 0.0f; - - GLdouble modelMatrix[16]; - GLdouble projMatrix[16]; - GLint viewport[4]; - - glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); - glGetIntegerv(GL_VIEWPORT, viewport); - - gluUnProject( - (viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2, - 0.0, - modelMatrix, projMatrix, viewport, - &camera_pos_x, &camera_pos_y, &camera_pos_z ); - - GLfloat distance = - sqrt( ( camera_pos_x - point_x ) * ( camera_pos_x - point_x ) + - ( camera_pos_y - point_y ) * ( camera_pos_y - point_y ) + - ( camera_pos_z - point_z ) * ( camera_pos_z - point_z ) ); - - return distance; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::drawGeometry( int panel, bool selected ) -{ - // texture coordinates for each panel - GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; - GLfloat opengl_texture_coords[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - - GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords; - - // base coordinates for each panel - GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - - // calculate posiitons - const int num_panels = (int)mMediaPanels.size(); - const int num_rows = (int)sqrt( (float)num_panels ); - const int num_cols = num_panels / num_rows; - const int panel_x = ( panel / num_rows ); - const int panel_y = ( panel % num_rows ); - - // default spacing is small - make it larger if checkbox set - for testing positional audio - float spacing = 0.1f; - //if ( mLargePanelSpacing ) - // spacing = 2.0f; - - const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2; - const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2; - - // Adjust for media aspect ratios - { - float aspect = 1.0f; - - if(mMediaPanels[ panel ]->mMediaHeight != 0) - { - aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight; - } - - if(aspect > 1.0f) - { - // media is wider than it is high -- adjust the top and bottom in - for( int corner = 0; corner < 4; ++corner ) - { - float temp = base_vertex_pos[corner * 2 + 1]; - - if(temp < 0.5f) - temp += 0.5 - (0.5f / aspect); - else - temp -= 0.5 - (0.5f / aspect); - - base_vertex_pos[corner * 2 + 1] = temp; - } - } - else if(aspect < 1.0f) - { - // media is higher than it is wide -- adjust the left and right sides in - for( int corner = 0; corner < 4; ++corner ) - { - float temp = base_vertex_pos[corner * 2]; - - if(temp < 0.5f) - temp += 0.5f - (0.5f * aspect); - else - temp -= 0.5f - (0.5f * aspect); - - base_vertex_pos[corner * 2] = temp; - } - } - } - - glBegin( GL_QUADS ); - for( int corner = 0; corner < 4; ++corner ) - { - glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] ); - GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f; - GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f; - - glVertex3f( x, y, 0.0f ); - }; - glEnd(); - - // calculate distance to this panel if it's selected - if ( selected ) - { - GLfloat point_x = base_vertex_pos[ 0 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f; - GLfloat point_y = base_vertex_pos[ 0 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f; - GLfloat point_z = 0.0f; - mDistanceCameraToSelectedGeometry = distanceToCamera( point_x, point_y, point_z ); - }; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::startPanelHighlight( float red, float green, float blue, float line_width ) -{ - glPushAttrib( GL_ALL_ATTRIB_BITS ); - glEnable( GL_POLYGON_OFFSET_FILL ); - glPolygonOffset( -2.5f, -2.5f ); - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - glLineWidth( line_width ); - glColor3f( red, green, blue ); - glDisable( GL_TEXTURE_2D ); -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::endPanelHighlight() -{ - glPopAttrib(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::draw( int draw_type ) -{ - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - // drawing pick texture - if ( draw_type == DrawTypePickTexture ) - { - // only bother with pick if we have something to render - // Actually, we need to pick even if we're not ready to render. - // Otherwise you can't select and remove a panel which has gone bad. - //if ( mMediaPanels[ panel ]->mReadyToRender ) - { - glMatrixMode( GL_TEXTURE ); - glPushMatrix(); - - // pick texture is a power of 2 so no need to scale - glLoadIdentity(); - - // bind to media texture - glLoadIdentity(); - bindTexture( mMediaPanels[ panel ]->mPickTextureHandle ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - - // draw geometry using pick texture - drawGeometry( panel, false ); - - glMatrixMode( GL_TEXTURE ); - glPopMatrix(); - }; - } - else - if ( draw_type == DrawTypeMediaTexture ) - { - bool texture_valid = false; - bool plugin_exited = false; - - if(mMediaPanels[ panel ]->mMediaSource) - { - texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid(); - plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited(); - } - - // save texture matrix (changes for each panel) - glMatrixMode( GL_TEXTURE ); - glPushMatrix(); - - // only process texture if the media is ready to draw - // (we still want to draw the geometry) - if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) - { - // bind to media texture - bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle ); - - if ( mFuzzyMedia ) - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - } - else - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - } - - // scale to fit panel - glScalef( mMediaPanels[ panel ]->mTextureScaleX, - mMediaPanels[ panel ]->mTextureScaleY, - 1.0f ); - }; - - float intensity = plugin_exited?0.25f:1.0f; - - // highlight the selected panel - if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) ) - { - startPanelHighlight( intensity, intensity, 0.0f, 5.0f ); - drawGeometry( panel, true ); - endPanelHighlight(); - } - else - // this panel not able to render yet since it - // doesn't have enough information - if ( !mMediaPanels[ panel ]->mReadyToRender ) - { - startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f ); - drawGeometry( panel, false ); - endPanelHighlight(); - } - else - // just display a border around the media - { - startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f ); - drawGeometry( panel, false ); - endPanelHighlight(); - }; - - if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) - { - // draw visual geometry - drawGeometry( panel, false ); - } - - // restore texture matrix (changes for each panel) - glMatrixMode( GL_TEXTURE ); - glPopMatrix(); - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::display() -{ - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // start with a clean slate - glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - // set up OpenGL view - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - glTranslatef( 0.0, 0.0, 0.0f ); - glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] ); - glMultMatrixf( mViewRotation ); - - // draw pick texture - draw( DrawTypePickTexture ); - - // read colors and get coordinate values - glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor ); - - // clear the pick render (otherwise it may depth-fight with the textures rendered later) - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - // draw visible geometry - draw( DrawTypeMediaTexture ); - - glutSwapBuffers(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::idle() -{ -// checkGLError("LLFBConnectTest::idle"); - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // random creation/destruction of panels enabled? -/* - const time_t panel_timeout_time = 5; - if ( mRandomPanelCount ) - { - // time for a change - static time_t last_panel_time = 0; - if ( time( NULL ) - last_panel_time > panel_timeout_time ) - { - if ( rand() % 2 == 0 ) - { - if ( mMediaPanels.size() < 16 ) - { - std::cout << "Randomly adding new panel" << std::endl; - addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - }; - } - else - { - if ( mMediaPanels.size() > 0 ) - { - std::cout << "Deleting selected panel" << std::endl; - remMediaPanel( mSelectedPanel ); - }; - }; - time( &last_panel_time ); - }; - }; - - // random selection of bookmarks enabled? - const time_t bookmark_timeout_time = 5; - if ( mRandomBookmarks ) - { - // time for a change - static time_t last_bookmark_time = 0; - if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time ) - { - // go to a different random bookmark on each panel - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second; - - std::cout << "Random: navigating to : " << uri << std::endl; - - std::string mime_type = mimeTypeFromUrl( uri ); - - if ( mime_type != mMediaPanels[ panel ]->mMimeType ) - { - replaceMediaPanel( mMediaPanels[ panel ], uri ); - } - else - { - mMediaPanels[ panel ]->mMediaSource->loadURI( uri ); - mMediaPanels[ panel ]->mMediaSource->start(); - }; - }; - - time( &last_bookmark_time ); - }; - }; -*/ - // update UI - if ( mSelectedPanel ) - { - // set volume based on slider if we have time media - //if ( mGluiMediaTimeControlWindowFlag ) - //{ - // mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); - //}; - - // NOTE: it is absurd that we need cache the state of GLUI controls - // but enabling/disabling controls drags framerate from 500+ - // down to 15. Not a problem for plugin system - only this test - // enable/disable time based UI controls based on type of plugin - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - { - /* - if ( ! mGluiMediaTimeControlWindowFlag ) - { - mGluiMediaTimeControlWindow->enable(); - mGluiMediaTimeControlWindowFlag = true; - }; - */ - } - else - { - /* - if ( mGluiMediaTimeControlWindowFlag ) - { - mGluiMediaTimeControlWindow->disable(); - mGluiMediaTimeControlWindowFlag = false; - }; - */ - }; - - // enable/disable browser based UI controls based on type of plugin - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) - { - if ( ! mGluiMediaBrowserControlWindowFlag ) - { - mGluiMediaBrowserControlWindow->enable(); - mGluiMediaBrowserControlWindowFlag = true; - }; - } - else - { - if ( mGluiMediaBrowserControlWindowFlag ) - { - mGluiMediaBrowserControlWindow->disable(); - mGluiMediaBrowserControlWindowFlag = false; - }; - }; - - // enable/disable browser back button depending on browser history - if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable() ) - { - if ( ! mMediaBrowserControlBackButtonFlag ) - { - mMediaBrowserControlBackButton->enable(); - mMediaBrowserControlBackButtonFlag = true; - }; - } - else - { - if ( mMediaBrowserControlBackButtonFlag ) - { - mMediaBrowserControlBackButton->disable(); - mMediaBrowserControlBackButtonFlag = false; - }; - }; - - // enable/disable browser forward button depending on browser history - if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable() ) - { - if ( ! mMediaBrowserControlForwardButtonFlag ) - { - mMediaBrowserControlForwardButton->enable(); - mMediaBrowserControlForwardButtonFlag = true; - }; - } - else - { - if ( mMediaBrowserControlForwardButtonFlag ) - { - mMediaBrowserControlForwardButton->disable(); - mMediaBrowserControlForwardButtonFlag = false; - }; - }; - - // NOTE: This is *very* slow and not worth optimising - updateStatusBar(); - }; - - // update all the panels - for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index ) - { - mediaPanel *panel = mMediaPanels[ panel_index ]; - - // call plugins idle function so it can potentially update itself - panel->mMediaSource->idle(); - - // update each media panel - updateMediaPanel( panel ); - - LLRect dirty_rect; - if ( ! panel->mMediaSource->textureValid() ) - { - //std::cout << "texture invalid, skipping update..." << std::endl; - } - else - if ( panel && - ( panel->mMediaWidth != panel->mMediaSource->getWidth() || - panel->mMediaHeight != panel->mMediaSource->getHeight() ) ) - { - //std::cout << "Resize in progress, skipping update..." << std::endl; - } - else - if ( panel->mMediaSource->getDirty( &dirty_rect ) ) - { - const unsigned char* pixels = panel->mMediaSource->getBitsData(); - if ( pixels && isTexture(panel->mMediaTextureHandle)) - { - int x_offset = dirty_rect.mLeft; - int y_offset = dirty_rect.mBottom; - int width = dirty_rect.mRight - dirty_rect.mLeft; - int height = dirty_rect.mTop - dirty_rect.mBottom; - - if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight)) - { - // Offset the pixels pointer properly - pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() ); - pixels += ( x_offset * panel->mMediaSource->getTextureDepth() ); - - // set up texture - bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() ); - if ( mFuzzyMedia ) - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - } - else - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - }; - - checkGLError("glTexParameteri"); - - if(panel->mMediaSource->getTextureFormatSwapBytes()) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - checkGLError("glPixelStorei"); - } - - // draw portion that changes into texture - glTexSubImage2D( GL_TEXTURE_2D, 0, - x_offset, - y_offset, - width, - height, - panel->mMediaSource->getTextureFormatPrimary(), - panel->mMediaSource->getTextureFormatType(), - pixels ); - - if(checkGLError("glTexSubImage2D")) - { - std::cerr << " panel ID=" << panel->mId << std::endl; - std::cerr << " texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl; - std::cerr << " media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl; - std::cerr << " dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl; - std::cerr << " texture width = " << panel->mMediaSource->getBitsWidth() << std::endl; - std::cerr << " format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl; - std::cerr << " format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl; - std::cerr << " pixels = " << (void*)pixels << std::endl; - } - - if(panel->mMediaSource->getTextureFormatSwapBytes()) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - checkGLError("glPixelStorei"); - } - - panel->mMediaSource->resetDirty(); - - panel->mReadyToRender = true; - } - else - { - std::cerr << "dirty rect is outside current media size, skipping update" << std::endl; - } - }; - }; - }; - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // trigger re-display - glutPostRedisplay(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::windowPosToTexturePos( int window_x, int window_y, - int& media_x, int& media_y, - int& id ) -{ - if ( ! mSelectedPanel ) - { - media_x = 0; - media_y = 0; - id = 0; - return; - }; - - // record cursor poisiton for a readback next frame - mCurMouseX = window_x; - // OpenGL app == coordinate system this way - // NOTE: unrelated to settings in plugin - this - // is just for this app - mCurMouseY = mWindowHeight - window_y; - - // extract x (0..1023, y (0..1023) and id (0..15) from RGB components - unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ]; - int texture_x = pixel_read_color_bits & 0x3ff; - int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff; - id = ( pixel_read_color_bits >> 20 ) & 0x0f; - - // scale to size of media (1024 because we use 10 bits for X and Y from 24) - media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f ); - media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f ); - - // we assume the plugin uses an inverted coordinate scheme like OpenGL - // if not, the plugin code inverts the Y coordinate for us - we don't need to - media_y = mSelectedPanel->mMediaHeight - media_y; - - if ( media_x > 0 && media_y > 0 ) - { - //std::cout << " mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id << std::endl; - //std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id << std::endl; - //std::cout << " media coords: " << media_x << " x " << media_y << " and id = " << id << std::endl; - //std::cout << std::endl; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::selectPanelById( int id ) -{ - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mId == id ) - { - selectPanel(mMediaPanels[ panel ]); - return; - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::selectPanel( mediaPanel* panel ) -{ - if( mSelectedPanel == panel ) - return; - - // turn off volume before we delete it - if( mSelectedPanel && mSelectedPanel->mMediaSource ) - { - mSelectedPanel->mMediaSource->setVolume( 0.0f ); - mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW ); - }; - - mSelectedPanel = panel; - - if( mSelectedPanel && mSelectedPanel->mMediaSource ) - { - //mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); - mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL ); - - if(!mSelectedPanel->mStartUrl.empty()) - { - mUrlEdit->set_text(const_cast(mSelectedPanel->mStartUrl.c_str()) ); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLFBConnectTest::findMediaPanel( LLPluginClassMedia* source ) -{ - mediaPanel *result = NULL; - - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mMediaSource == source ) - { - result = mMediaPanels[ panel ]; - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLFBConnectTest::findMediaPanel( const std::string &target_name ) -{ - mediaPanel *result = NULL; - - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mTarget == target_name ) - { - result = mMediaPanels[ panel ]; - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::navigateToNewURI( std::string uri ) -{ - if ( uri.length() ) - { - std::string mime_type = mimeTypeFromUrl( uri ); - - if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) ) - { - std::cout << "MIME type is the same" << std::endl; - mSelectedPanel->mMediaSource->loadURI( uri ); - mSelectedPanel->mMediaSource->start(); - mBookmarkList->do_selection( 0 ); - } - else - { - std::cout << "MIME type changed or plugin had exited" << std::endl; - replaceMediaPanel( mSelectedPanel, uri ); - mBookmarkList->do_selection( 0 ); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::initUrlHistory( std::string uris ) -{ - if ( uris.length() > 0 ) - { - std::cout << "init URL : " << uris << std::endl; - LLSD historySD; - - char *cstr, *p; - cstr = new char[uris.size()+1]; - strcpy(cstr, uris.c_str()); - const char *DELIMS = " ,;"; - p = strtok(cstr, DELIMS); - while (p != NULL) { - historySD.insert(0, p); - p = strtok(NULL, DELIMS); - } - mSelectedPanel->mMediaSource->initializeUrlHistory(historySD); - delete[] cstr; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::gluiCallback( int control_id ) -{ - if ( control_id == mIdBookmarks ) - { - std::string uri = mBookmarks[ mSelBookmark ].second; - - navigateToNewURI( uri ); - } - else - if ( control_id == mIdUrlEdit) - { - std::string uri = mUrlEdit->get_text(); - - navigateToNewURI( uri ); - } -/* - else - if ( control_id == mIdUrlInitHistoryEdit ) - { - std::string uri = mUrlInitHistoryEdit->get_text(); - - initUrlHistory( uri ); - } - else - if ( control_id == mIdControlAddPanel ) - { - addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - } - else - if ( control_id == mIdControlRemPanel ) - { - remMediaPanel( mSelectedPanel ); - } - else - if ( control_id == mIdDisableTimeout ) - { - // Set the "disable timeout" flag for all active plugins. - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout); - } - } - else - if ( control_id == mIdUsePluginReadThread ) - { - LLPluginProcessParent::setUseReadThread(mUsePluginReadThread); - } - else - if ( control_id == mIdControlCrashPlugin ) - { - // send message to plugin and ask it to crash - // (switch out for ReleaseCandidate version :) ) - if(mSelectedPanel && mSelectedPanel->mMediaSource) - { - mSelectedPanel->mMediaSource->crashPlugin(); - } - } - else - if ( control_id == mIdControlHangPlugin ) - { - // send message to plugin and ask it to hang - // (switch out for ReleaseCandidate version :) ) - if(mSelectedPanel && mSelectedPanel->mMediaSource) - { - mSelectedPanel->mMediaSource->hangPlugin(); - } - } - else -*/ - if ( control_id == mIdControlExitApp ) - { - // text for exiting plugin system cleanly - delete this; // clean up - exit( 0 ); - } -/* - else - if ( control_id == mIdMediaTimeControlPlay ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlLoop ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( true ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlPause ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->pause(); - } - else - if ( control_id == mIdMediaTimeControlStop ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->stop(); - }; - } - else - if ( control_id == mIdMediaTimeControlSeek ) - { - if ( mSelectedPanel ) - { - // get value from spinner - float seconds_to_seek = mMediaTimeControlSeekSeconds; - mSelectedPanel->mMediaSource->seek( seconds_to_seek ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlRewind ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(-2.0f); - }; - } - else - if ( control_id == mIdMediaTimeControlFastForward ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(2.0f); - }; - } - else -*/ - if ( control_id == mIdMediaBrowserControlBack ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_back(); - } - else - if ( control_id == mIdMediaBrowserControlStop ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_stop(); - } - else - if ( control_id == mIdMediaBrowserControlForward ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_forward(); - } - else - if ( control_id == mIdMediaBrowserControlHome ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl ); - } - else - if ( control_id == mIdMediaBrowserControlReload ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_reload( true ); - } -/* - else - if ( control_id == mIdMediaBrowserControlClearCache ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->clear_cache(); - } - else - if ( control_id == mIdMediaBrowserControlClearCookies ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->clear_cookies(); - } - else - if ( control_id == mIdMediaBrowserControlEnableCookies ) - { - if ( mSelectedPanel ) - { - if ( mMediaBrowserControlEnableCookies ) - { - mSelectedPanel->mMediaSource->enable_cookies( true ); - } - else - { - mSelectedPanel->mMediaSource->enable_cookies( false ); - } - }; - }; -*/ -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::keyboard( int key ) -{ - //if ( key == 'a' || key == 'A' ) - // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - //else - //if ( key == 'r' || key == 'R' ) - // remMediaPanel( mSelectedPanel ); - //else - //if ( key == 'd' || key == 'D' ) - // dumpPanelInfo(); - //else - if ( key == 27 ) - { - std::cout << "Application finished - exiting..." << std::endl; - delete this; - exit( 0 ); - }; - - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD()); - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD()); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::mouseButton( int button, int state, int x, int y ) -{ - if ( button == GLUT_LEFT_BUTTON ) - { - if ( state == GLUT_DOWN ) - { - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 ); - } - else - if ( state == GLUT_UP ) - { - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - // only select a panel if we're on a panel - // (HACK: strictly speaking this rules out clicking on - // the origin of a panel but that's very unlikely) - if ( media_x > 0 && media_y > 0 ) - { - selectPanelById( id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 ); - }; - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::mousePassive( int x, int y ) -{ - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::mouseMove( int x, int y ) -{ - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::makeChrome() -{ - // IDs used by GLUI - int start_id = 0x1000; - - // right side window - geometry manipulators -#if __APPLE__ - // the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways. - // Use a separate controls window in this case. - // GLUI window at right containing manipulation controls and other buttons - int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4; - int y = glutGet(GLUT_WINDOW_Y); - GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y ); -#else - GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT ); -#endif - mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation ); - mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos ); - mViewTranslationCtrl->set_speed( 0.01f ); - mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] ); - mViewScaleCtrl->set_speed( 0.05f ); - right_glui_window->set_main_gfx_window( mAppWindow ); - - // right side window - app controls - /* - mIdControlAddPanel = start_id++; - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper ); - right_glui_window->add_statictext( "" ); - mIdControlRemPanel = start_id++; - right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper ); - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - mIdControlCrashPlugin = start_id++; - right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper ); - mIdControlHangPlugin = start_id++; - right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper ); - */ - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - mIdControlExitApp = start_id++; - right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper ); - - //// top window - holds bookmark UI - mIdBookmarks = start_id++; - mSelBookmark = 0; - GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper ); - // only add the first 50 bookmarks - list can be very long sometimes (30,000+) - // when testing list of media URLs from AGNI for example - for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each ) - mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) ); - glui_window_top->set_main_gfx_window( mAppWindow ); - - glui_window_top->add_column( false ); - mIdUrlEdit = start_id++; - mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper ); - mUrlEdit->set_w( 600 ); - //GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - //mIdUrlInitHistoryEdit = start_id++; - //mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):", - // GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper ); - //mUrlInitHistoryEdit->set_w( 800 ); - - // top window - media controls for "time" media types (e.g. movies) -/* - mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow ); - mIdMediaTimeControlPlay = start_id++; - mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlLoop = start_id++; - mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlPause = start_id++; - mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - - GLUI_Button *button; - mIdMediaTimeControlRewind = start_id++; - button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper ); - button->set_w(30); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlFastForward = start_id++; - button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper ); - button->set_w(30); - - mGluiMediaTimeControlWindow->add_column( true ); - - mIdMediaTimeControlStop = start_id++; - mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlVolume = start_id++; - GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper); - spinner->set_float_limits( 0, 100 ); - mGluiMediaTimeControlWindow->add_column( true ); - mIdMediaTimeControlSeekSeconds = start_id++; - spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper); - spinner->set_float_limits( 0, 200 ); - spinner->set_w( 32 ); - spinner->set_speed( 0.025f ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlSeek = start_id++; - mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); -*/ - - // top window - media controls for "browser" media types (e.g. web browser) - mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow ); - mIdMediaBrowserControlBack = start_id++; - mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlStop = start_id++; - mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlForward = start_id++; - mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlHome = start_id++; - mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlReload = start_id++; - mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - /* - mIdMediaBrowserControlClearCache = start_id++; - mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlClearCookies = start_id++; - mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlEnableCookies = start_id++; - mMediaBrowserControlEnableCookies = 0; - mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper ); - - // top window - misc controls - GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mIdRandomPanelCount = start_id++; - mRandomPanelCount = 0; - glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - mIdRandomBookmarks = start_id++; - mRandomBookmarks = 0; - glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdDisableTimeout = start_id++; - mDisableTimeout = 0; - glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdUsePluginReadThread = start_id++; - mUsePluginReadThread = 0; - glui_window_misc_control->add_checkbox( "Use plugin read thread", &mUsePluginReadThread, mIdUsePluginReadThread, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdLargePanelSpacing = start_id++; - mLargePanelSpacing = 0; - glui_window_misc_control->add_checkbox( "Large Panel Spacing", &mLargePanelSpacing, mIdLargePanelSpacing, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); -*/ - // bottom window - status - mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM ); - mStatusText = mBottomGLUIWindow->add_statictext( "" ); - mBottomGLUIWindow->set_main_gfx_window( mAppWindow ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::resetView() -{ - mViewRotationCtrl->reset(); - - mViewScaleCtrl->set_x( 0.0f ); - mViewScaleCtrl->set_y( 0.0f ); - mViewScaleCtrl->set_z( 1.3f ); - - mViewTranslationCtrl->set_x( 0.0f ); - mViewTranslationCtrl->set_y( 0.0f ); - mViewTranslationCtrl->set_z( 0.0f ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ) -{ - int pick_texture_width = 1024; - int pick_texture_height = 1024; - int pick_texture_depth = 3; - unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ]; - for( int y = 0; y < pick_texture_height; ++y ) - { - for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth ) - { - unsigned long bits = 0L; - bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 ); - unsigned char r_component = ( bits >> 16 ) & 0xff; - unsigned char g_component = ( bits >> 8 ) & 0xff; - unsigned char b_component = bits & 0xff; - - ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component; - ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component; - ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component; - }; - }; - - glGenTextures( 1, texture_handle ); - - checkGLError("glGenTextures"); - std::cout << "glGenTextures returned " << *texture_handle << std::endl; - - bindTexture( *texture_handle ); - glTexImage2D( GL_TEXTURE_2D, 0, - GL_RGB, - pick_texture_width, pick_texture_height, - 0, GL_RGB, GL_UNSIGNED_BYTE, ptr ); - - *texture_pixels = ptr; -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLFBConnectTest::mimeTypeFromUrl( std::string& url ) -{ - // default to web - std::string mime_type = "text/html"; - - // we may need a more advanced MIME type accessor later :-) - if ( url.find( ".mov" ) != std::string::npos ) // Movies - mime_type = "video/quicktime"; - else - if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors - mime_type = "video/quicktime"; - else - if ( url.find( ".mp3" ) != std::string::npos ) // Apple Text descriptors - mime_type = "video/quicktime"; - else - if ( url.find( "example://" ) != std::string::npos ) // Example plugin - mime_type = "example/example"; - - return mime_type; -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLFBConnectTest::pluginNameFromMimeType( std::string& mime_type ) -{ -#if LL_DARWIN - std::string plugin_name( "media_plugin_null.dylib" ); - if ( mime_type == "video/quicktime" ) - plugin_name = "media_plugin_quicktime.dylib"; - else - if ( mime_type == "text/html" ) - plugin_name = "media_plugin_webkit.dylib"; - -#elif LL_WINDOWS - std::string plugin_name( "media_plugin_null.dll" ); - - if ( mime_type == "video/quicktime" ) - plugin_name = "media_plugin_quicktime.dll"; - else - if ( mime_type == "text/html" ) - plugin_name = "media_plugin_webkit.dll"; - else - if ( mime_type == "example/example" ) - plugin_name = "media_plugin_example.dll"; - -#elif LL_LINUX - std::string plugin_name( "libmedia_plugin_null.so" ); - - if ( mime_type == "video/quicktime" ) - plugin_name = "libmedia_plugin_quicktime.so"; - else - if ( mime_type == "text/html" ) - plugin_name = "libmedia_plugin_webkit.so"; -#endif - return plugin_name; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLFBConnectTest::addMediaPanel( std::string url ) -{ - // Get the plugin filename using the URL - std::string mime_type = mimeTypeFromUrl( url ); - std::string plugin_name = pluginNameFromMimeType( mime_type ); - - // create a random size for the new media - int media_width; - int media_height; - getRandomMediaSize( media_width, media_height, mime_type ); - media_width = 1024; - media_height = 1536; - - // make a new plugin - LLPluginClassMedia* media_source = new LLPluginClassMedia(this); - - // enable cookies so the FB login works - media_source->enable_cookies(true); - - // tell the plugin what size we asked for - media_source->setSize( media_width, media_height ); - - // Use the launcher start and initialize the plugin -#if LL_DARWIN || LL_LINUX - std::string launcher_name( "SLPlugin" ); -#elif LL_WINDOWS - std::string launcher_name( "SLPlugin.exe" ); -#endif - - // for this test app, use the cwd as the user data path (ugh). -#if LL_WINDOWS - std::string user_data_path = ".\\"; -#else - char cwd[ FILENAME_MAX ]; - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; - return NULL; - } - std::string user_data_path = std::string( cwd ) + "/"; -#endif - media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, user_data_path, plugin_name, false ); - //media_source->setDisableTimeout(mDisableTimeout); - - // make a new panel and save parameters - mediaPanel* panel = new mediaPanel; - panel->mMediaSource = media_source; - panel->mStartUrl = url; - panel->mMimeType = mime_type; - panel->mMediaWidth = media_width; - panel->mMediaHeight = media_height; - panel->mTextureWidth = 0; - panel->mTextureHeight = 0; - panel->mTextureScaleX = 0; - panel->mTextureScaleY = 0; - panel->mMediaTextureHandle = 0; - panel->mPickTextureHandle = 0; - panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too - panel->mReadyToRender = false; - - // look through current media panels to find an unused index number - bool id_exists = true; - for( int nid = 0; nid < mMaxPanels; ++nid ) - { - // does this id exist already? - id_exists = false; - for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid ) - { - if ( nid == mMediaPanels[ pid ]->mId ) - { - id_exists = true; - break; - }; - }; - - // id wasn't found so we can use it - if ( ! id_exists ) - { - panel->mId = nid; - break; - }; - }; - - // if we get here and this flag is set, there is no room for any more panels - if ( id_exists ) - { - std::cout << "No room for any more panels" << std::endl; - } - else - { - // now we have the ID we can use it to make the - // pick texture (id is baked into texture pixels) - makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); - - // save this in the list of panels - mMediaPanels.push_back( panel ); - - // select the panel that was just created - selectPanel( panel ); - - // load and start the URL - panel->mMediaSource->loadURI( url ); - panel->mMediaSource->start(); - - std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl; - } - - return panel; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::updateMediaPanel( mediaPanel* panel ) -{ -// checkGLError("LLFBConnectTest::updateMediaPanel"); - - if ( ! panel ) - return; - - if(!panel->mMediaSource || !panel->mMediaSource->textureValid()) - { - panel->mReadyToRender = false; - return; - } - - // take a reference copy of the plugin values since they - // might change during this lifetime of this function - int plugin_media_width = panel->mMediaSource->getWidth(); - int plugin_media_height = panel->mMediaSource->getHeight(); - int plugin_texture_width = panel->mMediaSource->getBitsWidth(); - int plugin_texture_height = panel->mMediaSource->getBitsHeight(); - - // If the texture isn't created or the media or texture dimensions changed AND - // the sizes are valid then we need to delete the old media texture (if necessary) - // then make a new one. - if ((panel->mMediaTextureHandle == 0 || - panel->mMediaWidth != plugin_media_width || - panel->mMediaHeight != plugin_media_height || - panel->mTextureWidth != plugin_texture_width || - panel->mTextureHeight != plugin_texture_height) && - ( plugin_media_width > 0 && plugin_media_height > 0 && - plugin_texture_width > 0 && plugin_texture_height > 0 ) ) - { - std::cout << "Valid media size (" << plugin_media_width << " x " << plugin_media_height - << ") and texture size (" << plugin_texture_width << " x " << plugin_texture_height - << ") for panel with ID=" << panel->mId << " - making texture" << std::endl; - - // delete old GL texture - if ( isTexture( panel->mMediaTextureHandle ) ) - { - std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl; - glDeleteTextures( 1, &panel->mMediaTextureHandle ); - panel->mMediaTextureHandle = 0; - } - - std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; - - // make a GL texture based on the dimensions the plugin told us - GLuint new_texture = 0; - glGenTextures( 1, &new_texture ); - - checkGLError("glGenTextures"); - - std::cout << "glGenTextures returned " << new_texture << std::endl; - - panel->mMediaTextureHandle = new_texture; - - bindTexture( panel->mMediaTextureHandle ); - - std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl; - glTexImage2D( GL_TEXTURE_2D, 0, - GL_RGB, - plugin_texture_width, plugin_texture_height, - 0, GL_RGB, GL_UNSIGNED_BYTE, - 0 ); - - - std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; - }; - - // update our record of the media and texture dimensions - // NOTE: do this after we we check for sizes changes - panel->mMediaWidth = plugin_media_width; - panel->mMediaHeight = plugin_media_height; - panel->mTextureWidth = plugin_texture_width; - panel->mTextureHeight = plugin_texture_height; - if ( plugin_texture_width > 0 ) - { - panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth; - }; - if ( plugin_texture_height > 0 ) - { - panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight; - }; - - // update the flag which tells us if the media source uses OprnGL coords or not. - panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL(); - - // Check to see if we have enough to render this panel. - // If we do, set a flag that the display functions use so - // they only render a panel with media if it's ready. - if ( panel->mMediaWidth < 0 || - panel->mMediaHeight < 0 || - panel->mTextureWidth < 1 || - panel->mTextureHeight < 1 || - panel->mMediaTextureHandle == 0 ) - { - panel->mReadyToRender = false; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLFBConnectTest::replaceMediaPanel( mediaPanel* panel, std::string url ) -{ - // no media panels so we can't change anything - have to add - if ( mMediaPanels.size() == 0 ) - return NULL; - - // sanity check - if ( ! panel ) - return NULL; - - int index; - for(index = 0; index < (int)mMediaPanels.size(); index++) - { - if(mMediaPanels[index] == panel) - break; - } - - if(index >= (int)mMediaPanels.size()) - { - // panel isn't in mMediaPanels - return NULL; - } - - std::cout << "Replacing media panel with index " << panel->mId << std::endl; - - int panel_id = panel->mId; - - if(mSelectedPanel == panel) - mSelectedPanel = NULL; - - delete panel; - - // Get the plugin filename using the URL - std::string mime_type = mimeTypeFromUrl( url ); - std::string plugin_name = pluginNameFromMimeType( mime_type ); - - // create a random size for the new media - int media_width; - int media_height; - getRandomMediaSize( media_width, media_height, mime_type ); - - // make a new plugin - LLPluginClassMedia* media_source = new LLPluginClassMedia(this); - - // tell the plugin what size we asked for - media_source->setSize( media_width, media_height ); - - // Use the launcher start and initialize the plugin -#if LL_DARWIN || LL_LINUX - std::string launcher_name( "SLPlugin" ); -#elif LL_WINDOWS - std::string launcher_name( "SLPlugin.exe" ); -#endif - - // for this test app, use the cwd as the user data path (ugh). -#if LL_WINDOWS - std::string user_data_path = ".\\"; -#else - char cwd[ FILENAME_MAX ]; - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; - return NULL; - } - std::string user_data_path = std::string( cwd ) + "/"; -#endif - - media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, user_data_path, plugin_name, false ); - //media_source->setDisableTimeout(mDisableTimeout); - - // make a new panel and save parameters - panel = new mediaPanel; - panel->mMediaSource = media_source; - panel->mStartUrl = url; - panel->mMimeType = mime_type; - panel->mMediaWidth = media_width; - panel->mMediaHeight = media_height; - panel->mTextureWidth = 0; - panel->mTextureHeight = 0; - panel->mTextureScaleX = 0; - panel->mTextureScaleY = 0; - panel->mMediaTextureHandle = 0; - panel->mPickTextureHandle = 0; - panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too - panel->mReadyToRender = false; - - panel->mId = panel_id; - - // Replace the entry in the panels array - mMediaPanels[index] = panel; - - // now we have the ID we can use it to make the - // pick texture (id is baked into texture pixels) - makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); - - // select the panel that was just created - selectPanel( panel ); - - // load and start the URL - panel->mMediaSource->loadURI( url ); - panel->mMediaSource->start(); - - return panel; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::getRandomMediaSize( int& width, int& height, std::string mime_type ) -{ - // Make a new media source with a random size which we'll either - // directly or the media plugin will tell us what it wants later. - // Use a random size so we can test support for weird media sizes. - // (Almost everything else will get filled in later once the - // plugin responds) - // NB. Do we need to enforce that width is on 4 pixel boundary? - width = ( ( rand() % 170 ) + 30 ) * 4; - height = ( ( rand() % 170 ) + 30 ) * 4; - - // adjust this random size if it's a browser so we get - // a more useful size for testing.. - if ( mime_type == "text/html" || mime_type == "example/example" ) - { - width = ( ( rand() % 100 ) + 100 ) * 4; - height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::remMediaPanel( mediaPanel* panel ) -{ - // always leave one panel - if ( mMediaPanels.size() == 1 ) - return; - - // sanity check - don't think this can happen but see above for a case where it might... - if ( ! panel ) - return; - - std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl; - - if(mSelectedPanel == panel) - mSelectedPanel = NULL; - - delete panel; - - // remove from storage list - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - if ( mMediaPanels[ i ] == panel ) - { - mMediaPanels.erase( mMediaPanels.begin() + i ); - break; - }; - }; - - // select the first panel - selectPanel( mMediaPanels[ 0 ] ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::updateStatusBar() -{ - if ( ! mSelectedPanel ) - return; - - // cache results - this is a very slow function - static int cached_id = -1; - static int cached_media_width = -1; - static int cached_media_height = -1; - static int cached_texture_width = -1; - static int cached_texture_height = -1; - static bool cached_supports_browser_media = true; - static bool cached_supports_time_media = false; - static int cached_movie_time = -1; - static GLfloat cached_distance = -1.0f; - - static std::string cached_plugin_version = ""; - if ( - cached_id == mSelectedPanel->mId && - cached_media_width == mSelectedPanel->mMediaWidth && - cached_media_height == mSelectedPanel->mMediaHeight && - cached_texture_width == mSelectedPanel->mTextureWidth && - cached_texture_height == mSelectedPanel->mTextureHeight && - cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() && - cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() && - cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() && - cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() && - cached_distance == mDistanceCameraToSelectedGeometry - ) - { - // nothing changed so don't spend time here - return; - }; - - std::ostringstream stream( "" ); - - stream.str( "" ); - stream.clear(); - - stream << "Id: "; - stream << std::setw( 2 ) << std::setfill( '0' ); - stream << mSelectedPanel->mId; - stream << " | "; - stream << "Media: "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << mSelectedPanel->mMediaWidth; - stream << " x "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << mSelectedPanel->mMediaHeight; - stream << " | "; - stream << "Texture: "; - stream << std::setw( 4 ) << std::setfill( '0' ); - stream << mSelectedPanel->mTextureWidth; - stream << " x "; - stream << std::setw( 4 ) << std::setfill( '0' ); - stream << mSelectedPanel->mTextureHeight; - - stream << " | "; - stream << "Distance: "; - stream << std::setw( 6 ); - stream << std::setprecision( 3 ); - stream << std::setprecision( 3 ); - stream << mDistanceCameraToSelectedGeometry; - stream << " | "; - - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) - stream << "BROWSER"; - else - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - stream << "TIME "; - stream << " | "; - stream << mSelectedPanel->mMediaSource->getPluginVersion(); - stream << " | "; - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - { - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << (int)mSelectedPanel->mMediaSource->getCurrentTime(); - stream << " / "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << (int)mSelectedPanel->mMediaSource->getDuration(); - stream << " @ "; - stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate(); - stream << " | "; - }; - - glutSetWindow( mBottomGLUIWindow->get_glut_window_id() ); - mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) ); - glutSetWindow( mAppWindow ); - - // caching - cached_id = mSelectedPanel->mId; - cached_media_width = mSelectedPanel->mMediaWidth; - cached_media_height = mSelectedPanel->mMediaHeight; - cached_texture_width = mSelectedPanel->mTextureWidth; - cached_texture_height = mSelectedPanel->mTextureHeight; - cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser(); - cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime(); - cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion(); - cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::dumpPanelInfo() -{ - std::cout << std::endl << "===== Media Panels =====" << std::endl; - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - std::cout << std::setw( 2 ) << std::setfill( '0' ); - std::cout << i + 1 << "> "; - std::cout << "Id: "; - std::cout << std::setw( 2 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mId; - std::cout << " | "; - std::cout << "Media: "; - std::cout << std::setw( 3 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mMediaWidth; - std::cout << " x "; - std::cout << std::setw( 3 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mMediaHeight; - std::cout << " | "; - std::cout << "Texture: "; - std::cout << std::setw( 4 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mTextureWidth; - std::cout << " x "; - std::cout << std::setw( 4 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mTextureHeight; - std::cout << " | "; - if ( mMediaPanels[ i ] == mSelectedPanel ) - std::cout << "(selected)"; - - std::cout << std::endl; - }; - std::cout << "========================" << std::endl; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLFBConnectTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) -{ - // Uncomment this to make things much, much quieter. -// return; - - switch(event) - { - case MEDIA_EVENT_CONTENT_UPDATED: - // too spammy -- don't log these -// std::cerr << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << std::endl; - break; - - case MEDIA_EVENT_TIME_DURATION_UPDATED: - // too spammy -- don't log these -// std::cerr << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl; - break; - - case MEDIA_EVENT_SIZE_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_SIZE_CHANGED " << std::endl; - break; - - case MEDIA_EVENT_CURSOR_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl; - break; - - case MEDIA_EVENT_NAVIGATE_BEGIN: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl; - break; - - case MEDIA_EVENT_NAVIGATE_COMPLETE: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl; - break; - - case MEDIA_EVENT_PROGRESS_UPDATED: - std::cerr << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl; - break; - - case MEDIA_EVENT_STATUS_TEXT_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl; - break; - - case MEDIA_EVENT_NAME_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl; - glutSetWindowTitle( self->getMediaName().c_str() ); - break; - - case MEDIA_EVENT_LOCATION_CHANGED: - { - std::cerr << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl; - mediaPanel* panel = findMediaPanel(self); - if(panel != NULL) - { - panel->mStartUrl = self->getLocation(); - if(panel == mSelectedPanel) - { - mUrlEdit->set_text(const_cast(panel->mStartUrl.c_str()) ); - } - } - } - break; - - case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl; - break; - - case MEDIA_EVENT_CLICK_LINK_HREF: - { - std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl; - // retrieve the event parameters - std::string url = self->getClickURL(); - std::string target = self->getClickTarget(); - - if(target == "_external") - { - // this should open in an external browser, but since this is a test app we don't care. - } - else if(target == "_blank") - { - // Create a new panel with the specified URL. - addMediaPanel(url); - } - else // other named target - { - mediaPanel *target_panel = findMediaPanel(target); - if(target_panel) - { - target_panel = replaceMediaPanel(target_panel, url); - } - else - { - target_panel = addMediaPanel(url); - } - - if(target_panel) - { - target_panel->mTarget = target; - } - } - } - break; - - case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: - std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl; - break; - - case MEDIA_EVENT_PLUGIN_FAILED: - std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl; - break; - - case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: - std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl; - break; - - case MEDIA_EVENT_CLOSE_REQUEST: - std::cerr << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << std::endl; - break; - - case MEDIA_EVENT_PICK_FILE_REQUEST: - std::cerr << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl; - // TODO: display an actual file picker - self->sendPickFileResponse("cake"); - break; - - case MEDIA_EVENT_GEOMETRY_CHANGE: - std::cerr << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() - << ", x = " << self->getGeometryX() - << ", y = " << self->getGeometryY() - << ", width = " << self->getGeometryWidth() - << ", height = " << self->getGeometryHeight() - << std::endl; - break; - - case MEDIA_EVENT_AUTH_REQUEST: - { - //std::cerr << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl; - - // TODO: display an auth dialog - self->sendAuthResponse(false, "", ""); - } - break; - - case MEDIA_EVENT_LINK_HOVERED: - { - std::cerr << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl; - } - break; - - default: - { - std::cerr << "Media event: , code is: " << int(event) << std::endl; - } - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -static void gluiCallbackWrapper( int control_id ) -{ - if ( gApplication ) - gApplication->gluiCallback( control_id ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutReshape( int width, int height ) -{ - if ( gApplication ) - gApplication->reshape( width, height ); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutDisplay() -{ - if ( gApplication ) - gApplication->display(); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutIdle(int update_ms) -{ - GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); - - if ( gApplication ) - gApplication->idle(); - -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutKeyboard( unsigned char key, int x, int y ) -{ - if ( gApplication ) - gApplication->keyboard( key ); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMousePassive( int x, int y ) -{ - if ( gApplication ) - gApplication->mousePassive( x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMouseMove( int x , int y ) -{ - if ( gApplication ) - gApplication->mouseMove( x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMouseButton( int button, int state, int x, int y ) -{ - if ( gApplication ) - gApplication->mouseButton( button, state, x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -int main( int argc, char* argv[] ) -{ -#if LL_DARWIN - // Set the current working directory to /Contents/Resources/ - CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if(resources_url != NULL) - { - CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle); - CFRelease(resources_url); - if(resources_string != NULL) - { - char buffer[PATH_MAX] = ""; - if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8)) - { - chdir(buffer); - } - CFRelease(resources_string); - } - } -#endif - - glutInit( &argc, argv ); - glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); - - const int app_window_x = 80; - const int app_window_y = 0; - const int app_window_width = 960; - const int app_window_height = 960; - - glutInitWindowPosition( app_window_x, app_window_y ); - glutInitWindowSize( app_window_width, app_window_height ); - - int app_window_handle = glutCreateWindow( "LLFBConnectTest" ); - - glutDisplayFunc( glutDisplay ); - - GLUI_Master.set_glutReshapeFunc( glutReshape ); - GLUI_Master.set_glutKeyboardFunc( glutKeyboard ); - GLUI_Master.set_glutMouseFunc( glutMouseButton ); - - glutPassiveMotionFunc( glutMousePassive ); - glutMotionFunc( glutMouseMove ); - - glutSetWindow( app_window_handle ); - - gApplication = new LLFBConnectTest( app_window_handle, app_window_width, app_window_height ); - - // update at approximately 60hz - int update_ms = 1000 / 60; - - GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); - - glutMainLoop(); - - delete gApplication; -} diff --git a/indra/test_apps/llfbconnecttest/llfbconnecttest.h b/indra/test_apps/llfbconnecttest/llfbconnecttest.h deleted file mode 100644 index 77e4d096d0..0000000000 --- a/indra/test_apps/llfbconnecttest/llfbconnecttest.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file LLFBConnectTest.cpp - * @brief Facebook Connect Test App - * - * $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$ - */ - -#ifndef LL_FB_CONNECT_H -#define LL_FB_CONNECT_H - -#include -#include -#include "llpluginclassmedia.h" -#include "llgl.h" - -// Forward declarations -class GLUI_Rotation; -class GLUI_Translation; -class GLUI_Listbox; -class GLUI_EditText; -class GLUI_StaticText; -class GLUI; -class GLUI_Button; - -//////////////////////////////////////////////////////////////////////////////// -// -struct mediaPanel -{ - public: - mediaPanel(); - ~mediaPanel(); - int mId; - std::string mStartUrl; - std::string mMimeType; - std::string mTarget; - LLPluginClassMedia *mMediaSource; - int mMediaWidth; - int mMediaHeight; - int mTextureWidth; - int mTextureHeight; - double mTextureScaleX; - double mTextureScaleY; - GLuint mMediaTextureHandle; - GLuint mPickTextureHandle; - unsigned char* mPickTexturePixels; - bool mAppTextureCoordsOpenGL; - bool mReadyToRender; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -class LLFBConnectTest : public LLPluginClassMediaOwner -{ - public: - LLFBConnectTest( int app_window, int window_width, int window_height ); - ~LLFBConnectTest(); - - void reshape( int width, int height ); - void display(); - void idle(); - void gluiCallback( int control_id ); - void keyboard( int key ); - void mousePassive( int x, int y ); - void mouseButton( int button, int state, int x, int y ); - void mouseMove( int x, int y ); - - void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1); - bool checkGLError(const char *name = "OpenGL"); - void drawGeometry( int panel, bool selected ); - void startPanelHighlight( float red, float green, float blue, float line_width ); - void endPanelHighlight(); - enum { DrawTypePickTexture, DrawTypeMediaTexture }; - void draw( int draw_type ); - void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id ); - - mediaPanel* addMediaPanel( std::string url ); - void updateMediaPanel( mediaPanel* panel ); - void remMediaPanel( mediaPanel* panel ); - mediaPanel* replaceMediaPanel( mediaPanel* panel, std::string url ); - void getRandomMediaSize( int& width, int& height, std::string mime_type ); - void navigateToNewURI( std::string uri ); - void initUrlHistory( std::string uri ); - void selectPanelById( int id ); - void selectPanel( mediaPanel* panel ); - mediaPanel* findMediaPanel( LLPluginClassMedia* panel ); - mediaPanel* findMediaPanel( const std::string &target_name ); - void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ); - void makeChrome(); - void resetView(); - - void dumpPanelInfo(); - void updateStatusBar(); - - GLfloat distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z ); - - - // Inherited from LLPluginClassMediaOwner - /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent); - - private: - const int mVersionMajor; - const int mVersionMinor; - const int mVersionPatch; - const int mMaxPanels; - int mAppWindow; - int mWindowWidth; - int mWindowHeight; - int mCurMouseX; - int mCurMouseY; - unsigned char mPixelReadColor[ 3 ]; - bool mFuzzyMedia; - const std::string mHomeWebUrl; - - std::vector< mediaPanel* > mMediaPanels; - mediaPanel* mSelectedPanel; - std::string mimeTypeFromUrl( std::string& url ); - std::string pluginNameFromMimeType( std::string& mime_type ); - - GLUI_Rotation* mViewRotationCtrl; - GLUI_Translation* mViewScaleCtrl; - GLUI_Translation* mViewTranslationCtrl; - float mViewportAspect; - float mViewPos[ 3 ]; - float mViewRotation[ 16 ]; - - float mDistanceCameraToSelectedGeometry; - - std::vector< std::pair< std::string, std::string > > mBookmarks; - GLUI_Listbox* mBookmarkList; - int mIdBookmarks; - int mIdUrlEdit; - GLUI_EditText* mUrlEdit; - int mSelBookmark; - - int mIdControlExitApp; - - GLUI* mGluiMediaBrowserControlWindow; - int mIdMediaBrowserControlBack; - GLUI_Button* mMediaBrowserControlBackButton; - int mIdMediaBrowserControlStop; - int mIdMediaBrowserControlForward; - GLUI_Button* mMediaBrowserControlForwardButton; - bool mGluiMediaBrowserControlWindowFlag; - bool mMediaBrowserControlBackButtonFlag; - bool mMediaBrowserControlForwardButtonFlag; - int mIdMediaBrowserControlHome; - int mIdMediaBrowserControlReload; - - GLUI* mBottomGLUIWindow; - GLUI_StaticText* mStatusText; -}; - -#endif // LL_FB_CONNECT_H - diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt index 0c8bdc464d..18f7e36d20 100755 --- a/indra/test_apps/llplugintest/CMakeLists.txt +++ b/indra/test_apps/llplugintest/CMakeLists.txt @@ -254,138 +254,8 @@ endif (DARWIN) # ) #endif (DARWIN) -### llmediaplugintest - -set(llmediaplugintest_SOURCE_FILES - llmediaplugintest.cpp - llmediaplugintest.h - bookmarks.txt - ) - -add_executable(llmediaplugintest - WIN32 - MACOSX_BUNDLE - ${llmediaplugintest_SOURCE_FILES} -) - -set_target_properties(llmediaplugintest - PROPERTIES - WIN32_EXECUTABLE - FALSE -) - -target_link_libraries(llmediaplugintest - ${GLUT_LIBRARY} - ${GLUI_LIBRARY} - ${OPENGL_LIBRARIES} - ${LLPLUGIN_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) - -if (DARWIN) - # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app. - target_link_libraries(llmediaplugintest - ${COREFOUNDATION_LIBRARY} - ) -endif (DARWIN) - -add_dependencies(llmediaplugintest - stage_third_party_libs - SLPlugin - media_plugin_quicktime - media_plugin_webkit - media_plugin_example - ${LLPLUGIN_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} -) - -# turn off weird GLUI pragma -add_definitions(-DGLUI_NO_LIB_PRAGMA) - -if (DARWIN OR LINUX) - # glui.h contains code that triggers the "overloaded-virtual" warning in gcc. - set_source_files_properties(llmediaplugintest.cpp PROPERTIES COMPILE_FLAGS "-Wno-overloaded-virtual") -endif (DARWIN OR LINUX) - # Gather build products of the various dependencies into the build directory for the testbed. -if (DARWIN) - # path inside the app bundle where we'll need to copy plugins and other related files - set(PLUGINS_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llmediaplugintest.app/Contents/Resources - ) - - # create the Contents/Resources directory - add_custom_command( - TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - make_directory - ${PLUGINS_DESTINATION_DIR} - COMMENT "Creating Resources directory in app bundle." - ) -else (DARWIN) - set(PLUGINS_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - ) -endif (DARWIN) - -set(BUILT_SLPLUGIN $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_SLPLUGIN} -) - -set(BUILT_LLCOMMON $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLCOMMON} -) - -set(BUILT_WEBKIT_PLUGIN $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_WEBKIT_PLUGIN} -) - -if (DARWIN OR WINDOWS) - set(BUILT_QUICKTIME_PLUGIN $) - add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_QUICKTIME_PLUGIN} - ) -endif (DARWIN OR WINDOWS) - -set(BUILT_EXAMPLE_PLUGIN $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_EXAMPLE_PLUGIN} ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_EXAMPLE_PLUGIN} -) - -# copy over bookmarks file if llmediaplugintest gets built -set(BUILT_LLMEDIAPLUGINTEST $) -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/ - DEPENDS ${BUILT_LLMEDIAPLUGINTEST} -) - -# also copy it to the same place as SLPlugin, which is what the mac wants... -add_custom_command(TARGET llmediaplugintest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR} - DEPENDS ${BUILT_LLMEDIAPLUGINTEST} -) - -if (DARWIN) -# add_custom_command(TARGET llmediaplugintest POST_BUILD -# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR} -# DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib -# ) -endif (DARWIN) - if(WINDOWS) #******************** # Plugin test library deploy @@ -402,7 +272,6 @@ if(WINDOWS) qtguid4.dll qtnetworkd4.dll qtopengld4.dll - qtwebkitd4.dll ssleay32.dll ) copy_if_different( @@ -459,7 +328,6 @@ if(WINDOWS) qtgui4.dll qtnetwork4.dll qtopengl4.dll - qtwebkit4.dll qtxmlpatterns4.dll ssleay32.dll ) @@ -534,8 +402,6 @@ if(WINDOWS) ${plugin_test_targets} ) - add_dependencies(llmediaplugintest copy_plugintest_libs) - endif(WINDOWS) if (DARWIN) @@ -553,8 +419,6 @@ if (DARWIN) libQtNetwork.4.dylib libQtOpenGL.4.7.1.dylib libQtOpenGL.4.dylib - libQtWebKit.4.7.1.dylib - libQtWebKit.4.dylib libQtSvg.4.7.1.dylib libQtSvg.4.dylib libQtXml.4.7.1.dylib @@ -607,7 +471,5 @@ if (DARWIN) ${plugin_test_targets} ) - add_dependencies(llmediaplugintest copy_plugintest_libs) endif (DARWIN) -ll_deploy_sharedlibs_command(llmediaplugintest) diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp deleted file mode 100755 index fa4f5abd28..0000000000 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ /dev/null @@ -1,2377 +0,0 @@ -/** - * @file LLMediaPluginTest.cpp - * @brief Primary test application for LLMedia (Separate Process) Plugin system - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, 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$ - */ - -#include "linden_common.h" -#include "indra_constants.h" - -#include "llapr.h" -#include "llerrorcontrol.h" - -#include -#include -#include -#include - -#include "llmediaplugintest.h" - - -#if LL_WINDOWS -#pragma warning(disable: 4263) -#pragma warning(disable: 4264) -#endif - -#if __APPLE__ - #include - #include -#else - #define FREEGLUT_STATIC - #include "GL/freeglut.h" - #define GLUI_FREEGLUT -#endif - -#include "glui.h" - - -LLMediaPluginTest* gApplication = 0; -static void gluiCallbackWrapper( int control_id ); - -//////////////////////////////////////////////////////////////////////////////// -// -static bool isTexture( GLuint texture ) -{ - bool result = false; - - // glIsTexture will sometimes return false for real textures... do this instead. - if(texture != 0) - result = true; - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel::mediaPanel() -{ - mMediaTextureHandle = 0; - mPickTextureHandle = 0; - mMediaSource = NULL; - mPickTexturePixels = NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel::~mediaPanel() -{ - // delete OpenGL texture handles - if ( isTexture( mPickTextureHandle ) ) - { - std::cerr << "remMediaPanel: deleting pick texture " << mPickTextureHandle << std::endl; - glDeleteTextures( 1, &mPickTextureHandle ); - mPickTextureHandle = 0; - } - - if ( isTexture( mMediaTextureHandle ) ) - { - std::cerr << "remMediaPanel: deleting media texture " << mMediaTextureHandle << std::endl; - glDeleteTextures( 1, &mMediaTextureHandle ); - mMediaTextureHandle = 0; - } - - if(mPickTexturePixels) - { - delete mPickTexturePixels; - } - - if(mMediaSource) - { - delete mMediaSource; - } - -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLMediaPluginTest::LLMediaPluginTest( int app_window, int window_width, int window_height ) : - mVersionMajor( 2 ), - mVersionMinor( 0 ), - mVersionPatch( 0 ), - mMaxPanels( 25 ), - mViewportAspect( 0 ), - mAppWindow( app_window ), - mCurMouseX( 0 ), - mCurMouseY( 0 ), - mFuzzyMedia( true ), - mSelectedPanel( 0 ), - mDistanceCameraToSelectedGeometry( 0.0f ), - mMediaBrowserControlEnableCookies( 0 ), - mMediaBrowserControlBackButton( 0 ), - mMediaBrowserControlForwardButton( 0 ), - mMediaTimeControlVolume( 100 ), - mMediaTimeControlSeekSeconds( 0 ), - mGluiMediaTimeControlWindowFlag( true ), - mGluiMediaBrowserControlWindowFlag( true ), - mMediaBrowserControlBackButtonFlag( true ), - mMediaBrowserControlForwardButtonFlag( true ), - mHomeWebUrl( "http://www.google.com/" ) -{ - // debugging spam - std::cout << std::endl << " GLUT version: " << "3.7.6" << std::endl; // no way to get real version from GLUT - std::cout << std::endl << " GLUI version: " << GLUI_Master.get_version() << std::endl; - std::cout << std::endl << "Media Plugin Test version: " << mVersionMajor << "." << mVersionMinor << "." << mVersionPatch << std::endl; - - // bookmark title - mBookmarks.push_back( std::pair< std::string, std::string >( "--- Bookmarks ---", "" ) ); - - // insert hardcoded URLs here as required for testing - //mBookmarks.push_back( std::pair< std::string, std::string >( "description", "url" ) ); - - // read bookmarks from file. - // note: uses command in ./CmakeLists.txt which copies bookmmarks file from source directory - // to app directory (WITHOUT build configuration dir) (this is cwd in Windows within MSVC) - // For example, test_apps\llplugintest and not test_apps\llplugintest\Release - // This may need to be changed for Mac/Linux builds. - // See https://jira.lindenlab.com/browse/DEV-31350 for large list of media URLs from AGNI - const std::string bookmarks_filename( "bookmarks.txt" ); - std::ifstream file_handle( bookmarks_filename.c_str() ); - if ( file_handle.is_open() ) - { - std::cout << "Reading bookmarks for test" << std::endl; - while( ! file_handle.eof() ) - { - std::string line; - std::getline( file_handle, line ); - if ( file_handle.eof() ) - break; - - if ( line.substr( 0, 1 ) != "#" ) - { - size_t comma_pos = line.find_first_of( ',' ); - if ( comma_pos != std::string::npos ) - { - std::string description = line.substr( 0, comma_pos ); - std::string url = line.substr( comma_pos + 1 ); - mBookmarks.push_back( std::pair< std::string, std::string >( description, url ) ); - } - else - { - mBookmarks.push_back( std::pair< std::string, std::string >( line, line ) ); - }; - }; - }; - std::cout << "Read " << mBookmarks.size() << " bookmarks" << std::endl; - } - else - { - std::cout << "Unable to read bookmarks from file: " << bookmarks_filename << std::endl; - }; - - // initialize linden lab APR module - ll_init_apr(); - - // Set up llerror logging - { - LLError::initForApplication("."); - LLError::setDefaultLevel(LLError::LEVEL_INFO); - //LLError::setTagLevel("Plugin", LLError::LEVEL_DEBUG); - } - - // lots of randomness in this app - srand( ( unsigned int )time( 0 ) ); - - // build GUI - makeChrome(); - - // OpenGL initialilzation - glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - glClearDepth( 1.0f ); - glEnable( GL_DEPTH_TEST ); - glEnable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE ); - glDepthFunc( GL_LEQUAL ); - glEnable( GL_TEXTURE_2D ); - glDisable( GL_BLEND ); - glColor3f( 1.0f, 1.0f, 1.0f ); - glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ); - glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); - - // start with a sane view - resetView(); - - // initial media panel - const int num_initial_panels = 1; - for( int i = 0; i < num_initial_panels; ++i ) - { - //addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - addMediaPanel( mHomeWebUrl ); - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLMediaPluginTest::~LLMediaPluginTest() -{ - // delete all media panels - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - remMediaPanel( mMediaPanels[ i ] ); - }; - - // Stop the plugin read thread if it's running. - LLPluginProcessParent::setUseReadThread(false); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::reshape( int width, int height ) -{ - // update viewport (the active window inside the chrome) - int viewport_x, viewport_y; - int viewport_height, viewport_width; - GLUI_Master.get_viewport_area( &viewport_x, &viewport_y, &viewport_width, &viewport_height ); - mViewportAspect = (float)( viewport_width ) / (float)( viewport_height ); - glViewport( viewport_x, viewport_y, viewport_width, viewport_height ); - - // save these as we'll need them later - mWindowWidth = width; - mWindowHeight = height; - - // adjust size of URL bar so it doesn't get clipped - mUrlEdit->set_w( mWindowWidth - 360 ); - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // trigger re-display - glutPostRedisplay(); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::bindTexture(GLuint texture, GLint row_length, GLint alignment) -{ - glEnable( GL_TEXTURE_2D ); - - glBindTexture( GL_TEXTURE_2D, texture ); - glPixelStorei( GL_UNPACK_ROW_LENGTH, row_length ); - glPixelStorei( GL_UNPACK_ALIGNMENT, alignment ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaPluginTest::checkGLError(const char *name) -{ - bool result = false; - GLenum error = glGetError(); - - if(error != GL_NO_ERROR) - { - // For some reason, glGenTextures is returning GL_INVALID_VALUE... - std::cout << name << " ERROR 0x" << std::hex << error << std::dec << std::endl; - result = true; - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -GLfloat LLMediaPluginTest::distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z ) -{ - GLdouble camera_pos_x = 0.0f; - GLdouble camera_pos_y = 0.0f; - GLdouble camera_pos_z = 0.0f; - - GLdouble modelMatrix[16]; - GLdouble projMatrix[16]; - GLint viewport[4]; - - glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projMatrix); - glGetIntegerv(GL_VIEWPORT, viewport); - - gluUnProject( - (viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2, - 0.0, - modelMatrix, projMatrix, viewport, - &camera_pos_x, &camera_pos_y, &camera_pos_z ); - - GLfloat distance = - sqrt( ( camera_pos_x - point_x ) * ( camera_pos_x - point_x ) + - ( camera_pos_y - point_y ) * ( camera_pos_y - point_y ) + - ( camera_pos_z - point_z ) * ( camera_pos_z - point_z ) ); - - return distance; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::drawGeometry( int panel, bool selected ) -{ - // texture coordinates for each panel - GLfloat non_opengl_texture_coords[ 8 ] = { 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f }; - GLfloat opengl_texture_coords[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - - GLfloat *texture_coords = mMediaPanels[ panel ]->mAppTextureCoordsOpenGL?opengl_texture_coords:non_opengl_texture_coords; - - // base coordinates for each panel - GLfloat base_vertex_pos[ 8 ] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f }; - - // calculate posiitons - const int num_panels = (int)mMediaPanels.size(); - const int num_rows = (int)sqrt( (float)num_panels ); - const int num_cols = num_panels / num_rows; - const int panel_x = ( panel / num_rows ); - const int panel_y = ( panel % num_rows ); - - // default spacing is small - make it larger if checkbox set - for testing positional audio - float spacing = 0.1f; - if ( mLargePanelSpacing ) - spacing = 2.0f; - - const GLfloat offset_x = num_cols * ( 1.0 + spacing ) / 2; - const GLfloat offset_y = num_rows * ( 1.0 + spacing ) / 2; - - // Adjust for media aspect ratios - { - float aspect = 1.0f; - - if(mMediaPanels[ panel ]->mMediaHeight != 0) - { - aspect = (float)mMediaPanels[ panel ]->mMediaWidth / (float)mMediaPanels[ panel ]->mMediaHeight; - } - - if(aspect > 1.0f) - { - // media is wider than it is high -- adjust the top and bottom in - for( int corner = 0; corner < 4; ++corner ) - { - float temp = base_vertex_pos[corner * 2 + 1]; - - if(temp < 0.5f) - temp += 0.5 - (0.5f / aspect); - else - temp -= 0.5 - (0.5f / aspect); - - base_vertex_pos[corner * 2 + 1] = temp; - } - } - else if(aspect < 1.0f) - { - // media is higher than it is wide -- adjust the left and right sides in - for( int corner = 0; corner < 4; ++corner ) - { - float temp = base_vertex_pos[corner * 2]; - - if(temp < 0.5f) - temp += 0.5f - (0.5f * aspect); - else - temp -= 0.5f - (0.5f * aspect); - - base_vertex_pos[corner * 2] = temp; - } - } - } - - glBegin( GL_QUADS ); - for( int corner = 0; corner < 4; ++corner ) - { - glTexCoord2f( texture_coords[ corner * 2 ], texture_coords[ corner * 2 + 1 ] ); - GLfloat x = base_vertex_pos[ corner * 2 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f; - GLfloat y = base_vertex_pos[ corner * 2 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f; - - glVertex3f( x, y, 0.0f ); - }; - glEnd(); - - // calculate distance to this panel if it's selected - if ( selected ) - { - GLfloat point_x = base_vertex_pos[ 0 ] + panel_x * ( 1.0 + spacing ) - offset_x + spacing / 2.0f; - GLfloat point_y = base_vertex_pos[ 0 + 1 ] + panel_y * ( 1.0 + spacing ) - offset_y + spacing / 2.0f; - GLfloat point_z = 0.0f; - mDistanceCameraToSelectedGeometry = distanceToCamera( point_x, point_y, point_z ); - }; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::startPanelHighlight( float red, float green, float blue, float line_width ) -{ - glPushAttrib( GL_ALL_ATTRIB_BITS ); - glEnable( GL_POLYGON_OFFSET_FILL ); - glPolygonOffset( -2.5f, -2.5f ); - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - glLineWidth( line_width ); - glColor3f( red, green, blue ); - glDisable( GL_TEXTURE_2D ); -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::endPanelHighlight() -{ - glPopAttrib(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::draw( int draw_type ) -{ - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - // drawing pick texture - if ( draw_type == DrawTypePickTexture ) - { - // only bother with pick if we have something to render - // Actually, we need to pick even if we're not ready to render. - // Otherwise you can't select and remove a panel which has gone bad. - //if ( mMediaPanels[ panel ]->mReadyToRender ) - { - glMatrixMode( GL_TEXTURE ); - glPushMatrix(); - - // pick texture is a power of 2 so no need to scale - glLoadIdentity(); - - // bind to media texture - glLoadIdentity(); - bindTexture( mMediaPanels[ panel ]->mPickTextureHandle ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - - // draw geometry using pick texture - drawGeometry( panel, false ); - - glMatrixMode( GL_TEXTURE ); - glPopMatrix(); - }; - } - else - if ( draw_type == DrawTypeMediaTexture ) - { - bool texture_valid = false; - bool plugin_exited = false; - - if(mMediaPanels[ panel ]->mMediaSource) - { - texture_valid = mMediaPanels[ panel ]->mMediaSource->textureValid(); - plugin_exited = mMediaPanels[ panel ]->mMediaSource->isPluginExited(); - } - - // save texture matrix (changes for each panel) - glMatrixMode( GL_TEXTURE ); - glPushMatrix(); - - // only process texture if the media is ready to draw - // (we still want to draw the geometry) - if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) - { - // bind to media texture - bindTexture( mMediaPanels[ panel ]->mMediaTextureHandle ); - - if ( mFuzzyMedia ) - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - } - else - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - } - - // scale to fit panel - glScalef( mMediaPanels[ panel ]->mTextureScaleX, - mMediaPanels[ panel ]->mTextureScaleY, - 1.0f ); - }; - - float intensity = plugin_exited?0.25f:1.0f; - - // highlight the selected panel - if ( mSelectedPanel && ( mMediaPanels[ panel ]->mId == mSelectedPanel->mId ) ) - { - startPanelHighlight( intensity, intensity, 0.0f, 5.0f ); - drawGeometry( panel, true ); - endPanelHighlight(); - } - else - // this panel not able to render yet since it - // doesn't have enough information - if ( !mMediaPanels[ panel ]->mReadyToRender ) - { - startPanelHighlight( intensity, 0.0f, 0.0f, 2.0f ); - drawGeometry( panel, false ); - endPanelHighlight(); - } - else - // just display a border around the media - { - startPanelHighlight( 0.0f, intensity, 0.0f, 2.0f ); - drawGeometry( panel, false ); - endPanelHighlight(); - }; - - if ( mMediaPanels[ panel ]->mReadyToRender && texture_valid ) - { - // draw visual geometry - drawGeometry( panel, false ); - } - - // restore texture matrix (changes for each panel) - glMatrixMode( GL_TEXTURE ); - glPopMatrix(); - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::display() -{ - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // start with a clean slate - glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - // set up OpenGL view - glMatrixMode( GL_PROJECTION ); - glLoadIdentity(); - glFrustum( -mViewportAspect * 0.04f, mViewportAspect * 0.04f, -0.04f, 0.04f, 0.1f, 50.0f ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); - glTranslatef( 0.0, 0.0, 0.0f ); - glTranslatef( mViewPos[ 0 ], mViewPos[ 1 ], -mViewPos[ 2 ] ); - glMultMatrixf( mViewRotation ); - - // draw pick texture - draw( DrawTypePickTexture ); - - // read colors and get coordinate values - glReadPixels( mCurMouseX, mCurMouseY, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, mPixelReadColor ); - - // clear the pick render (otherwise it may depth-fight with the textures rendered later) - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - - // draw visible geometry - draw( DrawTypeMediaTexture ); - - glutSwapBuffers(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::idle() -{ -// checkGLError("LLMediaPluginTest::idle"); - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // random creation/destruction of panels enabled? - const time_t panel_timeout_time = 5; - if ( mRandomPanelCount ) - { - // time for a change - static time_t last_panel_time = 0; - if ( time( NULL ) - last_panel_time > panel_timeout_time ) - { - if ( rand() % 2 == 0 ) - { - if ( mMediaPanels.size() < 16 ) - { - std::cout << "Randomly adding new panel" << std::endl; - addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - }; - } - else - { - if ( mMediaPanels.size() > 0 ) - { - std::cout << "Deleting selected panel" << std::endl; - remMediaPanel( mSelectedPanel ); - }; - }; - time( &last_panel_time ); - }; - }; - - // random selection of bookmarks enabled? - const time_t bookmark_timeout_time = 5; - if ( mRandomBookmarks ) - { - // time for a change - static time_t last_bookmark_time = 0; - if ( time( NULL ) - last_bookmark_time > bookmark_timeout_time ) - { - // go to a different random bookmark on each panel - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - std::string uri = mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second; - - std::cout << "Random: navigating to : " << uri << std::endl; - - std::string mime_type = mimeTypeFromUrl( uri ); - - if ( mime_type != mMediaPanels[ panel ]->mMimeType ) - { - replaceMediaPanel( mMediaPanels[ panel ], uri ); - } - else - { - mMediaPanels[ panel ]->mMediaSource->loadURI( uri ); - mMediaPanels[ panel ]->mMediaSource->start(); - }; - }; - - time( &last_bookmark_time ); - }; - }; - - // update UI - if ( mSelectedPanel ) - { - // set volume based on slider if we have time media - //if ( mGluiMediaTimeControlWindowFlag ) - //{ - // mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); - //}; - - // NOTE: it is absurd that we need cache the state of GLUI controls - // but enabling/disabling controls drags framerate from 500+ - // down to 15. Not a problem for plugin system - only this test - // enable/disable time based UI controls based on type of plugin - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - { - if ( ! mGluiMediaTimeControlWindowFlag ) - { - mGluiMediaTimeControlWindow->enable(); - mGluiMediaTimeControlWindowFlag = true; - }; - } - else - { - if ( mGluiMediaTimeControlWindowFlag ) - { - mGluiMediaTimeControlWindow->disable(); - mGluiMediaTimeControlWindowFlag = false; - }; - }; - - // enable/disable browser based UI controls based on type of plugin - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) - { - if ( ! mGluiMediaBrowserControlWindowFlag ) - { - mGluiMediaBrowserControlWindow->enable(); - mGluiMediaBrowserControlWindowFlag = true; - }; - } - else - { - if ( mGluiMediaBrowserControlWindowFlag ) - { - mGluiMediaBrowserControlWindow->disable(); - mGluiMediaBrowserControlWindowFlag = false; - }; - }; - - // enable/disable browser back button depending on browser history - if ( mSelectedPanel->mMediaSource->getHistoryBackAvailable() ) - { - if ( ! mMediaBrowserControlBackButtonFlag ) - { - mMediaBrowserControlBackButton->enable(); - mMediaBrowserControlBackButtonFlag = true; - }; - } - else - { - if ( mMediaBrowserControlBackButtonFlag ) - { - mMediaBrowserControlBackButton->disable(); - mMediaBrowserControlBackButtonFlag = false; - }; - }; - - // enable/disable browser forward button depending on browser history - if ( mSelectedPanel->mMediaSource->getHistoryForwardAvailable() ) - { - if ( ! mMediaBrowserControlForwardButtonFlag ) - { - mMediaBrowserControlForwardButton->enable(); - mMediaBrowserControlForwardButtonFlag = true; - }; - } - else - { - if ( mMediaBrowserControlForwardButtonFlag ) - { - mMediaBrowserControlForwardButton->disable(); - mMediaBrowserControlForwardButtonFlag = false; - }; - }; - - // NOTE: This is *very* slow and not worth optimising - updateStatusBar(); - }; - - // update all the panels - for( int panel_index = 0; panel_index < (int)mMediaPanels.size(); ++panel_index ) - { - mediaPanel *panel = mMediaPanels[ panel_index ]; - - // call plugins idle function so it can potentially update itself - panel->mMediaSource->idle(); - - // update each media panel - updateMediaPanel( panel ); - - LLRect dirty_rect; - if ( ! panel->mMediaSource->textureValid() ) - { - //std::cout << "texture invalid, skipping update..." << std::endl; - } - else - if ( panel && - ( panel->mMediaWidth != panel->mMediaSource->getWidth() || - panel->mMediaHeight != panel->mMediaSource->getHeight() ) ) - { - //std::cout << "Resize in progress, skipping update..." << std::endl; - } - else - if ( panel->mMediaSource->getDirty( &dirty_rect ) ) - { - const unsigned char* pixels = panel->mMediaSource->getBitsData(); - if ( pixels && isTexture(panel->mMediaTextureHandle)) - { - int x_offset = dirty_rect.mLeft; - int y_offset = dirty_rect.mBottom; - int width = dirty_rect.mRight - dirty_rect.mLeft; - int height = dirty_rect.mTop - dirty_rect.mBottom; - - if((dirty_rect.mRight <= panel->mTextureWidth) && (dirty_rect.mTop <= panel->mTextureHeight)) - { - // Offset the pixels pointer properly - pixels += ( y_offset * panel->mMediaSource->getTextureDepth() * panel->mMediaSource->getBitsWidth() ); - pixels += ( x_offset * panel->mMediaSource->getTextureDepth() ); - - // set up texture - bindTexture( panel->mMediaTextureHandle, panel->mMediaSource->getBitsWidth() ); - if ( mFuzzyMedia ) - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - } - else - { - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - }; - - checkGLError("glTexParameteri"); - - if(panel->mMediaSource->getTextureFormatSwapBytes()) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); - checkGLError("glPixelStorei"); - } - - // draw portion that changes into texture - glTexSubImage2D( GL_TEXTURE_2D, 0, - x_offset, - y_offset, - width, - height, - panel->mMediaSource->getTextureFormatPrimary(), - panel->mMediaSource->getTextureFormatType(), - pixels ); - - if(checkGLError("glTexSubImage2D")) - { - std::cerr << " panel ID=" << panel->mId << std::endl; - std::cerr << " texture size = " << panel->mTextureWidth << " x " << panel->mTextureHeight << std::endl; - std::cerr << " media size = " << panel->mMediaWidth << " x " << panel->mMediaHeight << std::endl; - std::cerr << " dirty rect = " << dirty_rect.mLeft << ", " << dirty_rect.mBottom << ", " << dirty_rect.mRight << ", " << dirty_rect.mTop << std::endl; - std::cerr << " texture width = " << panel->mMediaSource->getBitsWidth() << std::endl; - std::cerr << " format primary = 0x" << std::hex << panel->mMediaSource->getTextureFormatPrimary() << std::dec << std::endl; - std::cerr << " format type = 0x" << std::hex << panel->mMediaSource->getTextureFormatType() << std::dec << std::endl; - std::cerr << " pixels = " << (void*)pixels << std::endl; - } - - if(panel->mMediaSource->getTextureFormatSwapBytes()) - { - glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); - checkGLError("glPixelStorei"); - } - - panel->mMediaSource->resetDirty(); - - panel->mReadyToRender = true; - } - else - { - std::cerr << "dirty rect is outside current media size, skipping update" << std::endl; - } - }; - }; - }; - - // GLUI requires this - if ( glutGetWindow() != mAppWindow ) - glutSetWindow( mAppWindow ); - - // trigger re-display - glutPostRedisplay(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::windowPosToTexturePos( int window_x, int window_y, - int& media_x, int& media_y, - int& id ) -{ - if ( ! mSelectedPanel ) - { - media_x = 0; - media_y = 0; - id = 0; - return; - }; - - // record cursor poisiton for a readback next frame - mCurMouseX = window_x; - // OpenGL app == coordinate system this way - // NOTE: unrelated to settings in plugin - this - // is just for this app - mCurMouseY = mWindowHeight - window_y; - - // extract x (0..1023, y (0..1023) and id (0..15) from RGB components - unsigned long pixel_read_color_bits = ( mPixelReadColor[ 0 ] << 16 ) | ( mPixelReadColor[ 1 ] << 8 ) | mPixelReadColor[ 2 ]; - int texture_x = pixel_read_color_bits & 0x3ff; - int texture_y = ( pixel_read_color_bits >> 10 ) & 0x3ff; - id = ( pixel_read_color_bits >> 20 ) & 0x0f; - - // scale to size of media (1024 because we use 10 bits for X and Y from 24) - media_x = (int)( ( (float)mSelectedPanel->mMediaWidth * (float)texture_x ) / 1024.0f ); - media_y = (int)( ( (float)mSelectedPanel->mMediaHeight * (float)texture_y ) / 1024.0f ); - - // we assume the plugin uses an inverted coordinate scheme like OpenGL - // if not, the plugin code inverts the Y coordinate for us - we don't need to - media_y = mSelectedPanel->mMediaHeight - media_y; - - if ( media_x > 0 && media_y > 0 ) - { - //std::cout << " mouse coords: " << mCurMouseX << " x " << mCurMouseY << " and id = " << id << std::endl; - //std::cout << "raw texture coords: " << texture_x << " x " << texture_y << " and id = " << id << std::endl; - //std::cout << " media coords: " << media_x << " x " << media_y << " and id = " << id << std::endl; - //std::cout << std::endl; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::selectPanelById( int id ) -{ - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mId == id ) - { - selectPanel(mMediaPanels[ panel ]); - return; - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::selectPanel( mediaPanel* panel ) -{ - if( mSelectedPanel == panel ) - return; - - // turn off volume before we delete it - if( mSelectedPanel && mSelectedPanel->mMediaSource ) - { - mSelectedPanel->mMediaSource->setVolume( 0.0f ); - mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_LOW ); - }; - - mSelectedPanel = panel; - - if( mSelectedPanel && mSelectedPanel->mMediaSource ) - { - mSelectedPanel->mMediaSource->setVolume( (float)mMediaTimeControlVolume / 100.0f ); - mSelectedPanel->mMediaSource->setPriority( LLPluginClassMedia::PRIORITY_NORMAL ); - - if(!mSelectedPanel->mStartUrl.empty()) - { - mUrlEdit->set_text(const_cast(mSelectedPanel->mStartUrl.c_str()) ); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLMediaPluginTest::findMediaPanel( LLPluginClassMedia* source ) -{ - mediaPanel *result = NULL; - - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mMediaSource == source ) - { - result = mMediaPanels[ panel ]; - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLMediaPluginTest::findMediaPanel( const std::string &target_name ) -{ - mediaPanel *result = NULL; - - for( int panel = 0; panel < (int)mMediaPanels.size(); ++panel ) - { - if ( mMediaPanels[ panel ]->mTarget == target_name ) - { - result = mMediaPanels[ panel ]; - } - } - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::navigateToNewURI( std::string uri ) -{ - if ( uri.length() ) - { - std::string mime_type = mimeTypeFromUrl( uri ); - - if ( !mSelectedPanel->mMediaSource->isPluginExited() && (mime_type == mSelectedPanel->mMimeType) ) - { - std::cout << "MIME type is the same" << std::endl; - mSelectedPanel->mMediaSource->loadURI( uri ); - mSelectedPanel->mMediaSource->start(); - mBookmarkList->do_selection( 0 ); - } - else - { - std::cout << "MIME type changed or plugin had exited" << std::endl; - replaceMediaPanel( mSelectedPanel, uri ); - mBookmarkList->do_selection( 0 ); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::initUrlHistory( std::string uris ) -{ - if ( uris.length() > 0 ) - { - std::cout << "init URL : " << uris << std::endl; - LLSD historySD; - - char *cstr, *p; - cstr = new char[uris.size()+1]; - strcpy(cstr, uris.c_str()); - const char *DELIMS = " ,;"; - p = strtok(cstr, DELIMS); - while (p != NULL) { - historySD.insert(0, p); - p = strtok(NULL, DELIMS); - } - mSelectedPanel->mMediaSource->initializeUrlHistory(historySD); - delete[] cstr; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::gluiCallback( int control_id ) -{ - if ( control_id == mIdBookmarks ) - { - std::string uri = mBookmarks[ mSelBookmark ].second; - - navigateToNewURI( uri ); - } - else - if ( control_id == mIdUrlEdit) - { - std::string uri = mUrlEdit->get_text(); - - navigateToNewURI( uri ); - } - else - if ( control_id == mIdUrlInitHistoryEdit ) - { - std::string uri = mUrlInitHistoryEdit->get_text(); - - initUrlHistory( uri ); - } - else - if ( control_id == mIdControlAddPanel ) - { - addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - } - else - if ( control_id == mIdControlRemPanel ) - { - remMediaPanel( mSelectedPanel ); - } - else - if ( control_id == mIdDisableTimeout ) - { - // Set the "disable timeout" flag for all active plugins. - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - mMediaPanels[ i ]->mMediaSource->setDisableTimeout(mDisableTimeout); - } - } - else - if ( control_id == mIdUsePluginReadThread ) - { - LLPluginProcessParent::setUseReadThread(mUsePluginReadThread); - } - else - if ( control_id == mIdControlCrashPlugin ) - { - // send message to plugin and ask it to crash - // (switch out for ReleaseCandidate version :) ) - if(mSelectedPanel && mSelectedPanel->mMediaSource) - { - mSelectedPanel->mMediaSource->crashPlugin(); - } - } - else - if ( control_id == mIdControlHangPlugin ) - { - // send message to plugin and ask it to hang - // (switch out for ReleaseCandidate version :) ) - if(mSelectedPanel && mSelectedPanel->mMediaSource) - { - mSelectedPanel->mMediaSource->hangPlugin(); - } - } - else - if ( control_id == mIdControlExitApp ) - { - // text for exiting plugin system cleanly - delete this; // clean up - exit( 0 ); - } - else - if ( control_id == mIdMediaTimeControlPlay ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlLoop ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( true ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlPause ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->pause(); - } - else - if ( control_id == mIdMediaTimeControlStop ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->stop(); - }; - } - else - if ( control_id == mIdMediaTimeControlSeek ) - { - if ( mSelectedPanel ) - { - // get value from spinner - float seconds_to_seek = mMediaTimeControlSeekSeconds; - mSelectedPanel->mMediaSource->seek( seconds_to_seek ); - mSelectedPanel->mMediaSource->start(); - }; - } - else - if ( control_id == mIdMediaTimeControlRewind ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(-2.0f); - }; - } - else - if ( control_id == mIdMediaTimeControlFastForward ) - { - if ( mSelectedPanel ) - { - mSelectedPanel->mMediaSource->setLoop( false ); - mSelectedPanel->mMediaSource->start(2.0f); - }; - } - else - if ( control_id == mIdMediaBrowserControlBack ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_back(); - } - else - if ( control_id == mIdMediaBrowserControlStop ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_stop(); - } - else - if ( control_id == mIdMediaBrowserControlForward ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_forward(); - } - else - if ( control_id == mIdMediaBrowserControlHome ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->loadURI( mHomeWebUrl ); - } - else - if ( control_id == mIdMediaBrowserControlReload ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->browse_reload( true ); - } - else - if ( control_id == mIdMediaBrowserControlClearCache ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->clear_cache(); - } - else - if ( control_id == mIdMediaBrowserControlClearCookies ) - { - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->clear_cookies(); - } - else - if ( control_id == mIdMediaBrowserControlEnableCookies ) - { - if ( mSelectedPanel ) - { - if ( mMediaBrowserControlEnableCookies ) - { - mSelectedPanel->mMediaSource->enable_cookies( true ); - } - else - { - mSelectedPanel->mMediaSource->enable_cookies( false ); - } - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::keyboard( int key ) -{ - //if ( key == 'a' || key == 'A' ) - // addMediaPanel( mBookmarks[ rand() % ( mBookmarks.size() - 1 ) + 1 ].second ); - //else - //if ( key == 'r' || key == 'R' ) - // remMediaPanel( mSelectedPanel ); - //else - //if ( key == 'd' || key == 'D' ) - // dumpPanelInfo(); - //else - if ( key == 27 ) - { - std::cout << "Application finished - exiting..." << std::endl; - delete this; - exit( 0 ); - }; - - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_DOWN, key, 0 , LLSD()); - mSelectedPanel->mMediaSource->keyEvent( LLPluginClassMedia::KEY_EVENT_UP, key, 0, LLSD()); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::mouseButton( int button, int state, int x, int y ) -{ - if ( button == GLUT_LEFT_BUTTON ) - { - if ( state == GLUT_DOWN ) - { - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_DOWN, 0, media_x, media_y, 0 ); - } - else - if ( state == GLUT_UP ) - { - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - // only select a panel if we're on a panel - // (HACK: strictly speaking this rules out clicking on - // the origin of a panel but that's very unlikely) - if ( media_x > 0 && media_y > 0 ) - { - selectPanelById( id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_UP, 0, media_x, media_y, 0 ); - }; - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::mousePassive( int x, int y ) -{ - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::mouseMove( int x, int y ) -{ - int media_x, media_y, id; - windowPosToTexturePos( x, y, media_x, media_y, id ); - - if ( mSelectedPanel ) - mSelectedPanel->mMediaSource->mouseEvent( LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, media_x, media_y, 0 ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::makeChrome() -{ - // IDs used by GLUI - int start_id = 0x1000; - - // right side window - geometry manipulators -#if __APPLE__ - // the Apple GLUT implementation doesn't seem to set the graphic offset of subwindows correctly when they overlap in certain ways. - // Use a separate controls window in this case. - // GLUI window at right containing manipulation controls and other buttons - int x = glutGet(GLUT_WINDOW_X) + glutGet(GLUT_WINDOW_WIDTH) + 4; - int y = glutGet(GLUT_WINDOW_Y); - GLUI* right_glui_window = GLUI_Master.create_glui( "", 0, x, y ); -#else - GLUI* right_glui_window = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_RIGHT ); -#endif - mViewRotationCtrl = right_glui_window->add_rotation( "Rotation", mViewRotation ); - mViewTranslationCtrl = right_glui_window->add_translation( "Translate", GLUI_TRANSLATION_XY, mViewPos ); - mViewTranslationCtrl->set_speed( 0.01f ); - mViewScaleCtrl = right_glui_window->add_translation( "Scale", GLUI_TRANSLATION_Z, &mViewPos[ 2 ] ); - mViewScaleCtrl->set_speed( 0.05f ); - right_glui_window->set_main_gfx_window( mAppWindow ); - - // right side window - app controls - mIdControlAddPanel = start_id++; - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - right_glui_window->add_button( "Add panel", mIdControlAddPanel, gluiCallbackWrapper ); - right_glui_window->add_statictext( "" ); - mIdControlRemPanel = start_id++; - right_glui_window->add_button( "Rem panel", mIdControlRemPanel, gluiCallbackWrapper ); - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - mIdControlCrashPlugin = start_id++; - right_glui_window->add_button( "Crash plugin", mIdControlCrashPlugin, gluiCallbackWrapper ); - mIdControlHangPlugin = start_id++; - right_glui_window->add_button( "Hang plugin", mIdControlHangPlugin, gluiCallbackWrapper ); - - right_glui_window->add_statictext( "" ); - right_glui_window->add_separator(); - right_glui_window->add_statictext( "" ); - mIdControlExitApp = start_id++; - right_glui_window->add_button( "Exit app", mIdControlExitApp, gluiCallbackWrapper ); - - //// top window - holds bookmark UI - mIdBookmarks = start_id++; - mSelBookmark = 0; - GLUI* glui_window_top = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mBookmarkList = glui_window_top->add_listbox( "", &mSelBookmark, mIdBookmarks, gluiCallbackWrapper ); - // only add the first 50 bookmarks - list can be very long sometimes (30,000+) - // when testing list of media URLs from AGNI for example - for( unsigned int each = 0; each < mBookmarks.size() && each < 50; ++each ) - mBookmarkList->add_item( each, const_cast< char* >( mBookmarks[ each ].first.c_str() ) ); - glui_window_top->set_main_gfx_window( mAppWindow ); - - glui_window_top->add_column( false ); - mIdUrlEdit = start_id++; - mUrlEdit = glui_window_top->add_edittext( "Url:", GLUI_EDITTEXT_TEXT, 0, mIdUrlEdit, gluiCallbackWrapper ); - mUrlEdit->set_w( 600 ); - GLUI* glui_window_top2 = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mIdUrlInitHistoryEdit = start_id++; - mUrlInitHistoryEdit = glui_window_top2->add_edittext( "Init History (separate by commas or semicolons):", - GLUI_EDITTEXT_TEXT, 0, mIdUrlInitHistoryEdit, gluiCallbackWrapper ); - mUrlInitHistoryEdit->set_w( 800 ); - - // top window - media controls for "time" media types (e.g. movies) - mGluiMediaTimeControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mGluiMediaTimeControlWindow->set_main_gfx_window( mAppWindow ); - mIdMediaTimeControlPlay = start_id++; - mGluiMediaTimeControlWindow->add_button( "PLAY", mIdMediaTimeControlPlay, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlLoop = start_id++; - mGluiMediaTimeControlWindow->add_button( "LOOP", mIdMediaTimeControlLoop, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlPause = start_id++; - mGluiMediaTimeControlWindow->add_button( "PAUSE", mIdMediaTimeControlPause, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - - GLUI_Button *button; - mIdMediaTimeControlRewind = start_id++; - button = mGluiMediaTimeControlWindow->add_button( "<<", mIdMediaTimeControlRewind, gluiCallbackWrapper ); - button->set_w(30); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlFastForward = start_id++; - button = mGluiMediaTimeControlWindow->add_button( ">>", mIdMediaTimeControlFastForward, gluiCallbackWrapper ); - button->set_w(30); - - mGluiMediaTimeControlWindow->add_column( true ); - - mIdMediaTimeControlStop = start_id++; - mGluiMediaTimeControlWindow->add_button( "STOP", mIdMediaTimeControlStop, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlVolume = start_id++; - GLUI_Spinner* spinner = mGluiMediaTimeControlWindow->add_spinner( "Volume", 2, &mMediaTimeControlVolume, mIdMediaTimeControlVolume, gluiCallbackWrapper); - spinner->set_float_limits( 0, 100 ); - mGluiMediaTimeControlWindow->add_column( true ); - mIdMediaTimeControlSeekSeconds = start_id++; - spinner = mGluiMediaTimeControlWindow->add_spinner( "", 2, &mMediaTimeControlSeekSeconds, mIdMediaTimeControlSeekSeconds, gluiCallbackWrapper); - spinner->set_float_limits( 0, 200 ); - spinner->set_w( 32 ); - spinner->set_speed( 0.025f ); - mGluiMediaTimeControlWindow->add_column( false ); - mIdMediaTimeControlSeek = start_id++; - mGluiMediaTimeControlWindow->add_button( "SEEK", mIdMediaTimeControlSeek, gluiCallbackWrapper ); - mGluiMediaTimeControlWindow->add_column( false ); - - - // top window - media controls for "browser" media types (e.g. web browser) - mGluiMediaBrowserControlWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mGluiMediaBrowserControlWindow->set_main_gfx_window( mAppWindow ); - mIdMediaBrowserControlBack = start_id++; - mMediaBrowserControlBackButton = mGluiMediaBrowserControlWindow->add_button( "BACK", mIdMediaBrowserControlBack, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlStop = start_id++; - mGluiMediaBrowserControlWindow->add_button( "STOP", mIdMediaBrowserControlStop, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlForward = start_id++; - mMediaBrowserControlForwardButton = mGluiMediaBrowserControlWindow->add_button( "FORWARD", mIdMediaBrowserControlForward, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlHome = start_id++; - mGluiMediaBrowserControlWindow->add_button( "HOME", mIdMediaBrowserControlHome, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlReload = start_id++; - mGluiMediaBrowserControlWindow->add_button( "RELOAD", mIdMediaBrowserControlReload, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlClearCache = start_id++; - mGluiMediaBrowserControlWindow->add_button( "CLEAR CACHE", mIdMediaBrowserControlClearCache, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlClearCookies = start_id++; - mGluiMediaBrowserControlWindow->add_button( "CLEAR COOKIES", mIdMediaBrowserControlClearCookies, gluiCallbackWrapper ); - mGluiMediaBrowserControlWindow->add_column( false ); - mIdMediaBrowserControlEnableCookies = start_id++; - mMediaBrowserControlEnableCookies = 0; - mGluiMediaBrowserControlWindow->add_checkbox( "Enable Cookies", &mMediaBrowserControlEnableCookies, mIdMediaBrowserControlEnableCookies, gluiCallbackWrapper ); - - // top window - misc controls - GLUI* glui_window_misc_control = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_TOP ); - mIdRandomPanelCount = start_id++; - mRandomPanelCount = 0; - glui_window_misc_control->add_checkbox( "Randomize panel count", &mRandomPanelCount, mIdRandomPanelCount, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - mIdRandomBookmarks = start_id++; - mRandomBookmarks = 0; - glui_window_misc_control->add_checkbox( "Randomize bookmarks", &mRandomBookmarks, mIdRandomBookmarks, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdDisableTimeout = start_id++; - mDisableTimeout = 0; - glui_window_misc_control->add_checkbox( "Disable plugin timeout", &mDisableTimeout, mIdDisableTimeout, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdUsePluginReadThread = start_id++; - mUsePluginReadThread = 0; - glui_window_misc_control->add_checkbox( "Use plugin read thread", &mUsePluginReadThread, mIdUsePluginReadThread, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - mIdLargePanelSpacing = start_id++; - mLargePanelSpacing = 0; - glui_window_misc_control->add_checkbox( "Large Panel Spacing", &mLargePanelSpacing, mIdLargePanelSpacing, gluiCallbackWrapper ); - glui_window_misc_control->set_main_gfx_window( mAppWindow ); - glui_window_misc_control->add_column( true ); - - // bottom window - status - mBottomGLUIWindow = GLUI_Master.create_glui_subwindow( mAppWindow, GLUI_SUBWINDOW_BOTTOM ); - mStatusText = mBottomGLUIWindow->add_statictext( "" ); - mBottomGLUIWindow->set_main_gfx_window( mAppWindow ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::resetView() -{ - mViewRotationCtrl->reset(); - - mViewScaleCtrl->set_x( 0.0f ); - mViewScaleCtrl->set_y( 0.0f ); - mViewScaleCtrl->set_z( 3.0f ); - - mViewTranslationCtrl->set_x( 0.0f ); - mViewTranslationCtrl->set_y( 0.0f ); - mViewTranslationCtrl->set_z( 0.0f ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ) -{ - int pick_texture_width = 1024; - int pick_texture_height = 1024; - int pick_texture_depth = 3; - unsigned char* ptr = new unsigned char[ pick_texture_width * pick_texture_height * pick_texture_depth ]; - for( int y = 0; y < pick_texture_height; ++y ) - { - for( int x = 0; x < pick_texture_width * pick_texture_depth ; x += pick_texture_depth ) - { - unsigned long bits = 0L; - bits |= ( id << 20 ) | ( y << 10 ) | ( x / 3 ); - unsigned char r_component = ( bits >> 16 ) & 0xff; - unsigned char g_component = ( bits >> 8 ) & 0xff; - unsigned char b_component = bits & 0xff; - - ptr[ y * pick_texture_width * pick_texture_depth + x + 0 ] = r_component; - ptr[ y * pick_texture_width * pick_texture_depth + x + 1 ] = g_component; - ptr[ y * pick_texture_width * pick_texture_depth + x + 2 ] = b_component; - }; - }; - - glGenTextures( 1, texture_handle ); - - checkGLError("glGenTextures"); - std::cout << "glGenTextures returned " << *texture_handle << std::endl; - - bindTexture( *texture_handle ); - glTexImage2D( GL_TEXTURE_2D, 0, - GL_RGB, - pick_texture_width, pick_texture_height, - 0, GL_RGB, GL_UNSIGNED_BYTE, ptr ); - - *texture_pixels = ptr; -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLMediaPluginTest::mimeTypeFromUrl( std::string& url ) -{ - // default to web - std::string mime_type = "text/html"; - - // we may need a more advanced MIME type accessor later :-) - if ( url.find( ".mov" ) != std::string::npos ) // Movies - mime_type = "video/quicktime"; - else - if ( url.find( ".txt" ) != std::string::npos ) // Apple Text descriptors - mime_type = "video/quicktime"; - else - if ( url.find( ".mp3" ) != std::string::npos ) // Apple Text descriptors - mime_type = "video/quicktime"; - else - if ( url.find( "example://" ) != std::string::npos ) // Example plugin - mime_type = "example/example"; - - return mime_type; -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLMediaPluginTest::pluginNameFromMimeType( std::string& mime_type ) -{ -#if LL_DARWIN - std::string plugin_name( "media_plugin_null.dylib" ); - if ( mime_type == "video/quicktime" ) - plugin_name = "media_plugin_quicktime.dylib"; - else - if ( mime_type == "text/html" ) - plugin_name = "media_plugin_webkit.dylib"; - -#elif LL_WINDOWS - std::string plugin_name( "media_plugin_null.dll" ); - - if ( mime_type == "video/quicktime" ) - plugin_name = "media_plugin_quicktime.dll"; - else - if ( mime_type == "text/html" ) - plugin_name = "media_plugin_webkit.dll"; - else - if ( mime_type == "example/example" ) - plugin_name = "media_plugin_example.dll"; - -#elif LL_LINUX - std::string plugin_name( "libmedia_plugin_null.so" ); - - if ( mime_type == "video/quicktime" ) - plugin_name = "libmedia_plugin_quicktime.so"; - else - if ( mime_type == "text/html" ) - plugin_name = "libmedia_plugin_webkit.so"; -#endif - return plugin_name; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLMediaPluginTest::addMediaPanel( std::string url ) -{ - // Get the plugin filename using the URL - std::string mime_type = mimeTypeFromUrl( url ); - std::string plugin_name = pluginNameFromMimeType( mime_type ); - - // create a random size for the new media - int media_width; - int media_height; - getRandomMediaSize( media_width, media_height, mime_type ); - - // make a new plugin - LLPluginClassMedia* media_source = new LLPluginClassMedia(this); - - // tell the plugin what size we asked for - media_source->setSize( media_width, media_height ); - - // Use the launcher start and initialize the plugin -#if LL_DARWIN || LL_LINUX - std::string launcher_name( "SLPlugin" ); -#elif LL_WINDOWS - std::string launcher_name( "SLPlugin.exe" ); -#endif - - // for this test app, use the cwd as the user data path (ugh). -#if LL_WINDOWS - std::string user_data_path = ".\\"; -#else - char cwd[ FILENAME_MAX ]; - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; - return NULL; - } - std::string user_data_path = std::string( cwd ) + "/"; -#endif - media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, user_data_path, plugin_name, false ); - media_source->setDisableTimeout(mDisableTimeout); - - // make a new panel and save parameters - mediaPanel* panel = new mediaPanel; - panel->mMediaSource = media_source; - panel->mStartUrl = url; - panel->mMimeType = mime_type; - panel->mMediaWidth = media_width; - panel->mMediaHeight = media_height; - panel->mTextureWidth = 0; - panel->mTextureHeight = 0; - panel->mTextureScaleX = 0; - panel->mTextureScaleY = 0; - panel->mMediaTextureHandle = 0; - panel->mPickTextureHandle = 0; - panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too - panel->mReadyToRender = false; - - // look through current media panels to find an unused index number - bool id_exists = true; - for( int nid = 0; nid < mMaxPanels; ++nid ) - { - // does this id exist already? - id_exists = false; - for( int pid = 0; pid < (int)mMediaPanels.size(); ++pid ) - { - if ( nid == mMediaPanels[ pid ]->mId ) - { - id_exists = true; - break; - }; - }; - - // id wasn't found so we can use it - if ( ! id_exists ) - { - panel->mId = nid; - break; - }; - }; - - // if we get here and this flag is set, there is no room for any more panels - if ( id_exists ) - { - std::cout << "No room for any more panels" << std::endl; - } - else - { - // now we have the ID we can use it to make the - // pick texture (id is baked into texture pixels) - makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); - - // save this in the list of panels - mMediaPanels.push_back( panel ); - - // select the panel that was just created - selectPanel( panel ); - - // load and start the URL - panel->mMediaSource->loadURI( url ); - panel->mMediaSource->start(); - - std::cout << "Adding new media panel for " << url << "(" << media_width << "x" << media_height << ") with index " << panel->mId << " - total panels = " << mMediaPanels.size() << std::endl; - } - - return panel; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::updateMediaPanel( mediaPanel* panel ) -{ -// checkGLError("LLMediaPluginTest::updateMediaPanel"); - - if ( ! panel ) - return; - - if(!panel->mMediaSource || !panel->mMediaSource->textureValid()) - { - panel->mReadyToRender = false; - return; - } - - // take a reference copy of the plugin values since they - // might change during this lifetime of this function - int plugin_media_width = panel->mMediaSource->getWidth(); - int plugin_media_height = panel->mMediaSource->getHeight(); - int plugin_texture_width = panel->mMediaSource->getBitsWidth(); - int plugin_texture_height = panel->mMediaSource->getBitsHeight(); - - // If the texture isn't created or the media or texture dimensions changed AND - // the sizes are valid then we need to delete the old media texture (if necessary) - // then make a new one. - if ((panel->mMediaTextureHandle == 0 || - panel->mMediaWidth != plugin_media_width || - panel->mMediaHeight != plugin_media_height || - panel->mTextureWidth != plugin_texture_width || - panel->mTextureHeight != plugin_texture_height) && - ( plugin_media_width > 0 && plugin_media_height > 0 && - plugin_texture_width > 0 && plugin_texture_height > 0 ) ) - { - std::cout << "Valid media size (" << plugin_media_width << " x " << plugin_media_height - << ") and texture size (" << plugin_texture_width << " x " << plugin_texture_height - << ") for panel with ID=" << panel->mId << " - making texture" << std::endl; - - // delete old GL texture - if ( isTexture( panel->mMediaTextureHandle ) ) - { - std::cerr << "updateMediaPanel: deleting texture " << panel->mMediaTextureHandle << std::endl; - glDeleteTextures( 1, &panel->mMediaTextureHandle ); - panel->mMediaTextureHandle = 0; - } - - std::cerr << "before: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; - - // make a GL texture based on the dimensions the plugin told us - GLuint new_texture = 0; - glGenTextures( 1, &new_texture ); - - checkGLError("glGenTextures"); - - std::cout << "glGenTextures returned " << new_texture << std::endl; - - panel->mMediaTextureHandle = new_texture; - - bindTexture( panel->mMediaTextureHandle ); - - std::cout << "Setting texture size to " << plugin_texture_width << " x " << plugin_texture_height << std::endl; - glTexImage2D( GL_TEXTURE_2D, 0, - GL_RGB, - plugin_texture_width, plugin_texture_height, - 0, GL_RGB, GL_UNSIGNED_BYTE, - 0 ); - - - std::cerr << "after: pick texture is " << panel->mPickTextureHandle << ", media texture is " << panel->mMediaTextureHandle << std::endl; - }; - - // update our record of the media and texture dimensions - // NOTE: do this after we we check for sizes changes - panel->mMediaWidth = plugin_media_width; - panel->mMediaHeight = plugin_media_height; - panel->mTextureWidth = plugin_texture_width; - panel->mTextureHeight = plugin_texture_height; - if ( plugin_texture_width > 0 ) - { - panel->mTextureScaleX = (double)panel->mMediaWidth / (double)panel->mTextureWidth; - }; - if ( plugin_texture_height > 0 ) - { - panel->mTextureScaleY = (double)panel->mMediaHeight / (double)panel->mTextureHeight; - }; - - // update the flag which tells us if the media source uses OprnGL coords or not. - panel->mAppTextureCoordsOpenGL = panel->mMediaSource->getTextureCoordsOpenGL(); - - // Check to see if we have enough to render this panel. - // If we do, set a flag that the display functions use so - // they only render a panel with media if it's ready. - if ( panel->mMediaWidth < 0 || - panel->mMediaHeight < 0 || - panel->mTextureWidth < 1 || - panel->mTextureHeight < 1 || - panel->mMediaTextureHandle == 0 ) - { - panel->mReadyToRender = false; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -mediaPanel* LLMediaPluginTest::replaceMediaPanel( mediaPanel* panel, std::string url ) -{ - // no media panels so we can't change anything - have to add - if ( mMediaPanels.size() == 0 ) - return NULL; - - // sanity check - if ( ! panel ) - return NULL; - - int index; - for(index = 0; index < (int)mMediaPanels.size(); index++) - { - if(mMediaPanels[index] == panel) - break; - } - - if(index >= (int)mMediaPanels.size()) - { - // panel isn't in mMediaPanels - return NULL; - } - - std::cout << "Replacing media panel with index " << panel->mId << std::endl; - - int panel_id = panel->mId; - - if(mSelectedPanel == panel) - mSelectedPanel = NULL; - - delete panel; - - // Get the plugin filename using the URL - std::string mime_type = mimeTypeFromUrl( url ); - std::string plugin_name = pluginNameFromMimeType( mime_type ); - - // create a random size for the new media - int media_width; - int media_height; - getRandomMediaSize( media_width, media_height, mime_type ); - - // make a new plugin - LLPluginClassMedia* media_source = new LLPluginClassMedia(this); - - // tell the plugin what size we asked for - media_source->setSize( media_width, media_height ); - - // Use the launcher start and initialize the plugin -#if LL_DARWIN || LL_LINUX - std::string launcher_name( "SLPlugin" ); -#elif LL_WINDOWS - std::string launcher_name( "SLPlugin.exe" ); -#endif - - // for this test app, use the cwd as the user data path (ugh). -#if LL_WINDOWS - std::string user_data_path = ".\\"; -#else - char cwd[ FILENAME_MAX ]; - if (NULL == getcwd( cwd, FILENAME_MAX - 1 )) - { - std::cerr << "Couldn't get cwd - probably too long - failing to init." << std::endl; - return NULL; - } - std::string user_data_path = std::string( cwd ) + "/"; -#endif - - media_source->setUserDataPath(user_data_path); - media_source->init( launcher_name, user_data_path, plugin_name, false ); - media_source->setDisableTimeout(mDisableTimeout); - - // make a new panel and save parameters - panel = new mediaPanel; - panel->mMediaSource = media_source; - panel->mStartUrl = url; - panel->mMimeType = mime_type; - panel->mMediaWidth = media_width; - panel->mMediaHeight = media_height; - panel->mTextureWidth = 0; - panel->mTextureHeight = 0; - panel->mTextureScaleX = 0; - panel->mTextureScaleY = 0; - panel->mMediaTextureHandle = 0; - panel->mPickTextureHandle = 0; - panel->mAppTextureCoordsOpenGL = false; // really need an 'undefined' state here too - panel->mReadyToRender = false; - - panel->mId = panel_id; - - // Replace the entry in the panels array - mMediaPanels[index] = panel; - - // now we have the ID we can use it to make the - // pick texture (id is baked into texture pixels) - makePickTexture( panel->mId, &panel->mPickTextureHandle, &panel->mPickTexturePixels ); - - // select the panel that was just created - selectPanel( panel ); - - // load and start the URL - panel->mMediaSource->loadURI( url ); - panel->mMediaSource->start(); - - return panel; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::getRandomMediaSize( int& width, int& height, std::string mime_type ) -{ - // Make a new media source with a random size which we'll either - // directly or the media plugin will tell us what it wants later. - // Use a random size so we can test support for weird media sizes. - // (Almost everything else will get filled in later once the - // plugin responds) - // NB. Do we need to enforce that width is on 4 pixel boundary? - width = ( ( rand() % 170 ) + 30 ) * 4; - height = ( ( rand() % 170 ) + 30 ) * 4; - - // adjust this random size if it's a browser so we get - // a more useful size for testing.. - if ( mime_type == "text/html" || mime_type == "example/example" ) - { - width = ( ( rand() % 100 ) + 100 ) * 4; - height = ( width * ( ( rand() % 400 ) + 1000 ) ) / 1000; - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::remMediaPanel( mediaPanel* panel ) -{ - // always leave one panel - if ( mMediaPanels.size() == 1 ) - return; - - // sanity check - don't think this can happen but see above for a case where it might... - if ( ! panel ) - return; - - std::cout << "Removing media panel with index " << panel->mId << " - total panels = " << mMediaPanels.size() - 1 << std::endl; - - if(mSelectedPanel == panel) - mSelectedPanel = NULL; - - delete panel; - - // remove from storage list - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - if ( mMediaPanels[ i ] == panel ) - { - mMediaPanels.erase( mMediaPanels.begin() + i ); - break; - }; - }; - - // select the first panel - selectPanel( mMediaPanels[ 0 ] ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::updateStatusBar() -{ - if ( ! mSelectedPanel ) - return; - - // cache results - this is a very slow function - static int cached_id = -1; - static int cached_media_width = -1; - static int cached_media_height = -1; - static int cached_texture_width = -1; - static int cached_texture_height = -1; - static bool cached_supports_browser_media = true; - static bool cached_supports_time_media = false; - static int cached_movie_time = -1; - static GLfloat cached_distance = -1.0f; - - static std::string cached_plugin_version = ""; - if ( - cached_id == mSelectedPanel->mId && - cached_media_width == mSelectedPanel->mMediaWidth && - cached_media_height == mSelectedPanel->mMediaHeight && - cached_texture_width == mSelectedPanel->mTextureWidth && - cached_texture_height == mSelectedPanel->mTextureHeight && - cached_supports_browser_media == mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() && - cached_supports_time_media == mSelectedPanel->mMediaSource->pluginSupportsMediaTime() && - cached_plugin_version == mSelectedPanel->mMediaSource->getPluginVersion() && - cached_movie_time == (int)mSelectedPanel->mMediaSource->getCurrentTime() && - cached_distance == mDistanceCameraToSelectedGeometry - ) - { - // nothing changed so don't spend time here - return; - }; - - std::ostringstream stream( "" ); - - stream.str( "" ); - stream.clear(); - - stream << "Id: "; - stream << std::setw( 2 ) << std::setfill( '0' ); - stream << mSelectedPanel->mId; - stream << " | "; - stream << "Media: "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << mSelectedPanel->mMediaWidth; - stream << " x "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << mSelectedPanel->mMediaHeight; - stream << " | "; - stream << "Texture: "; - stream << std::setw( 4 ) << std::setfill( '0' ); - stream << mSelectedPanel->mTextureWidth; - stream << " x "; - stream << std::setw( 4 ) << std::setfill( '0' ); - stream << mSelectedPanel->mTextureHeight; - - stream << " | "; - stream << "Distance: "; - stream << std::setw( 6 ); - stream << std::setprecision( 3 ); - stream << std::setprecision( 3 ); - stream << mDistanceCameraToSelectedGeometry; - stream << " | "; - - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser() ) - stream << "BROWSER"; - else - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - stream << "TIME "; - stream << " | "; - stream << mSelectedPanel->mMediaSource->getPluginVersion(); - stream << " | "; - if ( mSelectedPanel->mMediaSource->pluginSupportsMediaTime() ) - { - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << (int)mSelectedPanel->mMediaSource->getCurrentTime(); - stream << " / "; - stream << std::setw( 3 ) << std::setfill( '0' ); - stream << (int)mSelectedPanel->mMediaSource->getDuration(); - stream << " @ "; - stream << (int)mSelectedPanel->mMediaSource->getCurrentPlayRate(); - stream << " | "; - }; - - glutSetWindow( mBottomGLUIWindow->get_glut_window_id() ); - mStatusText->set_text( const_cast< char*>( stream.str().c_str() ) ); - glutSetWindow( mAppWindow ); - - // caching - cached_id = mSelectedPanel->mId; - cached_media_width = mSelectedPanel->mMediaWidth; - cached_media_height = mSelectedPanel->mMediaHeight; - cached_texture_width = mSelectedPanel->mTextureWidth; - cached_texture_height = mSelectedPanel->mTextureHeight; - cached_supports_browser_media = mSelectedPanel->mMediaSource->pluginSupportsMediaBrowser(); - cached_supports_time_media = mSelectedPanel->mMediaSource->pluginSupportsMediaTime(); - cached_plugin_version = mSelectedPanel->mMediaSource->getPluginVersion(); - cached_movie_time = (int)mSelectedPanel->mMediaSource->getCurrentTime(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::dumpPanelInfo() -{ - std::cout << std::endl << "===== Media Panels =====" << std::endl; - for( int i = 0; i < (int)mMediaPanels.size(); ++i ) - { - std::cout << std::setw( 2 ) << std::setfill( '0' ); - std::cout << i + 1 << "> "; - std::cout << "Id: "; - std::cout << std::setw( 2 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mId; - std::cout << " | "; - std::cout << "Media: "; - std::cout << std::setw( 3 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mMediaWidth; - std::cout << " x "; - std::cout << std::setw( 3 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mMediaHeight; - std::cout << " | "; - std::cout << "Texture: "; - std::cout << std::setw( 4 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mTextureWidth; - std::cout << " x "; - std::cout << std::setw( 4 ) << std::setfill( '0' ); - std::cout << mMediaPanels[ i ]->mTextureHeight; - std::cout << " | "; - if ( mMediaPanels[ i ] == mSelectedPanel ) - std::cout << "(selected)"; - - std::cout << std::endl; - }; - std::cout << "========================" << std::endl; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) -{ - // Uncomment this to make things much, much quieter. -// return; - - switch(event) - { - case MEDIA_EVENT_CONTENT_UPDATED: - // too spammy -- don't log these -// std::cerr << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << std::endl; - break; - - case MEDIA_EVENT_TIME_DURATION_UPDATED: - // too spammy -- don't log these -// std::cerr << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << std::endl; - break; - - case MEDIA_EVENT_SIZE_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_SIZE_CHANGED " << std::endl; - break; - - case MEDIA_EVENT_CURSOR_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << std::endl; - break; - - case MEDIA_EVENT_NAVIGATE_BEGIN: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN " << std::endl; - break; - - case MEDIA_EVENT_NAVIGATE_COMPLETE: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << std::endl; - break; - - case MEDIA_EVENT_PROGRESS_UPDATED: - std::cerr << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << std::endl; - break; - - case MEDIA_EVENT_STATUS_TEXT_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << std::endl; - break; - - case MEDIA_EVENT_NAME_CHANGED: - std::cerr << "Media event: MEDIA_EVENT_NAME_CHANGED, new name is: " << self->getMediaName() << std::endl; - glutSetWindowTitle( self->getMediaName().c_str() ); - break; - - case MEDIA_EVENT_LOCATION_CHANGED: - { - std::cerr << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << std::endl; - mediaPanel* panel = findMediaPanel(self); - if(panel != NULL) - { - panel->mStartUrl = self->getLocation(); - if(panel == mSelectedPanel) - { - mUrlEdit->set_text(const_cast(panel->mStartUrl.c_str()) ); - } - } - } - break; - - case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: - std::cerr << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl; - break; - - case MEDIA_EVENT_CLICK_LINK_HREF: - { - std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl; - // retrieve the event parameters - std::string url = self->getClickURL(); - std::string target = self->getClickTarget(); - - if(target == "_external") - { - // this should open in an external browser, but since this is a test app we don't care. - } - else if(target == "_blank") - { - // Create a new panel with the specified URL. - addMediaPanel(url); - } - else // other named target - { - mediaPanel *target_panel = findMediaPanel(target); - if(target_panel) - { - target_panel = replaceMediaPanel(target_panel, url); - } - else - { - target_panel = addMediaPanel(url); - } - - if(target_panel) - { - target_panel->mTarget = target; - } - } - } - break; - - case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: - std::cerr << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << std::endl; - break; - - case MEDIA_EVENT_PLUGIN_FAILED: - std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << std::endl; - break; - - case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: - std::cerr << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << std::endl; - break; - - case MEDIA_EVENT_CLOSE_REQUEST: - std::cerr << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << std::endl; - break; - - case MEDIA_EVENT_PICK_FILE_REQUEST: - std::cerr << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << std::endl; - // TODO: display an actual file picker - self->sendPickFileResponse("cake"); - break; - - case MEDIA_EVENT_GEOMETRY_CHANGE: - std::cerr << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() - << ", x = " << self->getGeometryX() - << ", y = " << self->getGeometryY() - << ", width = " << self->getGeometryWidth() - << ", height = " << self->getGeometryHeight() - << std::endl; - break; - - case MEDIA_EVENT_AUTH_REQUEST: - { - //std::cerr << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl; - - // TODO: display an auth dialog - self->sendAuthResponse(false, "", ""); - } - break; - - case MEDIA_EVENT_LINK_HOVERED: - { - std::cerr << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl; - } - break; - - default: - { - std::cerr << "Media event: , code is: " << int(event) << std::endl; - } - break; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -static void gluiCallbackWrapper( int control_id ) -{ - if ( gApplication ) - gApplication->gluiCallback( control_id ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutReshape( int width, int height ) -{ - if ( gApplication ) - gApplication->reshape( width, height ); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutDisplay() -{ - if ( gApplication ) - gApplication->display(); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutIdle(int update_ms) -{ - GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); - - if ( gApplication ) - gApplication->idle(); - -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutKeyboard( unsigned char key, int x, int y ) -{ - if ( gApplication ) - gApplication->keyboard( key ); -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMousePassive( int x, int y ) -{ - if ( gApplication ) - gApplication->mousePassive( x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMouseMove( int x , int y ) -{ - if ( gApplication ) - gApplication->mouseMove( x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void glutMouseButton( int button, int state, int x, int y ) -{ - if ( gApplication ) - gApplication->mouseButton( button, state, x, y ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -int main( int argc, char* argv[] ) -{ -#if LL_DARWIN - // Set the current working directory to /Contents/Resources/ - CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if(resources_url != NULL) - { - CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle); - CFRelease(resources_url); - if(resources_string != NULL) - { - char buffer[PATH_MAX] = ""; - if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8)) - { - chdir(buffer); - } - CFRelease(resources_string); - } - } -#endif - - glutInit( &argc, argv ); - glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); - - const int app_window_x = 80; - const int app_window_y = 0; - const int app_window_width = 960; - const int app_window_height = 960; - - glutInitWindowPosition( app_window_x, app_window_y ); - glutInitWindowSize( app_window_width, app_window_height ); - - int app_window_handle = glutCreateWindow( "LLMediaPluginTest" ); - - glutDisplayFunc( glutDisplay ); - - GLUI_Master.set_glutReshapeFunc( glutReshape ); - GLUI_Master.set_glutKeyboardFunc( glutKeyboard ); - GLUI_Master.set_glutMouseFunc( glutMouseButton ); - - glutPassiveMotionFunc( glutMousePassive ); - glutMotionFunc( glutMouseMove ); - - glutSetWindow( app_window_handle ); - - gApplication = new LLMediaPluginTest( app_window_handle, app_window_width, app_window_height ); - - // update at approximately 60hz - int update_ms = 1000 / 60; - - GLUI_Master.set_glutTimerFunc( update_ms, glutIdle, update_ms); - - glutMainLoop(); - - delete gApplication; -} diff --git a/indra/test_apps/llplugintest/llmediaplugintest.h b/indra/test_apps/llplugintest/llmediaplugintest.h deleted file mode 100755 index 1f6f18e43c..0000000000 --- a/indra/test_apps/llplugintest/llmediaplugintest.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - * @file LLMediaPluginTest.cpp - * @brief Primary test application for LLMedia (Separate Process) Plugin system - * - * $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$ - */ - -#ifndef LL_MEDIA_PLUGIN_TEST_H -#define LL_MEDIA_PLUGIN_TEST_H - -#include -#include -#include "llpluginclassmedia.h" -#include "llgl.h" - -// Forward declarations -class GLUI_Rotation; -class GLUI_Translation; -class GLUI_Listbox; -class GLUI_EditText; -class GLUI_StaticText; -class GLUI; -class GLUI_Button; - -//////////////////////////////////////////////////////////////////////////////// -// -struct mediaPanel -{ - public: - mediaPanel(); - ~mediaPanel(); - int mId; - std::string mStartUrl; - std::string mMimeType; - std::string mTarget; - LLPluginClassMedia *mMediaSource; - int mMediaWidth; - int mMediaHeight; - int mTextureWidth; - int mTextureHeight; - double mTextureScaleX; - double mTextureScaleY; - GLuint mMediaTextureHandle; - GLuint mPickTextureHandle; - unsigned char* mPickTexturePixels; - bool mAppTextureCoordsOpenGL; - bool mReadyToRender; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -class LLMediaPluginTest : public LLPluginClassMediaOwner -{ - public: - LLMediaPluginTest( int app_window, int window_width, int window_height ); - ~LLMediaPluginTest(); - - void reshape( int width, int height ); - void display(); - void idle(); - void gluiCallback( int control_id ); - void keyboard( int key ); - void mousePassive( int x, int y ); - void mouseButton( int button, int state, int x, int y ); - void mouseMove( int x, int y ); - - void bindTexture(GLuint texture, GLint row_length = 0, GLint alignment = 1); - bool checkGLError(const char *name = "OpenGL"); - void drawGeometry( int panel, bool selected ); - void startPanelHighlight( float red, float green, float blue, float line_width ); - void endPanelHighlight(); - enum { DrawTypePickTexture, DrawTypeMediaTexture }; - void draw( int draw_type ); - void windowPosToTexturePos( int window_x, int window_y, int& media_x, int& media_y, int& id ); - - mediaPanel* addMediaPanel( std::string url ); - void updateMediaPanel( mediaPanel* panel ); - void remMediaPanel( mediaPanel* panel ); - mediaPanel* replaceMediaPanel( mediaPanel* panel, std::string url ); - void getRandomMediaSize( int& width, int& height, std::string mime_type ); - void navigateToNewURI( std::string uri ); - void initUrlHistory( std::string uri ); - void selectPanelById( int id ); - void selectPanel( mediaPanel* panel ); - mediaPanel* findMediaPanel( LLPluginClassMedia* panel ); - mediaPanel* findMediaPanel( const std::string &target_name ); - void makePickTexture( int id, GLuint* texture_handle, unsigned char** texture_pixels ); - void makeChrome(); - void resetView(); - - void dumpPanelInfo(); - void updateStatusBar(); - - GLfloat distanceToCamera( GLfloat point_x, GLfloat point_y, GLfloat point_z ); - - - // Inherited from LLPluginClassMediaOwner - /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent); - - private: - const int mVersionMajor; - const int mVersionMinor; - const int mVersionPatch; - const int mMaxPanels; - int mAppWindow; - int mWindowWidth; - int mWindowHeight; - int mCurMouseX; - int mCurMouseY; - unsigned char mPixelReadColor[ 3 ]; - bool mFuzzyMedia; - const std::string mHomeWebUrl; - - std::vector< mediaPanel* > mMediaPanels; - mediaPanel* mSelectedPanel; - std::string mimeTypeFromUrl( std::string& url ); - std::string pluginNameFromMimeType( std::string& mime_type ); - - GLUI_Rotation* mViewRotationCtrl; - GLUI_Translation* mViewScaleCtrl; - GLUI_Translation* mViewTranslationCtrl; - float mViewportAspect; - float mViewPos[ 3 ]; - float mViewRotation[ 16 ]; - - float mDistanceCameraToSelectedGeometry; - - int mIdControlAddPanel; - int mIdControlRemPanel; - - std::vector< std::pair< std::string, std::string > > mBookmarks; - GLUI_Listbox* mBookmarkList; - int mIdBookmarks; - int mIdUrlEdit; - GLUI_EditText* mUrlEdit; - int mIdUrlInitHistoryEdit; - GLUI_EditText* mUrlInitHistoryEdit; - int mSelBookmark; - int mIdRandomPanelCount; - int mRandomPanelCount; - int mIdRandomBookmarks; - int mRandomBookmarks; - int mIdDisableTimeout; - int mDisableTimeout; - int mIdUsePluginReadThread; - int mUsePluginReadThread; - int mIdLargePanelSpacing; - int mLargePanelSpacing; - int mIdControlCrashPlugin; - int mIdControlHangPlugin; - int mIdControlExitApp; - - GLUI* mGluiMediaTimeControlWindow; - int mIdMediaTimeControlPlay; - int mIdMediaTimeControlLoop; - int mIdMediaTimeControlPause; - int mIdMediaTimeControlStop; - int mIdMediaTimeControlSeek; - int mIdMediaTimeControlVolume; - int mMediaTimeControlVolume; - int mIdMediaTimeControlSeekSeconds; - int mMediaTimeControlSeekSeconds; - int mIdMediaTimeControlRewind; - int mIdMediaTimeControlFastForward; - - GLUI* mGluiMediaBrowserControlWindow; - int mIdMediaBrowserControlBack; - GLUI_Button* mMediaBrowserControlBackButton; - int mIdMediaBrowserControlStop; - int mIdMediaBrowserControlForward; - GLUI_Button* mMediaBrowserControlForwardButton; - bool mGluiMediaTimeControlWindowFlag; - bool mGluiMediaBrowserControlWindowFlag; - bool mMediaBrowserControlBackButtonFlag; - bool mMediaBrowserControlForwardButtonFlag; - int mIdMediaBrowserControlHome; - int mIdMediaBrowserControlReload; - int mIdMediaBrowserControlClearCache; - int mIdMediaBrowserControlClearCookies; - int mIdMediaBrowserControlEnableCookies; - int mMediaBrowserControlEnableCookies; - - GLUI* mBottomGLUIWindow; - GLUI_StaticText* mStatusText; -}; - -#endif // LL_MEDIA_PLUGIN_TEST_H - -- cgit v1.2.3