#include "RConfigure.h"
#include "Riostream.h"
#include "TApplication.h"
#include "TException.h"
#include "TGuiFactory.h"
#include "TVirtualX.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TString.h"
#include "TError.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TTimer.h"
#include "TInterpreter.h"
#include "TStyle.h"
#include "TVirtualPad.h"
#include "TEnv.h"
#include "TColor.h"
#include "TClassTable.h"
#include "TPluginManager.h"
#include "TClassTable.h"
#include "TBrowser.h"
#include "TUrl.h"
TApplication *gApplication = 0;
Bool_t TApplication::fgGraphNeeded = kFALSE;
Bool_t TApplication::fgGraphInit = kFALSE;
TList *TApplication::fgApplications = 0;
class TIdleTimer : public TTimer {
public:
TIdleTimer(Long_t ms) : TTimer(ms, kTRUE) { }
Bool_t Notify();
};
Bool_t TIdleTimer::Notify()
{
gApplication->HandleIdleTimer();
Reset();
return kFALSE;
}
ClassImp(TApplication)
TApplication::TApplication()
{
fArgc = 0;
fArgv = 0;
fAppImp = 0;
fAppRemote = 0;
fIsRunning = kFALSE;
fReturnFromRun = kFALSE;
fNoLog = kFALSE;
fNoLogo = kFALSE;
fQuit = kFALSE;
fFiles = 0;
fIdleTimer = 0;
fSigHandler = 0;
ResetBit(kProcessRemotely);
}
TApplication::TApplication(const char *appClassName,
Int_t *argc, char **argv, void *options,
Int_t numOptions)
{
if (gApplication && gApplication->TestBit(kDefaultApplication)) {
delete gApplication;
gApplication = 0;
gROOT->SetBatch(kFALSE);
fgGraphInit = kFALSE;
}
if (gApplication) {
Error("TApplication", "only one instance of TApplication allowed");
return;
}
if (!gROOT)
::Fatal("TApplication::TApplication", "ROOT system not initialized");
if (!gSystem)
::Fatal("TApplication::TApplication", "gSystem not initialized");
gApplication = this;
gROOT->SetApplication(this);
gROOT->SetName(appClassName);
if (!fgApplications)
fgApplications = new TList;
fgApplications->Add(this);
if (options) { }
if (argc && *argc > 0) {
fArgc = *argc;
fArgv = (char **)new char*[fArgc];
} else {
fArgc = 0;
fArgv = 0;
}
for (int i = 0; i < fArgc; i++)
fArgv[i] = StrDup(argv[i]);
fNoLog = kFALSE;
fNoLogo = kFALSE;
fQuit = kFALSE;
fAppImp = 0;
if (numOptions >= 0)
GetOptions(argc, argv);
if (fArgv)
gSystem->SetProgname(fArgv[0]);
gSystem->NotifyApplicationCreated();
fIdleTimer = 0;
fSigHandler = 0;
fIsRunning = kFALSE;
fReturnFromRun = kFALSE;
fAppImp = gGuiFactory->CreateApplicationImp(appClassName, argc, argv);
fAppRemote = 0;
ResetBit(kProcessRemotely);
gInterpreter->EnableAutoLoading();
if (gClassTable->GetDict("TPad")) {
fgGraphNeeded = kTRUE;
InitializeGraphics();
}
gInterpreter->InitializeDictionaries();
gInterpreter->UpdateListOfTypes();
gInterpreter->SaveContext();
gInterpreter->SaveGlobalsContext();
gROOT->SetLineHasBeenProcessed();
}
TApplication::~TApplication()
{
for (int i = 0; i < fArgc; i++)
if (fArgv[i]) delete [] fArgv[i];
delete [] fArgv;
SafeDelete(fAppImp);
if (fgApplications)
fgApplications->Remove(this);
}
void TApplication::NeedGraphicsLibs()
{
fgGraphNeeded = kTRUE;
}
void TApplication::InitializeGraphics()
{
if (fgGraphInit || !fgGraphNeeded)
return;
fgGraphInit = kTRUE;
LoadGraphicsLibs();
const char *ttpath = gEnv->GetValue("Root.TTFontPath",
#ifdef TTFFONTDIR
TTFFONTDIR);
#else
"$(ROOTSYS)/fonts");
#endif
char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);
if (!ttfont)
ttfont = gSystem->Which(ttpath, "FreeSansBold.ttf", kReadPermission);
#if !defined(R__WIN32)
if (!gROOT->IsBatch() && !strcmp(gVirtualX->GetName(), "X11") &&
ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
if (gClassTable->GetDict("TGX11TTF")) {
ProcessLine("TGX11TTF::Activate();");
} else {
TPluginHandler *h;
if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
h->LoadPlugin();
}
}
#endif
delete [] ttfont;
if (fAppImp)
delete fAppImp;
fAppImp = gGuiFactory->CreateApplicationImp(gROOT->GetName(), &fArgc, fArgv);
if (!fAppImp) {
MakeBatch();
fAppImp = gGuiFactory->CreateApplicationImp(gROOT->GetName(), &fArgc, fArgv);
}
TColor::InitializeColors();
Init();
if (gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
Int_t x, y;
UInt_t w, h;
if (gVirtualX) {
gVirtualX->GetGeometry(-1, x, y, w, h);
if (h > 0 && h < 1000) gStyle->SetScreenFactor(0.0011*h);
}
}
}
void TApplication::ClearInputFiles()
{
if (fFiles) {
fFiles->Delete();
SafeDelete(fFiles);
}
}
char *TApplication::Argv(Int_t index) const
{
if (fArgv) {
if (index >= fArgc) {
Error("Argv", "index (%d) >= number of arguments (%d)", index, fArgc);
return 0;
}
return fArgv[index];
}
return 0;
}
void TApplication::GetOptions(Int_t *argc, char **argv)
{
static char null[1] = { "" };
fNoLog = kFALSE;
fQuit = kFALSE;
fFiles = 0;
if (!argc)
return;
int i, j;
TString pwd;
for (i = 1; i < *argc; i++) {
if (!strcmp(argv[i], "-?") || !strncmp(argv[i], "-h", 2) ||
!strncmp(argv[i], "--help", 6)) {
fprintf(stderr, "Usage: %s [-l] [-b] [-n] [-q] [dir] [[file:]data.root] [file1.C ... fileN.C]\n", argv[0]);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -b : run in batch mode without graphics\n");
fprintf(stderr, " -n : do not execute logon and logoff macros as specified in .rootrc\n");
fprintf(stderr, " -q : exit after processing command line macro files\n");
fprintf(stderr, " -l : do not show splash screen\n");
fprintf(stderr, " dir : if dir is a valid directory cd to it before executing\n");
fprintf(stderr, "\n");
fprintf(stderr, " -? : print usage\n");
fprintf(stderr, " -h : print usage\n");
fprintf(stderr, " --help : print usage\n");
fprintf(stderr, " -config : print ./configure options\n");
fprintf(stderr, "\n");
Terminate(0);
} else if (!strcmp(argv[i], "-config")) {
fprintf(stderr, "ROOT ./configure options:\n%s\n", gROOT->GetConfigOptions());
Terminate(0);
} else if (!strcmp(argv[i], "-b")) {
MakeBatch();
argv[i] = null;
} else if (!strcmp(argv[i], "-n")) {
fNoLog = kTRUE;
argv[i] = null;
} else if (!strcmp(argv[i], "-q")) {
fQuit = kTRUE;
argv[i] = null;
} else if (!strcmp(argv[i], "-l")) {
fNoLogo = kTRUE;
argv[i] = null;
} else if (!strcmp(argv[i], "-splash")) {
argv[i] = null;
} else if (argv[i][0] != '-' && argv[i][0] != '+') {
Long64_t size;
Long_t id, flags, modtime;
char *arg = strchr(argv[i], '(');
if (arg) *arg = '\0';
char *dir = gSystem->ExpandPathName(argv[i]);
if (arg) *arg = '(';
if (!gSystem->GetPathInfo(dir, &id, &size, &flags, &modtime)) {
if ((flags & 2)) {
if (pwd == "") {
pwd = gSystem->WorkingDirectory();
fWorkDir = dir;
gSystem->ChangeDirectory(dir);
argv[i] = null;
} else if (!strcmp(gROOT->GetName(), "Rint")) {
Warning("GetOptions", "only one directory argument can be specified (%s)", dir);
}
} else if (flags == 0 || flags == 1) {
if (!fFiles) fFiles = new TObjArray;
fFiles->Add(new TObjString(argv[i]));
argv[i] = null;
}
} else {
if (TString(dir).EndsWith(".root") && !strcmp(gROOT->GetName(), "Rint")) {
Warning("GetOptions", "file %s not found", dir);
} else {
char *mac, *s = Strip(dir, '+');
if ((mac = gSystem->Which(TROOT::GetMacroPath(), s,
kReadPermission))) {
if (!fFiles) fFiles = new TObjArray;
fFiles->Add(new TObjString(argv[i]));
argv[i] = null;
delete [] mac;
} else {
if (!strcmp(gROOT->GetName(), "Rint"))
Warning("GetOptions", "macro %s not found", s);
}
delete [] s;
}
}
delete [] dir;
}
}
if (pwd != "")
gSystem->ChangeDirectory(pwd);
j = 0;
for (i = 0; i < *argc; i++) {
if (strcmp(argv[i], "")) {
argv[j] = argv[i];
j++;
}
}
*argc = j;
}
void TApplication::HandleIdleTimer()
{
if (!fIdleCommand.IsNull())
ProcessLine(GetIdleCommand());
Emit("HandleIdleTimer()");
}
void TApplication::HandleException(Int_t sig)
{
if (TROOT::Initialized()) {
if (gException) {
gInterpreter->RewindDictionary();
gInterpreter->ClearFileBusy();
}
Throw(sig);
}
gSystem->Exit(sig);
}
void TApplication::Help(const char *line)
{
gInterpreter->ProcessLine(line);
Printf("\nROOT special commands.");
Printf("===========================================================================");
Printf(" pwd : show current directory, pad and style");
Printf(" ls : list contents of current directory");
Printf(" which [file] : shows path of macro file");
}
void TApplication::LoadGraphicsLibs()
{
if (gROOT->IsBatch()) return;
TPluginHandler *h;
if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPad")))
h->LoadPlugin();
TString name;
TString title1 = "ROOT interface to ";
TString nativex, title;
TString nativeg = "root";
#ifndef R__WIN32
nativex = "x11";
name = "X11";
title = title1 + "X11";
#else
nativex = "win32gdk";
name = "Win32gdk";
title = title1 + "Win32gdk";
#endif
TString guiBackend(gEnv->GetValue("Gui.Backend", "native"));
guiBackend.ToLower();
if (guiBackend == "native") {
guiBackend = nativex;
} else {
name = guiBackend;
title = title1 + guiBackend;
}
TString guiFactory(gEnv->GetValue("Gui.Factory", "native"));
guiFactory.ToLower();
if (guiFactory == "native")
guiFactory = nativeg;
if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend))) {
if (h->LoadPlugin() == -1)
return;
gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
}
if ((h = gROOT->GetPluginManager()->FindHandler("TGuiFactory", guiFactory))) {
if (h->LoadPlugin() == -1)
return;
gGuiFactory = (TGuiFactory *) h->ExecPlugin(0);
}
}
void TApplication::MakeBatch()
{
gROOT->SetBatch();
if (gGuiFactory != gBatchGuiFactory) delete gGuiFactory;
gGuiFactory = gBatchGuiFactory;
#ifndef R__WIN32
if (gVirtualX != gGXBatch) delete gVirtualX;
#endif
gVirtualX = gGXBatch;
}
Int_t TApplication::ParseRemoteLine(const char *ln,
TString &hostdir, TString &user,
Int_t &dbg, TString &script)
{
if (!ln || strlen(ln) <= 0)
return 0;
Int_t rc = 0;
Bool_t isHostDir = kTRUE;
Bool_t isScript = kFALSE;
Bool_t isUser = kFALSE;
Bool_t isDbg = kFALSE;
TString line(ln);
TString tkn;
Int_t from = 0;
while (line.Tokenize(tkn, from, " ")) {
if (tkn == "-l") {
isUser = kTRUE;
} else if (tkn == "-d") {
isDbg = kTRUE;
} else if (tkn == "-close") {
rc = 1;
} else if (tkn.BeginsWith("-")) {
::Warning("TApplication::ParseRemoteLine","unknown option: %s", tkn.Data());
} else {
if (isUser) {
user = tkn;
isUser = kFALSE;
} else if (isDbg) {
dbg = tkn.Atoi();
isDbg = kFALSE;
} else if (isHostDir) {
hostdir = tkn;
hostdir.ReplaceAll(":","/");
isHostDir = kFALSE;
isScript = kTRUE;
} else if (isScript) {
script = tkn;
script.Insert(0, "\"");
script += "\"";
isScript = kFALSE;
break;
} else {
::Warning("TApplication::ParseRemoteLine",
"inconsistent input line %s", line.Data());
}
}
}
return rc;
}
Long_t TApplication::ProcessRemote(const char *line, Int_t *)
{
if (!line) return 0;
if (!strncmp(line, "-?", 2) || !strncmp(line, "-h", 2) ||
!strncmp(line, "--help", 6)) {
Info("ProcessRemote", "remote session help:");
Printf(".R [user@]host[:dir] [-l user] [-d dbg] [[<]script] | [host] -close");
Printf("Create a ROOT session on the specified remote host.");
Printf("The variable \"dir\" is the remote directory to be used as working dir.");
Printf("The username can be specified in two ways, \"-l\" having the priority");
Printf("(as in ssh). A \"dbg\" value > 0 gives increasing verbosity.");
Printf("The last argument \"script\" allows to specify an alternative script to");
Printf("be executed remotely to startup the session, \"roots\" being");
Printf("the default. If the script is preceeded by a \"<\" the script will be");
Printf("sourced, after which \"roots\" is executed. The sourced script can be ");
Printf("used to change the PATH and other variables, allowing an alternative");
Printf("\"roots\" script to be found.");
Printf("To close down a session do \".R host -close\".");
Printf("To switch between sessions do \".R host\", to switch to the local");
Printf("session do \".R\".");
Printf("To list all open sessions do \"gApplication->GetApplications()->Print()\".");
return 0;
}
TString hostdir, user, script;
Int_t dbg = 0;
Int_t rc = ParseRemoteLine(line, hostdir, user, dbg, script);
if (hostdir.Length() <= 0) {
if (rc == 1) {
TApplication::Close(fAppRemote);
delete fAppRemote;
}
fAppRemote = 0;
return 1;
} else if (rc == 1) {
TApplication *ap = TApplication::Open(hostdir, 0, 0);
if (ap) {
TApplication::Close(ap);
delete ap;
}
}
if (user.Length() > 0)
hostdir.Insert(0,Form("%s@", user.Data()));
const char *sc = (script.Length() > 0) ? script.Data() : 0;
TApplication *ap = TApplication::Open(hostdir, dbg, sc);
if (ap) {
fAppRemote = ap;
}
return 1;
}
Long_t TApplication::ProcessLine(const char *line, Bool_t sync, Int_t *err)
{
if (!line || !*line) return 0;
if (!strncmp(line, ".R", 2)) {
Int_t n = 2;
while (*(line+n) == ' ')
n++;
return ProcessRemote(line+n, err);
}
if (fAppRemote && TestBit(kProcessRemotely)) {
ResetBit(kProcessRemotely);
return fAppRemote->ProcessLine(line, err);
}
if (!strncasecmp(line, ".qqqqqqq", 7)) {
gSystem->Abort();
} else if (!strncasecmp(line, ".qqqqq", 5)) {
Info("ProcessLine", "Bye... (try '.qqqqqqq' if still running)");
gSystem->Exit(1);
} else if (!strncasecmp(line, ".exit", 4) || !strncasecmp(line, ".quit", 2)) {
gInterpreter->ResetGlobals();
Terminate(0);
return 0;
}
if (!strncmp(line, "?", 1)) {
Help(line);
return 1;
}
if (!strncmp(line, ".pwd", 4)) {
if (gDirectory)
Printf("Current directory: %s", gDirectory->GetPath());
if (gPad)
Printf("Current pad: %s", gPad->GetName());
if (gStyle)
Printf("Current style: %s", gStyle->GetName());
return 1;
}
if (!strncmp(line, ".ls", 3)) {
const char *opt = 0;
if (line[3]) opt = &line[3];
if (gDirectory) gDirectory->ls(opt);
return 1;
}
if (!strncmp(line, ".which", 6)) {
char *fn = Strip(line+7);
char *s = strtok(fn, "+(");
char *mac = gSystem->Which(TROOT::GetMacroPath(), s, kReadPermission);
if (!mac)
Printf("No macro %s in path %s", s, TROOT::GetMacroPath());
else
Printf("%s", mac);
delete [] fn;
delete [] mac;
return mac ? 1 : 0;
}
if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2)) {
TString aclicMode;
TString arguments;
TString io;
TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
char *mac = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
if (arguments.Length()) {
Warning("ProcessLine", "argument(s) \"%s\" ignored with .%c", arguments.Data(),
line[1]);
}
Long_t retval = 0;
if (!mac)
Error("ProcessLine", "macro %s not found in path %s", fname.Data(),
TROOT::GetMacroPath());
else {
TString cmd(line+1);
Ssiz_t posSpace = cmd.Index(' ');
if (posSpace == -1) cmd.Remove(1);
else cmd.Remove(posSpace);
static TString tempbuf;
if (sync) {
tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
retval = gInterpreter->ProcessLineSynch(tempbuf,
(TInterpreter::EErrorCode*)err);
} else {
tempbuf.Form(".%s %s%s%s", cmd.Data(), mac, aclicMode.Data(),io.Data());
retval = gInterpreter->ProcessLine(tempbuf,
(TInterpreter::EErrorCode*)err);
}
}
delete [] mac;
InitializeGraphics();
return retval;
}
if (!strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
return ProcessFile(line+3, err, line[2] == 'k');
}
if (!strcmp(line, ".reset")) {
Printf("*** .reset not allowed, please use gROOT->Reset() ***");
return 0;
#if 0
gROOT->GetListOfClasses()->Delete();
#endif
}
if (sync)
return gInterpreter->ProcessLineSynch(line, (TInterpreter::EErrorCode*)err);
else
return gInterpreter->ProcessLine(line, (TInterpreter::EErrorCode*)err);
}
Long_t TApplication::ProcessFile(const char *file, Int_t *error, Bool_t keep)
{
return ExecuteFile(file, error, keep);
}
Long_t TApplication::ExecuteFile(const char *file, Int_t *error, Bool_t keep)
{
const Int_t kBufSize = 1024;
if (!file || !*file) return 0;
TString aclicMode;
TString arguments;
TString io;
TString fname = gSystem->SplitAclicMode(file, aclicMode, arguments, io);
char *exnam = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
if (!exnam) {
::Error("TApplication::ExecuteFile", "macro %s not found in path %s", fname.Data(),
TROOT::GetMacroPath());
delete [] exnam;
return 0;
}
::ifstream macro(exnam, ios::in);
if (!macro.good()) {
::Error("TApplication::ExecuteFile", "%s no such file", exnam);
delete [] exnam;
return 0;
}
char currentline[kBufSize];
int tempfile = 0;
int comment = 0;
int ifndefc = 0;
int ifdef = 0;
char *s = 0;
Bool_t execute = kFALSE;
Long_t retval = 0;
while (1) {
macro.getline(currentline, kBufSize);
if (macro.eof()) break;
s = currentline;
while (s && (*s == ' ' || *s == '\t')) s++;
if (*s == '#') {
char *cs = Compress(currentline);
if (strstr(cs, "#ifndef__CINT__") ||
strstr(cs, "#if!defined(__CINT__)"))
ifndefc = 1;
else if (ifndefc && (strstr(cs, "#ifdef") || strstr(cs, "#ifndef") ||
strstr(cs, "#ifdefined") || strstr(cs, "#if!defined")))
ifdef++;
else if (ifndefc && strstr(cs, "#endif")) {
if (ifdef)
ifdef--;
else
ifndefc = 0;
} else if (ifndefc && !ifdef && strstr(cs, "#else"))
ifndefc = 0;
delete [] cs;
}
if (!*s || *s == '#' || ifndefc || !strncmp(s, "//", 2)) continue;
if (!strncmp(s, ".X", 2) || !strncmp(s, ".x", 2)) {
retval = ExecuteFile(s+3);
execute = kTRUE;
continue;
}
if (!strncmp(s, "/*", 2)) comment = 1;
if (comment) {
again:
s = strstr(s, "*/");
if (s) {
comment = 0;
s += 2;
while (s && (*s == ' ' || *s == '\t')) s++;
if (!*s) continue;
if (!strncmp(s, "//", 2)) continue;
if (!strncmp(s, "/*", 2)) {
comment = 1;
goto again;
}
}
}
if (!comment && *s == '{') tempfile = 1;
if (!comment) break;
}
macro.close();
if (!execute) {
TString exname = exnam;
if (!tempfile) {
exname += aclicMode;
}
exname += arguments;
exname += io;
static TString tempbuf;
if (tempfile) {
tempbuf.Form(".x %s", exname.Data());
} else {
tempbuf.Form(".X%s %s", keep ? "k" : " ", exname.Data());
}
retval = gInterpreter->ProcessLineSynch(tempbuf,(TInterpreter::EErrorCode*)error);
}
delete [] exnam;
return retval;
}
void TApplication::Run(Bool_t retrn)
{
SetReturnFromRun(retrn);
fIsRunning = kTRUE;
gSystem->Run();
fIsRunning = kFALSE;
}
void TApplication::SetIdleTimer(UInt_t idleTimeInSec, const char *command)
{
if (fIdleTimer) RemoveIdleTimer();
fIdleCommand = command;
fIdleTimer = new TIdleTimer(idleTimeInSec*1000);
gSystem->AddTimer(fIdleTimer);
}
void TApplication::RemoveIdleTimer()
{
if (fIdleTimer) {
SafeDelete(fIdleTimer);
}
}
void TApplication::StartIdleing()
{
if (fIdleTimer) {
fIdleTimer->Reset();
gSystem->AddTimer(fIdleTimer);
}
}
void TApplication::StopIdleing()
{
if (fIdleTimer)
gSystem->RemoveTimer(fIdleTimer);
}
void TApplication::Terminate(Int_t status)
{
Emit("Terminate(Int_t)", status);
if (fReturnFromRun)
gSystem->ExitLoop();
else
gSystem->Exit(status);
}
void TApplication::LineProcessed(const char *line)
{
Emit("LineProcessed(const char*)", line);
}
void TApplication::KeyPressed(Int_t key)
{
Emit("KeyPressed(Int_t)", key);
}
void TApplication::ReturnPressed(char *text )
{
Emit("ReturnPressed(char*)", text);
}
void TApplication::SetEchoMode(Bool_t)
{
}
void TApplication::CreateApplication()
{
if (!gApplication) {
char *a = StrDup("RootApp");
char *b = StrDup("-b");
char *argv[2];
Int_t argc = 2;
argv[0] = a;
argv[1] = b;
new TApplication("RootApp", &argc, argv, 0, 0);
if (gDebug > 0)
Printf("<TApplication::CreateApplication>: "
"created default TApplication");
delete [] a; delete [] b;
gApplication->SetBit(kDefaultApplication);
}
}
TApplication *TApplication::Open(const char *url,
Int_t debug, const char *script)
{
TApplication *ap = 0;
TUrl nu(url);
Int_t nnew = 0;
if (fgApplications) {
TIter nxa(fgApplications);
while ((ap = (TApplication *) nxa())) {
TString apn(ap->ApplicationName());
if (apn == url) {
return ap;
} else {
TUrl au(apn);
if (strlen(au.GetUser()) > 0 && strlen(nu.GetUser()) > 0 &&
!strcmp(au.GetUser(), nu.GetUser())) {
if (!strncmp(au.GetHost(), nu.GetHost(), strlen(nu.GetHost())))
nnew++;
}
}
}
} else {
::Error("TApplication::Open", "list of applications undefined - protocol error");
return ap;
}
if (nnew > 0) {
nnew++;
nu.SetOptions(Form("%d", nnew));
}
TPluginHandler *h = 0;
if ((h = gROOT->GetPluginManager()->FindHandler("TApplication","remote"))) {
if (h->LoadPlugin() == 0) {
ap = (TApplication *) h->ExecPlugin(3, nu.GetUrl(), debug, script);
} else {
::Error("TApplication::Open", "failed to load plugin for TApplicationRemote");
}
} else {
::Error("TApplication::Open", "failed to find plugin for TApplicationRemote");
}
if (ap && !(ap->TestBit(kInvalidObject))) {
fgApplications->Add(ap);
gROOT->GetListOfBrowsables()->Add(ap, ap->ApplicationName());
TIter next(gROOT->GetListOfBrowsers());
TBrowser *b;
while ((b = (TBrowser*) next()))
b->Add(ap, ap->ApplicationName());
gROOT->RefreshBrowsers();
} else {
SafeDelete(ap);
::Error("TApplication::Open",
"TApplicationRemote for %s could not be instantiated", url);
}
return ap;
}
void TApplication::Close(TApplication *app)
{
if (app) {
app->Terminate(0);
fgApplications->Remove(app);
gROOT->GetListOfBrowsables()->RecursiveRemove(app);
TIter next(gROOT->GetListOfBrowsers());
TBrowser *b;
while ((b = (TBrowser*) next()))
b->RecursiveRemove(app);
gROOT->RefreshBrowsers();
}
}
void TApplication::ls(Option_t *opt) const
{
if (fgApplications) {
TIter nxa(fgApplications);
TApplication *a = 0;
while ((a = (TApplication *) nxa())) {
a->Print(opt);
}
} else {
Print(opt);
}
}
TList *TApplication::GetApplications()
{
return fgApplications;
}