diff --git a/linden/indra/cmake/LLXML.cmake b/linden/indra/cmake/LLXML.cmake index 1ce93c0..7313c75 100644 --- a/linden/indra/cmake/LLXML.cmake +++ b/linden/indra/cmake/LLXML.cmake @@ -7,7 +7,4 @@ set(LLXML_INCLUDE_DIRS ${EXPAT_INCLUDE_DIRS} ) -set(LLXML_LIBRARIES - llxml - ${EXPAT_LIBRARIES} - ) +set(LLXML_LIBRARIES llxml) diff --git a/linden/indra/llxml/CMakeLists.txt b/linden/indra/llxml/CMakeLists.txt index d86bc0d..9febd97 100644 --- a/linden/indra/llxml/CMakeLists.txt +++ b/linden/indra/llxml/CMakeLists.txt @@ -34,3 +34,8 @@ set_source_files_properties(${llxml_HEADER_FILES} list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES}) add_library (llxml ${llxml_SOURCE_FILES}) +target_link_libraries( + llxml + ${BOOST_SIGNALS_LIBRARY} + ${EXPAT_LIBRARIES} + ) diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 2cf418e..084f129 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -496,30 +496,17 @@ void LLAppViewer::initGridChoice() } } -bool send_url_to_other_instance(const std::string& url) +//virtual +bool LLAppViewer::initSLURLHandler() { -#if LL_WINDOWS - wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars. - mbstowcs(window_class, sWindowClass, 255); - window_class[255] = 0; - // Use the class instead of the window name. - HWND other_window = FindWindow(window_class, NULL); - - if (other_window != NULL) - { - lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl; - COPYDATASTRUCT cds; - const S32 SLURL_MESSAGE_TYPE = 0; - cds.dwData = SLURL_MESSAGE_TYPE; - cds.cbData = url.length() + 1; - cds.lpData = (void*)url.c_str(); - - LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); - lldebugs << "SendMessage(WM_COPYDATA) to other window '" - << gWindowTitle << "' returned " << msg_result << llendl; - return true; - } -#endif + // does nothing unless subclassed + return false; +} + +//virtual +bool LLAppViewer::sendURLToOtherInstance(const std::string& url) +{ + // does nothing unless subclassed return false; } @@ -719,6 +706,9 @@ bool LLAppViewer::init() // Find partition serial number (Windows) or hardware serial (Mac) mSerialNumber = generateSerialNumber(); + // do any necessary set-up for accepting incoming SLURLs from apps + initSLURLHandler(); + if(false == initHardwareTest()) { // Early out from user choice. @@ -1962,7 +1952,7 @@ bool LLAppViewer::initConfiguration() } if (!slurl.empty()) { - if (send_url_to_other_instance(slurl)) + if (sendURLToOtherInstance(slurl)) { // successfully handed off URL to existing instance, exit return false; diff --git a/linden/indra/newview/llappviewer.h b/linden/indra/newview/llappviewer.h index 801deb1..1e7ffbb 100644 --- a/linden/indra/newview/llappviewer.h +++ b/linden/indra/newview/llappviewer.h @@ -136,15 +136,18 @@ public: void resumeMainloopTimeout(const std::string& state = "", F32 secs = -1.0f); void pingMainloopTimeout(const std::string& state, F32 secs = -1.0f); + protected: virtual bool initWindow(); // Initialize the viewer's window. virtual bool initLogging(); // Initialize log files, logging system, return false on failure. virtual void initConsole() {}; // Initialize OS level debugging console. virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit. + virtual bool initSLURLHandler(); + virtual bool sendURLToOtherInstance(const std::string& url); - virtual bool initParseCommandLine(LLCommandLineParser& clp) + virtual bool initParseCommandLine(LLCommandLineParser& clp) { return true; } // Allow platforms to specify the command line args. - + virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this. diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp index 0a4a9cf..6b9350b 100644 --- a/linden/indra/newview/llappviewerlinux.cpp +++ b/linden/indra/newview/llappviewerlinux.cpp @@ -1,6 +1,6 @@ /** * @file llappviewerlinux.cpp - * @brief The LLAppViewerWin32 class definitions + * @brief The LLAppViewerLinux class definitions * * $LicenseInfo:firstyear=2007&license=viewergpl$ * @@ -36,8 +36,10 @@ #include "llcommandlineparser.h" #include "llmemtype.h" +#include "llurldispatcher.h" // SLURL from other app instance #include "llviewernetwork.h" #include "llviewercontrol.h" +#include "llwindowsdl.h" #include "llmd5.h" #include "llfindlocale.h" @@ -60,6 +62,17 @@ # include "ELFIO/ELFIO.h" // for better backtraces #endif +#if LL_DBUS_ENABLED +# include "llappviewerlinux_api_dbus.h" + +// regrettable hacks to give us better runtime compatibility with older systems inside llappviewerlinux_api.h: +#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) +#undef g_return_if_fail +#define g_return_if_fail(COND) llg_return_if_fail(COND) +// The generated API +# include "llappviewerlinux_api.h" +#endif + namespace { int gArgC = 0; @@ -321,6 +334,186 @@ bool LLAppViewerLinux::init() return LLAppViewer::init(); } +///////////////////////////////////////// +#if LL_DBUS_ENABLED + +typedef struct +{ + GObjectClass parent_class; +} ViewerAppAPIClass; + +static void viewerappapi_init(ViewerAppAPI *server); +static void viewerappapi_class_init(ViewerAppAPIClass *klass); + +/// + +// regrettable hacks to give us better runtime compatibility with older systems in general +static GType llg_type_register_static_simple_ONCE(GType parent_type, + const gchar *type_name, + guint class_size, + GClassInitFunc class_init, + guint instance_size, + GInstanceInitFunc instance_init, + GTypeFlags flags) +{ + static GTypeInfo type_info; + memset(&type_info, 0, sizeof(type_info)); + + type_info.class_size = class_size; + type_info.class_init = class_init; + type_info.instance_size = instance_size; + type_info.instance_init = instance_init; + + return g_type_register_static(parent_type, type_name, &type_info, flags); +} +#define llg_intern_static_string(S) (S) +#define g_intern_static_string(S) llg_intern_static_string(S) +#define g_type_register_static_simple(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) llg_type_register_static_simple_ONCE(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) + +G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT); + +void viewerappapi_class_init(ViewerAppAPIClass *klass) +{ +} + +static bool dbus_server_init = false; + +void viewerappapi_init(ViewerAppAPI *server) +{ + // Connect to the default DBUS, register our service/API. + + if (!dbus_server_init) + { + GError *error = NULL; + + server->connection = lldbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (server->connection) + { + lldbus_g_object_type_install_info(viewerappapi_get_type(), &dbus_glib_viewerapp_object_info); + + lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server)); + + DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + + guint request_name_ret_unused; + // akin to org_freedesktop_DBus_request_name + if (lldbus_g_proxy_call(serverproxy, "RequestName", &error, G_TYPE_STRING, VIEWERAPI_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &request_name_ret_unused, G_TYPE_INVALID)) + { + // total success. + dbus_server_init = true; + } + else + { + llwarns << "Unable to register service name: " << error->message << llendl; + } + + g_object_unref(serverproxy); + } + else + { + g_warning("Unable to connect to dbus: %s", error->message); + } + + if (error) + g_error_free(error); + } +} + +gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error) +{ + bool success = false; + + llinfos << "Was asked to go to slurl: " << slurl << llendl; + + const bool from_external_browser = true; + if (LLURLDispatcher::dispatch(slurl, from_external_browser)) + { + // bring window to foreground, as it has just been "launched" from a URL + // todo: hmm, how to get there from here? + //xxx->mWindow->bringToFront(); + success = true; + } + + *success_rtn = g_new (gboolean, 1); + (*success_rtn)[0] = (gboolean)success; + + return TRUE; // the invokation succeeded, even if the actual dispatch didn't. +} + +/// + +//virtual +bool LLAppViewerLinux::initSLURLHandler() +{ + if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) + { + return false; // failed + } + + g_type_init(); + + //ViewerAppAPI *api_server = (ViewerAppAPI*) + g_object_new(viewerappapi_get_type(), NULL); + + return true; +} + +//virtual +bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) +{ + if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) + { + return false; // failed + } + + bool success = false; + DBusGConnection *bus; + GError *error = NULL; + + g_type_init(); + + bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (bus) + { + gboolean rtn = FALSE; + DBusGProxy *remote_object = + lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE); + + if (lldbus_g_proxy_call(remote_object, "GoSLURL", &error, + G_TYPE_STRING, url.c_str(), G_TYPE_INVALID, + G_TYPE_BOOLEAN, &rtn, G_TYPE_INVALID)) + { + success = rtn; + } + else + { + llinfos << "Call-out to other instance failed (perhaps not running): " << error->message << llendl; + } + + g_object_unref(G_OBJECT(remote_object)); + } + else + { + llwarns << "Couldn't connect to session bus: " << error->message << llendl; + } + + if (error) + g_error_free(error); + + return success; +} + +#else // LL_DBUS_ENABLED +bool LLAppViewerLinux::initSLURLHandler() +{ + return false; // not implemented without dbus +} +bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) +{ + return false; // not implemented without dbus +} +#endif // LL_DBUS_ENABLED + void LLAppViewerLinux::handleSyncCrashTrace() { // This backtrace writes into stack_trace.log diff --git a/linden/indra/newview/llappviewerlinux.h b/linden/indra/newview/llappviewerlinux.h index a180b4d..f95aaa4 100644 --- a/linden/indra/newview/llappviewerlinux.h +++ b/linden/indra/newview/llappviewerlinux.h @@ -32,6 +32,14 @@ #ifndef LL_LLAPPVIEWERLINUX_H #define LL_LLAPPVIEWERLINUX_H +#if LL_DBUS_ENABLED +extern "C" { +# include +# include +# include +} +#endif + #ifndef LL_LLAPPVIEWER_H #include "llappviewer.h" #endif @@ -49,6 +57,7 @@ public: // virtual bool init(); // Override to do application initialization std::string generateSerialNumber(); + bool setupSLURLHandler(); protected: virtual bool beingDebugged(); @@ -58,6 +67,26 @@ protected: virtual bool initLogging(); virtual bool initParseCommandLine(LLCommandLineParser& clp); + + virtual bool initSLURLHandler(); + virtual bool sendURLToOtherInstance(const std::string& url); }; +#if LL_DBUS_ENABLED +typedef struct +{ + GObject parent; + DBusGConnection *connection; +} ViewerAppAPI; + +extern "C" { + gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error); +} + +#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" +#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" +#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" + +#endif // LL_DBUS_ENABLED + #endif // LL_LLAPPVIEWERLINUX_H diff --git a/linden/indra/newview/llappviewerlinux_api.h b/linden/indra/newview/llappviewerlinux_api.h new file mode 100644 index 0000000..bd17599 --- /dev/null +++ b/linden/indra/newview/llappviewerlinux_api.h @@ -0,0 +1,148 @@ +/* Generated by dbus-binding-tool; do not edit! */ +/** + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef __dbus_glib_marshal_viewerapp_MARSHAL_H__ +#define __dbus_glib_marshal_viewerapp_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.5XXD8T:1) */ +extern void dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +void +dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer arg_3, + gpointer data2); + register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); + + g_value_set_boolean (return_value, v_return); +} + +G_END_DECLS + +#endif /* __dbus_glib_marshal_viewerapp_MARSHAL_H__ */ + +#include +static const DBusGMethodInfo dbus_glib_viewerapp_methods[] = { + { (GCallback) viewer_app_api_GoSLURL, dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER, 0 }, +}; + +const DBusGObjectInfo dbus_glib_viewerapp_object_info = { + 0, + dbus_glib_viewerapp_methods, + 1, +"com.secondlife.ViewerAppAPI\0GoSLURL\0S\0slurl\0I\0s\0success_ret\0O\0F\0N\0b\0\0\0", +"\0", +"\0" +}; + diff --git a/linden/indra/newview/llappviewerlinux_api.xml b/linden/indra/newview/llappviewerlinux_api.xml new file mode 100644 index 0000000..fac35b7 --- /dev/null +++ b/linden/indra/newview/llappviewerlinux_api.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/linden/indra/newview/llappviewerlinux_api_dbus.cpp b/linden/indra/newview/llappviewerlinux_api_dbus.cpp new file mode 100644 index 0000000..806714f --- /dev/null +++ b/linden/indra/newview/llappviewerlinux_api_dbus.cpp @@ -0,0 +1,131 @@ +/** + * @file llappviewerlinux_api_dbus.cpp + * @brief dynamic DBus symbol-grabbing code + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if LL_DBUS_ENABLED + +#include "linden_common.h" + +extern "C" { +#include + +#include "apr_pools.h" +#include "apr_dso.h" +} + +#define DEBUGMSG(...) lldebugs << llformat(__VA_ARGS__) << llendl +#define INFOMSG(...) llinfos << llformat(__VA_ARGS__) << llendl +#define WARNMSG(...) llwarns << llformat(__VA_ARGS__) << llendl + +#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL +#include "llappviewerlinux_api_dbus_syms_raw.inc" +#undef LL_DBUS_SYM + +static bool sSymsGrabbed = false; +static apr_pool_t *sSymDBUSDSOMemoryPool = NULL; +static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL; + +bool grab_dbus_syms(std::string dbus_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 *sSymDBUSDSOHandle = NULL; + +#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0) + + //attempt to load the shared library + apr_pool_create(&sSymDBUSDSOMemoryPool, NULL); + + if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle, + dbus_dso_name.c_str(), + sSymDBUSDSOMemoryPool) )) + { + INFOMSG("Found DSO: %s", dbus_dso_name.c_str()); + +#include "llappviewerlinux_api_dbus_syms_raw.inc" + + if ( sSymDBUSDSOHandle ) + { + sSymDBUSDSOHandleG = sSymDBUSDSOHandle; + sSymDBUSDSOHandle = NULL; + } + + rtn = !sym_error; + } + else + { + INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str()); + rtn = false; // failure + } + + if (sym_error) + { + WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries."); + } +#undef LL_DBUS_SYM + + sSymsGrabbed = rtn; + return rtn; +} + + +void ungrab_dbus_syms() +{ + // should be safe to call regardless of whether we've + // actually grabbed syms. + + if ( sSymDBUSDSOHandleG ) + { + apr_dso_unload(sSymDBUSDSOHandleG); + sSymDBUSDSOHandleG = NULL; + } + + if ( sSymDBUSDSOMemoryPool ) + { + apr_pool_destroy(sSymDBUSDSOMemoryPool); + sSymDBUSDSOMemoryPool = NULL; + } + + // NULL-out all of the symbols we'd grabbed +#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0) +#include "llappviewerlinux_api_dbus_syms_raw.inc" +#undef LL_DBUS_SYM + + sSymsGrabbed = false; +} + +#endif // LL_DBUS_ENABLED diff --git a/linden/indra/newview/llappviewerlinux_api_dbus.h b/linden/indra/newview/llappviewerlinux_api_dbus.h new file mode 100644 index 0000000..6d6c1b0 --- /dev/null +++ b/linden/indra/newview/llappviewerlinux_api_dbus.h @@ -0,0 +1,49 @@ +/** + * @file llappviewerlinux_api_dbus.h + * @brief DBus-glib symbol handling + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#if LL_DBUS_ENABLED + +extern "C" { +#include +} + +#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2" + +bool grab_dbus_syms(std::string dbus_dso_name); +void ungrab_dbus_syms(); + +#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) extern RTN (*ll##DBUSSYM)(__VA_ARGS__) +#include "llappviewerlinux_api_dbus_syms_raw.inc" +#undef LL_DBUS_SYM + +#endif // LL_DBUS_ENABLED diff --git a/linden/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/linden/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc new file mode 100644 index 0000000..c0548e2 --- /dev/null +++ b/linden/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc @@ -0,0 +1,9 @@ + +// required symbols to grab +LL_DBUS_SYM(true, dbus_g_bus_get, DBusGConnection*, DBusBusType, GError**); +LL_DBUS_SYM(true, dbus_g_proxy_new_for_name, DBusGProxy*, DBusGConnection*, const char *, const char*, const char*); +LL_DBUS_SYM(true, dbus_g_proxy_call, gboolean, DBusGProxy*, const char*, GError**, GType, ...); +LL_DBUS_SYM(true, dbus_g_object_type_install_info, void, GType, const DBusGObjectInfo*); +LL_DBUS_SYM(true, dbus_g_connection_register_g_object, void, DBusGConnection*, const char*, GObject*); + +// optional symbols to grab diff --git a/linden/indra/newview/llappviewerwin32.cpp b/linden/indra/newview/llappviewerwin32.cpp index 9f37534..1f24ee3 100644 --- a/linden/indra/newview/llappviewerwin32.cpp +++ b/linden/indra/newview/llappviewerwin32.cpp @@ -64,7 +64,7 @@ #include "llcommandlineparser.h" -//*FIX:Mani - This hack is to fix a linker issue with libndofdev.lib +// *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib // The lib was compiled under VS2005 - in VS2003 we need to remap assert #ifdef LL_DEBUG #ifdef LL_MSVC7 @@ -77,6 +77,8 @@ extern "C" { #endif #endif +const std::string LLAppViewerWin32::sWindowClass = "Second Life"; + LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) { // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. @@ -478,6 +480,33 @@ void LLAppViewerWin32::handleCrashReporting() } } +//virtual +bool LLAppViewerWin32::sendURLToOtherInstance(const std::string& url) +{ + wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars. + mbstowcs(window_class, sWindowClass.c_str(), 255); + window_class[255] = 0; + // Use the class instead of the window name. + HWND other_window = FindWindow(window_class, NULL); + + if (other_window != NULL) + { + lldebugs << "Found other window with the name '" << getWindowTitle() << "'" << llendl; + COPYDATASTRUCT cds; + const S32 SLURL_MESSAGE_TYPE = 0; + cds.dwData = SLURL_MESSAGE_TYPE; + cds.cbData = url.length() + 1; + cds.lpData = (void*)url.c_str(); + + LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); + lldebugs << "SendMessage(WM_COPYDATA) to other window '" + << getWindowTitle() << "' returned " << msg_result << llendl; + return true; + } + return false; +} + + std::string LLAppViewerWin32::generateSerialNumber() { char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore diff --git a/linden/indra/newview/llappviewerwin32.h b/linden/indra/newview/llappviewerwin32.h index fe16ec4..315310c 100644 --- a/linden/indra/newview/llappviewerwin32.h +++ b/linden/indra/newview/llappviewerwin32.h @@ -56,8 +56,12 @@ protected: virtual void handleCrashReporting(); virtual void handleSyncCrashTrace(); + virtual bool sendURLToOtherInstance(const std::string& url); + std::string generateSerialNumber(); + static const std::string sWindowClass; + private: void disableWinErrorReporting(); diff --git a/linden/install.xml b/linden/install.xml index 484598a..3b1ddf5 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -206,6 +206,32 @@ + dbusglib + + copyright + Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. + description + dbus/dbus-glib: headers only + license + AFL2.1 + packages + + linux + + md5sum + eb25444142d4102b0ce1b7ffaadb071e + url + http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/dbusglib-linux-20080707.tar.bz2 + + linux32 + + md5sum + eb25444142d4102b0ce1b7ffaadb071e + url + http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/dbusglib-linux-20080707.tar.bz2 + + + elfio license @@ -1118,6 +1144,11 @@ anguage Infrstructure (CLI) international standard licenses + AFL2.1 + + url + http://opensource-definition.org/licenses/afl-2.1.html + GL url