/*========================================================================= Program: ParaView Module: vtkInitializationHelper.cxx Copyright (c) Kitware, Inc. All rights reserved. See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkInitializationHelper.h" #include "vtkClientServerInterpreter.h" #include "vtkClientServerInterpreterInitializer.h" #include "vtkNew.h" #include "vtkOutputWindow.h" #include "vtkProcessModule.h" #include "vtkPVConfig.h" #include "vtkPVInitializer.h" #include "vtkPVOptions.h" #include "vtkPVPluginLoader.h" #include "vtkPVSession.h" #include "vtkSMSettings.h" #include "vtkSmartPointer.h" #include "vtkSMMessage.h" #include "vtkSMProperty.h" #include "vtkSMProxyManager.h" #include #include #include // Windows-only helper functionality: #ifdef _WIN32 # include #endif namespace { #ifdef _WIN32 BOOL CALLBACK listMonitorsCallback(HMONITOR hMonitor, HDC /*hdcMonitor*/, LPRECT /*lprcMonitor*/, LPARAM dwData) { std::ostringstream *str = reinterpret_cast(dwData); MONITORINFOEX monitorInfo; monitorInfo.cbSize = sizeof(monitorInfo); if (GetMonitorInfo(hMonitor, &monitorInfo)) { LPRECT rect = &monitorInfo.rcMonitor; *str << "Device: \"" << monitorInfo.szDevice << "\" " << "Geometry: " << std::noshowpos << rect->right - rect->left << "x" << rect->bottom - rect->top << std::showpos << rect->left << rect->top << " " << ((monitorInfo.dwFlags & MONITORINFOF_PRIMARY) ? "(primary)" : "") << std::endl; } return true; } #endif // _WIN32 std::string ListAttachedMonitors() { #ifndef _WIN32 return std::string("Monitor detection only implemented for MS Windows."); #else // _WIN32 std::ostringstream str; EnumDisplayMonitors(NULL, NULL, listMonitorsCallback, reinterpret_cast(&str)); return str.str(); #endif // _WIN32 } } // end anon namespace bool vtkInitializationHelper::LoadSettingsFilesDuringInitialization = true; bool vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = false; std::string vtkInitializationHelper::OrganizationName = "ParaView"; std::string vtkInitializationHelper::ApplicationName = "GenericParaViewApplication"; //---------------------------------------------------------------------------- void vtkInitializationHelper::SetLoadSettingsFilesDuringInitialization(bool val) { if (vtkProcessModule::GetProcessModule() && val != vtkInitializationHelper::LoadSettingsFilesDuringInitialization) { vtkGenericWarningMacro("SetLoadSettingsFilesDuringInitialization should be called " "before calling Initialize()."); } else { vtkInitializationHelper::LoadSettingsFilesDuringInitialization = val; } } //---------------------------------------------------------------------------- bool vtkInitializationHelper::GetLoadSettingsFilesDuringInitialization() { return vtkInitializationHelper::LoadSettingsFilesDuringInitialization; } //---------------------------------------------------------------------------- void vtkInitializationHelper::SetOrganizationName(const std::string & organizationName) { vtkInitializationHelper::OrganizationName = organizationName; } //---------------------------------------------------------------------------- const std::string & vtkInitializationHelper::GetOrganizationName() { return vtkInitializationHelper::OrganizationName; } //---------------------------------------------------------------------------- void vtkInitializationHelper::SetApplicationName(const std::string & appName) { vtkInitializationHelper::ApplicationName = appName; } //---------------------------------------------------------------------------- const std::string & vtkInitializationHelper::GetApplicationName() { return vtkInitializationHelper::ApplicationName; } //---------------------------------------------------------------------------- void vtkInitializationHelper::Initialize(const char* executable, int type) { vtkInitializationHelper::Initialize(executable, type, NULL); } //---------------------------------------------------------------------------- void vtkInitializationHelper::Initialize(const char* executable, int type, vtkPVOptions* options) { if (!executable) { vtkGenericWarningMacro("Executable name has to be defined."); return; } // Pass the program name to make option parser happier char* argv = new char[strlen(executable)+1]; strcpy(argv, executable); vtkSmartPointer newoptions = options; if (!options) { newoptions = vtkSmartPointer::New(); } vtkInitializationHelper::Initialize(1, &argv, type, newoptions); delete[] argv; } //---------------------------------------------------------------------------- void vtkInitializationHelper::Initialize(int argc, char**argv, int type, vtkPVOptions* options) { if (vtkProcessModule::GetProcessModule()) { vtkGenericWarningMacro("Process already initialize. Skipping."); return; } if (!options) { vtkGenericWarningMacro("vtkPVOptions must be specified."); return; } // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. GOOGLE_PROTOBUF_VERIFY_VERSION; vtkProcessModule::Initialize( static_cast(type), argc, argv); std::ostringstream sscerr; if (argv && !options->Parse(argc, argv) ) { if ( options->GetUnknownArgument() ) { sscerr << "Got unknown argument: " << options->GetUnknownArgument() << endl; } if ( options->GetErrorMessage() ) { sscerr << "Error: " << options->GetErrorMessage() << endl; } options->SetHelpSelected(1); } if (options->GetHelpSelected()) { sscerr << options->GetHelp() << endl; vtkOutputWindow::GetInstance()->DisplayText( sscerr.str().c_str() ); // TODO: indicate to the caller that application must quit. } if (options->GetTellVersion() ) { std::ostringstream str; str << "paraview version " << PARAVIEW_VERSION_FULL << "\n"; vtkOutputWindow::GetInstance()->DisplayText(str.str().c_str()); // TODO: indicate to the caller that application must quit. } if (options->GetPrintMonitors()) { std::string monitors = ListAttachedMonitors(); vtkOutputWindow::GetInstance()->DisplayText(monitors.c_str()); // TODO: indicate to the caller that application must quit. } vtkProcessModule::GetProcessModule()->SetOptions(options); // this has to happen after process module is initialized and options have // been set. PARAVIEW_INITIALIZE(); // Set multi-server flag to vtkProcessModule vtkProcessModule::GetProcessModule()->SetMultipleSessionsSupport( options->GetMultiServerMode() != 0); // Make sure the ProxyManager get created... vtkSMProxyManager::GetProxyManager(); // Now load any plugins located in the PV_PLUGIN_PATH environment variable. // These are always loaded (not merely located). vtkNew loader; loader->LoadPluginsFromPluginSearchPath(); loader->LoadPluginsFromPluginConfigFile(); vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = false; // Load settings files on client-processes. if (!options->GetDisableRegistry() && type != vtkProcessModule::PROCESS_SERVER && type != vtkProcessModule::PROCESS_DATA_SERVER && type != vtkProcessModule::PROCESS_RENDER_SERVER) { vtkInitializationHelper::LoadSettings(); } } //---------------------------------------------------------------------------- void vtkInitializationHelper::StandaloneInitialize() { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. GOOGLE_PROTOBUF_VERIFY_VERSION; } //---------------------------------------------------------------------------- void vtkInitializationHelper::Finalize() { if (vtkInitializationHelper::SaveUserSettingsFileDuringFinalization) { // Write out settings file(s) std::string userSettingsFilePath = vtkInitializationHelper::GetUserSettingsFilePath(); vtkSMSettings* settings = vtkSMSettings::GetInstance(); bool savingSucceeded = settings->SaveSettingsToFile(userSettingsFilePath.c_str()); if (!savingSucceeded) { vtkGenericWarningMacro(<< "Saving settings file to '" << userSettingsFilePath << "' failed"); } } vtkSMProxyManager::Finalize(); vtkProcessModule::Finalize(); // Optional: Delete all global objects allocated by libprotobuf. google::protobuf::ShutdownProtobufLibrary(); } //---------------------------------------------------------------------------- void vtkInitializationHelper::StandaloneFinalize() { // Optional: Delete all global objects allocated by libprotobuf. google::protobuf::ShutdownProtobufLibrary(); } //---------------------------------------------------------------------------- void vtkInitializationHelper::LoadSettings() { if (vtkInitializationHelper::LoadSettingsFilesDuringInitialization == false) { return; } vtkSMSettings* settings = vtkSMSettings::GetInstance(); int myRank = vtkProcessModule::GetProcessModule()->GetPartitionId(); if (myRank > 0) // don't read files on satellites. { settings->DistributeSettings(); return; } // Load user-level settings std::string userSettingsFilePath = vtkInitializationHelper::GetUserSettingsFilePath(); if (!settings->AddCollectionFromFile(userSettingsFilePath, VTK_DOUBLE_MAX)) { // Loading user settings failed, so we need to create an empty // collection with highest priority manually. Otherwise, if a // setting is changed, a lower-priority collection such as site // settings may receive the modified setting values. settings->AddCollectionFromString("{}", VTK_DOUBLE_MAX); } // Load site-level settings vtkPVOptions* options = vtkProcessModule::GetProcessModule()->GetOptions(); std::string app_dir = options->GetApplicationPath(); app_dir = vtksys::SystemTools::GetProgramPath(app_dir.c_str()); // If the application path ends with lib/paraview-X.X, shared // forwarding of the executable was used. Remove that part of the // path to get back to the installation root. std::string installDirectory = app_dir.substr(0, app_dir.find("/lib/paraview-" PARAVIEW_VERSION)); // Remove the trailing /bin if it is there. if (installDirectory.size() >= 4 && installDirectory.substr(installDirectory.size()-4) == "/bin") { installDirectory = installDirectory.substr(0, installDirectory.size()-4); } std::vector pathsToSearch; pathsToSearch.push_back(installDirectory + "/share/paraview-" PARAVIEW_VERSION); pathsToSearch.push_back(installDirectory + "/lib/"); pathsToSearch.push_back(installDirectory); #if defined(__APPLE__) // paths for app pathsToSearch.push_back(installDirectory + "/../../.."); pathsToSearch.push_back(installDirectory + "/../../../../lib"); // paths when doing a unix style install. pathsToSearch.push_back(installDirectory +"/../lib/paraview-" PARAVIEW_VERSION); #endif // On windows configuration files are in the parent directory pathsToSearch.push_back(installDirectory + "/../"); std::string filename = vtkInitializationHelper::GetApplicationName() + "-SiteSettings.json"; std::string siteSettingsFile; for (size_t cc = 0; cc < pathsToSearch.size(); cc++) { std::string path = pathsToSearch[cc]; siteSettingsFile = path + "/" + filename; if (settings->AddCollectionFromFile(siteSettingsFile, 1.0)) { break; } } settings->DistributeSettings(); vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = true; } //---------------------------------------------------------------------------- std::string vtkInitializationHelper::GetUserSettingsDirectory() { std::string organizationName(vtkInitializationHelper::GetOrganizationName()); std::string applicationName(vtkInitializationHelper::GetApplicationName()); #if defined(WIN32) const char* appData = getenv("APPDATA"); if (!appData) { return std::string(); } std::string separator("\\"); std::string directoryPath(appData); if (directoryPath[directoryPath.size()-1] != separator[0]) { directoryPath.append(separator); } directoryPath += applicationName + separator; #else std::string directoryPath; std::string separator("/"); // Emulating QSettings behavior. const char* xdgConfigHome = getenv("XDG_CONFIG_HOME"); if (xdgConfigHome && strlen(xdgConfigHome) > 0) { directoryPath = xdgConfigHome; if (directoryPath[directoryPath.size() - 1] != separator[0]) { directoryPath += separator; } } else { const char* home = getenv("HOME"); if (!home) { return std::string(); } directoryPath = home; if (directoryPath[directoryPath.size() - 1] != separator[0]) { directoryPath += separator; } directoryPath += ".config/"; } directoryPath += organizationName + separator; #endif return directoryPath; } //---------------------------------------------------------------------------- std::string vtkInitializationHelper::GetUserSettingsFilePath() { std::string path = vtkInitializationHelper::GetUserSettingsDirectory(); path.append(vtkInitializationHelper::GetApplicationName()); path.append("-UserSettings.json"); return path; } //---------------------------------------------------------------------------- void vtkInitializationHelper::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); }