RootGraphicsEnabler.cxx
Go to the documentation of this file.
1 // ROOT libraries
2 #include "TROOT.h"
3 #include "TApplication.h"
4 #include "TGClient.h"
5 #include "TSystem.h"
6 #include "TVirtualX.h"
7 #include "TGX11.h" // this header currently triggers a compiler error,
8 // that we had to disable via compiler flag -Wno-variadic-macros
9 
10 // C/C++ standard libraries
11 #include <iostream>
12 #include <string>
13 #include <stdexcept> // std::runtime_error
14 #include <cstdlib> // getenv()
15 
16 namespace { // local namespace
17 /**
18 * This class implements a work-around to initialize ROOT graphics system
19 * before some other code messes with it (that is, we are the first ones
20 * to mess with it, and of course we do it right(TM)).
21 * To ensure this code is executed as soon as possible, it's bound to
22 * the construction of a static variable. While it is not predictable
23 * when this code will be executed, it is expected to be executed before
24 * main() function of the executable if linked statically, or as soon
25 * as a library statically linked with this one is dynamically loaded.
26 *
27 * The work around consists of making sure there is an active TApplication
28 * (but not the ones that pull in an interactive prompt, e.g. TRint),
29 * pulling ROOT out of batch mode, and creating ROOT's X11 graphics client
30 * (that, for example, TEve needs).
31 */
32 struct RootGraphicsEnablerClass
33 {
34  /// Default constructor: quiet
35  RootGraphicsEnablerClass() { EnableRootGraphics(); }
36 
37  /// Constructor: enable messages on specified stream
38  RootGraphicsEnablerClass(std::ostream& out) { EnableRootGraphics(&out); }
39 
40  /// Enacts the tricks to enable the graphics
41 /// @param out pointer to output stream (default: none, be quiet)
42 static void EnableRootGraphics(std::ostream* out = nullptr);
43 }; // RootGraphicEnablerClass
44 
45 // static instance that is here only to ensure the initialization function is called;
46 // this is currently verbose
47 RootGraphicsEnablerClass RootGraphicsEnabler{
48  std::cout
49 };
50 
51 void RootGraphicsEnablerClass::EnableRootGraphics(std::ostream* out /* = nullptr */)
52 {
53  if (out) (*out) << "RootGraphicsEnablerClass hacking its way forth." << std::endl;
54 
55  //======================================================================
56  // Setup the root environment for a program started with no arguments
57  //======================================================================
58  if (out) (*out) << " ==> get the current TApplication (and make sure gROOT is valid)" << std::endl;
59  TApplication* app = ROOT::GetROOT()->GetApplication();
60 
61  // ROOT::GetROOT() should initialize gROOT.
62  if (!gROOT)
63  throw std::runtime_error("RootGraphicsEnabler: no ROOT global pointer");
64 
65  if (!app) {
66  if (out) (*out) << " ==> create a TApplication" << std::endl;
67  int argc = 0;
68  char** argv = nullptr;
69  new TApplication("TApplicationFromRootGraphicsEnabler", &argc, argv);
70  } // if no application
71 
72  if (out) (*out) << " ==> set batch mode off (now it is " << (gROOT->IsBatch()? "on)": "already off)") << std::endl;
73 
74  gROOT->SetBatch(kFALSE);
75 
76  if (!gClient)
77  {
78  if (out) (*out) << " ==> creating a TGClient" << std::endl;
79  if (out) (*out) << " ==> loading graphics library (X11)" << std::endl;
80  int res = gSystem->Load("libGX11.so");
81  if (out) {
82  switch (res) {
83  case 0: break; // successfully loaded
84  case 1: (*out) << " (it was already)" << std::endl; break;
85  case -1: (*out) << " ERROR: not found!" << std::endl; break;
86  case -2: (*out) << " ERROR: version mismatch!" << std::endl; break;
87  default: (*out) << " ERROR: undocumented (code=" << res << ")" << std::endl; break;
88  } // switch
89  }
90 
91  if (out) (*out) << " ==> creating TVirtualX" << std::endl;
92 
93  gVirtualX = new TGX11("X11", "X11 session");
94  std::string const DISPLAY = getenv("DISPLAY");
95 
96  if (out) (*out) << " ==> creating the TGClient (DISPLAY='" << DISPLAY << "')" << std::endl;
97 
98  new TGClient(DISPLAY.c_str());
99  } // if no graphics client
100 
101  if (out) (*out) << "RootGraphicsEnablerClass hacking compleled." << std::endl;
102 
103 } // RootGraphicsEnabler::EnableRootGraphics()
104 
105 } // local namespace
std::string string
Definition: nybbler.cc:12
std::string getenv(std::string const &name)
Definition: getenv.cc:15
QTextStream & endl(QTextStream &s)