vtkInitializationHelper.cxx 14.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

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"
16

17
#include "vtkClientServerInterpreter.h"
18
#include "vtkClientServerInterpreterInitializer.h"
19
#include "vtkNew.h"
20
#include "vtkOutputWindow.h"
21 22
#include "vtkPVConfig.h"
#include "vtkPVInitializer.h"
23
#include "vtkPVOptions.h"
24
#include "vtkPVPluginLoader.h"
Cory Quammen's avatar
Cory Quammen committed
25
#include "vtkPVSession.h"
26
#include "vtkProcessModule.h"
27
#include "vtkSMMessage.h"
28
#include "vtkSMProperty.h"
29
#include "vtkSMProxyManager.h"
30 31
#include "vtkSMSettings.h"
#include "vtkSmartPointer.h"
32

33
#include <sstream>
34
#include <string>
35
#include <vector>
36
#include <vtksys/SystemTools.hxx>
37

38 39
// Windows-only helper functionality:
#ifdef _WIN32
40
#include <windows.h>
41 42
#endif

Kitware Robot's avatar
Kitware Robot committed
43 44
namespace
{
45 46

#ifdef _WIN32
Kitware Robot's avatar
Kitware Robot committed
47 48
BOOL CALLBACK listMonitorsCallback(
  HMONITOR hMonitor, HDC /*hdcMonitor*/, LPRECT /*lprcMonitor*/, LPARAM dwData)
49
{
Kitware Robot's avatar
Kitware Robot committed
50
  std::ostringstream* str = reinterpret_cast<std::ostringstream*>(dwData);
51 52 53 54 55

  MONITORINFOEX monitorInfo;
  monitorInfo.cbSize = sizeof(monitorInfo);

  if (GetMonitorInfo(hMonitor, &monitorInfo))
Kitware Robot's avatar
Kitware Robot committed
56 57 58 59 60 61 62
  {
    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;
  }
63 64 65 66 67 68 69 70
  return true;
}
#endif // _WIN32

std::string ListAttachedMonitors()
{
#ifndef _WIN32
  return std::string("Monitor detection only implemented for MS Windows.");
Kitware Robot's avatar
Kitware Robot committed
71
#else  // _WIN32
72
  std::ostringstream str;
Kitware Robot's avatar
Kitware Robot committed
73
  EnumDisplayMonitors(NULL, NULL, listMonitorsCallback, reinterpret_cast<LPARAM>(&str));
74 75 76 77 78 79
  return str.str();
#endif // _WIN32
}

} // end anon namespace

80
bool vtkInitializationHelper::LoadSettingsFilesDuringInitialization = true;
81

82
bool vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = false;
83

84
std::string vtkInitializationHelper::OrganizationName = "ParaView";
85
std::string vtkInitializationHelper::ApplicationName = "GenericParaViewApplication";
86

87 88 89 90 91
//----------------------------------------------------------------------------
void vtkInitializationHelper::SetLoadSettingsFilesDuringInitialization(bool val)
{
  if (vtkProcessModule::GetProcessModule() &&
    val != vtkInitializationHelper::LoadSettingsFilesDuringInitialization)
Kitware Robot's avatar
Kitware Robot committed
92
  {
93
    vtkGenericWarningMacro("SetLoadSettingsFilesDuringInitialization should be called "
Kitware Robot's avatar
Kitware Robot committed
94 95
                           "before calling Initialize().");
  }
96
  else
Kitware Robot's avatar
Kitware Robot committed
97
  {
98
    vtkInitializationHelper::LoadSettingsFilesDuringInitialization = val;
Kitware Robot's avatar
Kitware Robot committed
99
  }
100 101 102 103 104 105 106 107
}

//----------------------------------------------------------------------------
bool vtkInitializationHelper::GetLoadSettingsFilesDuringInitialization()
{
  return vtkInitializationHelper::LoadSettingsFilesDuringInitialization;
}

108
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
109
void vtkInitializationHelper::SetOrganizationName(const std::string& organizationName)
110 111 112 113 114
{
  vtkInitializationHelper::OrganizationName = organizationName;
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
115
const std::string& vtkInitializationHelper::GetOrganizationName()
116 117 118 119
{
  return vtkInitializationHelper::OrganizationName;
}

120
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
121
void vtkInitializationHelper::SetApplicationName(const std::string& appName)
122 123 124 125 126
{
  vtkInitializationHelper::ApplicationName = appName;
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
127
const std::string& vtkInitializationHelper::GetApplicationName()
128 129 130 131
{
  return vtkInitializationHelper::ApplicationName;
}

132
//----------------------------------------------------------------------------
133
void vtkInitializationHelper::Initialize(const char* executable, int type)
134
{
135
  vtkInitializationHelper::Initialize(executable, type, NULL);
136 137 138
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
139
void vtkInitializationHelper::Initialize(const char* executable, int type, vtkPVOptions* options)
140
{
141
  if (!executable)
Kitware Robot's avatar
Kitware Robot committed
142
  {
143 144
    vtkGenericWarningMacro("Executable name has to be defined.");
    return;
Kitware Robot's avatar
Kitware Robot committed
145
  }
146 147

  // Pass the program name to make option parser happier
148 149
  vtkSmartPointer<vtkPVOptions> newoptions = options;
  if (!options)
Kitware Robot's avatar
Kitware Robot committed
150
  {
151
    newoptions = vtkSmartPointer<vtkPVOptions>::New();
Kitware Robot's avatar
Kitware Robot committed
152
  }
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170

  std::vector<char*> argv;
  argv.push_back(vtksys::SystemTools::DuplicateString(executable));
  if (newoptions->GetForceNoMPIInitOnClient())
  {
    argv.push_back(vtksys::SystemTools::DuplicateString("--no-mpi"));
  }
  if (newoptions->GetForceMPIInitOnClient())
  {
    argv.push_back(vtksys::SystemTools::DuplicateString("--mpi"));
  }

  vtkInitializationHelper::Initialize(static_cast<int>(argv.size()), &argv[0], type, newoptions);

  for (auto tofree : argv)
  {
    delete[] tofree;
  }
171 172 173
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
174
void vtkInitializationHelper::Initialize(int argc, char** argv, int type, vtkPVOptions* options)
175
{
176
  if (vtkProcessModule::GetProcessModule())
Kitware Robot's avatar
Kitware Robot committed
177
  {
178
    vtkGenericWarningMacro("Process already initialize. Skipping.");
179
    return;
Kitware Robot's avatar
Kitware Robot committed
180
  }
181 182

  if (!options)
Kitware Robot's avatar
Kitware Robot committed
183
  {
184 185
    vtkGenericWarningMacro("vtkPVOptions must be specified.");
    return;
Kitware Robot's avatar
Kitware Robot committed
186
  }
187

188 189 190 191
  // 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;

Kitware Robot's avatar
Kitware Robot committed
192
  vtkProcessModule::Initialize(static_cast<vtkProcessModule::ProcessTypes>(type), argc, argv);
193

194
  std::ostringstream sscerr;
Kitware Robot's avatar
Kitware Robot committed
195 196 197
  if (argv && !options->Parse(argc, argv))
  {
    if (options->GetUnknownArgument())
198
    {
199 200
      sscerr << "Got unknown argument: " << options->GetUnknownArgument()
             << ". Could you have misspelled your Python file path or name?" << endl;
Kitware Robot's avatar
Kitware Robot committed
201 202 203
    }
    if (options->GetErrorMessage())
    {
204
      sscerr << "Error: " << options->GetErrorMessage() << endl;
205
    }
Kitware Robot's avatar
Kitware Robot committed
206 207
    options->SetHelpSelected(1);
  }
208
  if (options->GetHelpSelected())
Kitware Robot's avatar
Kitware Robot committed
209
  {
210
    sscerr << options->GetHelp() << endl;
Kitware Robot's avatar
Kitware Robot committed
211
    vtkOutputWindow::GetInstance()->DisplayText(sscerr.str().c_str());
212
    // TODO: indicate to the caller that application must quit.
Kitware Robot's avatar
Kitware Robot committed
213
  }
214

Kitware Robot's avatar
Kitware Robot committed
215 216
  if (options->GetTellVersion())
  {
217
    std::ostringstream str;
218 219
    str << "paraview version " << PARAVIEW_VERSION_FULL << "\n";
    vtkOutputWindow::GetInstance()->DisplayText(str.str().c_str());
220
    // TODO: indicate to the caller that application must quit.
Kitware Robot's avatar
Kitware Robot committed
221
  }
222

223
  if (options->GetPrintMonitors())
Kitware Robot's avatar
Kitware Robot committed
224 225 226 227 228
  {
    std::string monitors = ListAttachedMonitors();
    vtkOutputWindow::GetInstance()->DisplayText(monitors.c_str());
    // TODO: indicate to the caller that application must quit.
  }
229

230
  vtkProcessModule::GetProcessModule()->SetOptions(options);
231

232 233 234 235
  // this has to happen after process module is initialized and options have
  // been set.
  PARAVIEW_INITIALIZE();

236 237
  // Set multi-server flag to vtkProcessModule
  vtkProcessModule::GetProcessModule()->SetMultipleSessionsSupport(
Kitware Robot's avatar
Kitware Robot committed
238
    options->GetMultiServerMode() != 0);
239

240 241
  // Make sure the ProxyManager get created...
  vtkSMProxyManager::GetProxyManager();
242 243 244 245 246

  // Now load any plugins located in the PV_PLUGIN_PATH environment variable.
  // These are always loaded (not merely located).
  vtkNew<vtkPVPluginLoader> loader;
  loader->LoadPluginsFromPluginSearchPath();
247
  loader->LoadPluginsFromPluginConfigFile();
Cory Quammen's avatar
Cory Quammen committed
248

249 250
  vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = false;
  // Load settings files on client-processes.
Kitware Robot's avatar
Kitware Robot committed
251
  if (!options->GetDisableRegistry() && type != vtkProcessModule::PROCESS_SERVER &&
252 253
    type != vtkProcessModule::PROCESS_DATA_SERVER &&
    type != vtkProcessModule::PROCESS_RENDER_SERVER)
Kitware Robot's avatar
Kitware Robot committed
254
  {
255
    vtkInitializationHelper::LoadSettings();
Kitware Robot's avatar
Kitware Robot committed
256
  }
257

Kitware Robot's avatar
Kitware Robot committed
258 259 260 261 262 263
  vtkSMSettings* settings = vtkSMSettings::GetInstance();
  settings->AddCollectionFromString("{ \"standard_presets\": { "
                                    "\"vtkBlockColors\": \"KAAMS\", "
                                    "\"AtomicNumbers\": \"BlueObeliskElements\" "
                                    "} }",
    0.0);
264 265
}

266
//----------------------------------------------------------------------------
267
void vtkInitializationHelper::StandaloneInitialize()
268 269 270 271 272 273
{
  // 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;
}

274 275 276
//----------------------------------------------------------------------------
void vtkInitializationHelper::Finalize()
{
277
  if (vtkInitializationHelper::SaveUserSettingsFileDuringFinalization)
Kitware Robot's avatar
Kitware Robot committed
278
  {
279
    // Write out settings file(s)
Kitware Robot's avatar
Kitware Robot committed
280
    std::string userSettingsFilePath = vtkInitializationHelper::GetUserSettingsFilePath();
281
    vtkSMSettings* settings = vtkSMSettings::GetInstance();
282
    bool savingSucceeded = settings->SaveSettingsToFile(userSettingsFilePath.c_str());
283
    if (!savingSucceeded)
Kitware Robot's avatar
Kitware Robot committed
284 285
    {
      vtkGenericWarningMacro(<< "Saving settings file to '" << userSettingsFilePath << "' failed");
286
    }
Kitware Robot's avatar
Kitware Robot committed
287
  }
288

289
  vtkSMProxyManager::Finalize();
290
  vtkProcessModule::Finalize();
291 292 293

  // Optional:  Delete all global objects allocated by libprotobuf.
  google::protobuf::ShutdownProtobufLibrary();
294
}
295 296

//----------------------------------------------------------------------------
297
void vtkInitializationHelper::StandaloneFinalize()
298 299 300 301 302
{
  // Optional:  Delete all global objects allocated by libprotobuf.
  google::protobuf::ShutdownProtobufLibrary();
}

303
//----------------------------------------------------------------------------
304
void vtkInitializationHelper::LoadSettings()
305
{
306
  if (vtkInitializationHelper::LoadSettingsFilesDuringInitialization == false)
Kitware Robot's avatar
Kitware Robot committed
307
  {
308
    return;
Kitware Robot's avatar
Kitware Robot committed
309
  }
310

311
  vtkSMSettings* settings = vtkSMSettings::GetInstance();
312
  int myRank = vtkProcessModule::GetProcessModule()->GetPartitionId();
313

314
  if (myRank > 0) // don't read files on satellites.
Kitware Robot's avatar
Kitware Robot committed
315
  {
316
    settings->DistributeSettings();
317
    return;
Kitware Robot's avatar
Kitware Robot committed
318
  }
319

320
  // Load user-level settings
321
  std::string userSettingsFilePath = vtkInitializationHelper::GetUserSettingsFilePath();
322
  if (!settings->AddCollectionFromFile(userSettingsFilePath, VTK_DOUBLE_MAX))
Kitware Robot's avatar
Kitware Robot committed
323
  {
324 325 326 327 328
    // 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);
Kitware Robot's avatar
Kitware Robot committed
329
  }
330 331

  // Load site-level settings
332 333 334 335
  vtkPVOptions* options = vtkProcessModule::GetProcessModule()->GetOptions();
  std::string app_dir = options->GetApplicationPath();
  app_dir = vtksys::SystemTools::GetProgramPath(app_dir.c_str());

336 337 338 339 340 341
  // 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.
Cory Quammen's avatar
Cory Quammen committed
342
  if (installDirectory.size() >= 4 &&
Kitware Robot's avatar
Kitware Robot committed
343 344 345 346
    installDirectory.substr(installDirectory.size() - 4) == "/bin")
  {
    installDirectory = installDirectory.substr(0, installDirectory.size() - 4);
  }
347

348
  std::vector<std::string> pathsToSearch;
349 350 351
  pathsToSearch.push_back(installDirectory + "/share/paraview-" PARAVIEW_VERSION);
  pathsToSearch.push_back(installDirectory + "/lib/");
  pathsToSearch.push_back(installDirectory);
352 353
#if defined(__APPLE__)
  // paths for app
354 355
  pathsToSearch.push_back(installDirectory + "/../../..");
  pathsToSearch.push_back(installDirectory + "/../../../../lib");
356

357
  // paths when doing a unix style install.
Kitware Robot's avatar
Kitware Robot committed
358
  pathsToSearch.push_back(installDirectory + "/../lib/paraview-" PARAVIEW_VERSION);
359 360
#endif
  // On windows configuration files are in the parent directory
361
  pathsToSearch.push_back(installDirectory + "/../");
362

363
  std::string filename = vtkInitializationHelper::GetApplicationName() + "-SiteSettings.json";
364 365
  std::string siteSettingsFile;
  for (size_t cc = 0; cc < pathsToSearch.size(); cc++)
Kitware Robot's avatar
Kitware Robot committed
366
  {
367
    std::string path = pathsToSearch[cc];
368
    siteSettingsFile = path + "/" + filename;
369
    if (settings->AddCollectionFromFile(siteSettingsFile, 1.0))
Kitware Robot's avatar
Kitware Robot committed
370
    {
371 372
      break;
    }
Kitware Robot's avatar
Kitware Robot committed
373
  }
374 375
  settings->DistributeSettings();

376
  vtkInitializationHelper::SaveUserSettingsFileDuringFinalization = true;
377 378 379 380 381
}

//----------------------------------------------------------------------------
std::string vtkInitializationHelper::GetUserSettingsDirectory()
{
382
  std::string organizationName(vtkInitializationHelper::GetOrganizationName());
383
  std::string applicationName(vtkInitializationHelper::GetApplicationName());
384
#if defined(_WIN32)
385 386
  const char* appData = getenv("APPDATA");
  if (!appData)
Kitware Robot's avatar
Kitware Robot committed
387
  {
388
    return std::string();
Kitware Robot's avatar
Kitware Robot committed
389
  }
390
  std::string separator("\\");
391
  std::string directoryPath(appData);
Kitware Robot's avatar
Kitware Robot committed
392 393
  if (directoryPath[directoryPath.size() - 1] != separator[0])
  {
394
    directoryPath.append(separator);
Kitware Robot's avatar
Kitware Robot committed
395
  }
396
  directoryPath += applicationName + separator;
397
#else
398 399
  std::string directoryPath;
  std::string separator("/");
Kitware Robot's avatar
Kitware Robot committed
400

401 402 403
  // Emulating QSettings behavior.
  const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
  if (xdgConfigHome && strlen(xdgConfigHome) > 0)
Kitware Robot's avatar
Kitware Robot committed
404
  {
405 406
    directoryPath = xdgConfigHome;
    if (directoryPath[directoryPath.size() - 1] != separator[0])
Kitware Robot's avatar
Kitware Robot committed
407
    {
408
      directoryPath += separator;
409
    }
Kitware Robot's avatar
Kitware Robot committed
410
  }
411
  else
Kitware Robot's avatar
Kitware Robot committed
412
  {
413 414
    const char* home = getenv("HOME");
    if (!home)
Kitware Robot's avatar
Kitware Robot committed
415
    {
416
      return std::string();
Kitware Robot's avatar
Kitware Robot committed
417
    }
418 419
    directoryPath = home;
    if (directoryPath[directoryPath.size() - 1] != separator[0])
Kitware Robot's avatar
Kitware Robot committed
420
    {
421
      directoryPath += separator;
422
    }
Kitware Robot's avatar
Kitware Robot committed
423 424
    directoryPath += ".config/";
  }
425
  directoryPath += organizationName + separator;
426
#endif
427
  return directoryPath;
428 429
}

430 431 432 433 434 435 436 437 438 439
//----------------------------------------------------------------------------
std::string vtkInitializationHelper::GetUserSettingsFilePath()
{
  std::string path = vtkInitializationHelper::GetUserSettingsDirectory();
  path.append(vtkInitializationHelper::GetApplicationName());
  path.append("-UserSettings.json");

  return path;
}

440 441 442 443 444
//----------------------------------------------------------------------------
void vtkInitializationHelper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}