ROOT logo
// Client program which allows the snooping of objects from a spyserv process.
// To run this demo do the following (see spyserv.C):
//   - open two or more windows
//   - start root in all windows
//   - execute in the first window:    .x spyserv.C  (or spyserv.C++)
//   - execute in the other window(s): .x spy.C      (or spy.C++)
//   - in the "spy" client windows click the "Connect" button and snoop
//     the histograms by clicking on the "hpx", "hpxpy" and "hprof"
//     buttons
//Author: Fons Rademakers
   
#include "TGButton.h"
#include "TRootEmbeddedCanvas.h"
#include "TGLayout.h"
#include "TH2.h"
#include "TCanvas.h"
#include "TSocket.h"
#include "TMessage.h"
#include "RQ_OBJECT.h"


class Spy {

RQ_OBJECT("Spy")

private:
   TGMainFrame         *fMain;
   TRootEmbeddedCanvas *fCanvas;
   TGHorizontalFrame   *fHorz;
   TGHorizontalFrame   *fHorz2;
   TGLayoutHints       *fLbut;
   TGLayoutHints       *fLhorz;
   TGLayoutHints       *fLcan;
   TGButton            *fHpx;
   TGButton            *fHpxpy;
   TGButton            *fHprof;
   TGButton            *fConnect;
   TGButton            *fQuit;
   TSocket             *fSock;
   TH1                 *fHist;

public:
   Spy();
   ~Spy();

   void Connect();
   void DoButton();
};

void Spy::DoButton()
{
   // Ask for histogram...

   if (!fSock->IsValid())
      return;

   TGButton *btn = (TGButton *) gTQSender;
   switch (btn->WidgetId()) {
      case 1:
         fSock->Send("get hpx");
         break;
      case 2:
         fSock->Send("get hpxpy");
         break;
      case 3:
         fSock->Send("get hprof");
         break;
   }
   TMessage *mess;
   if (fSock->Recv(mess) <= 0) {
      Error("Spy::DoButton", "error receiving message");
      return;
   }

   if (fHist) delete fHist;
   if (mess->GetClass()->InheritsFrom(TH1::Class())) {
      fHist = (TH1*) mess->ReadObject(mess->GetClass());
      if (mess->GetClass()->InheritsFrom(TH2::Class()))
         fHist->Draw("cont");
      else
         fHist->Draw();
      fCanvas->GetCanvas()->Modified();
      fCanvas->GetCanvas()->Update();
   }

   delete mess;
}

void Spy::Connect()
{
   // Connect to SpyServ
   fSock = new TSocket("localhost", 9090);
   fConnect->SetState(kButtonDisabled);
   fHpx->SetState(kButtonUp);
   fHpxpy->SetState(kButtonUp);
   fHprof->SetState(kButtonUp);
}

Spy::Spy()
{
   // Create a main frame
   fMain = new TGMainFrame(0, 100, 100);
   fMain->SetCleanup(kDeepCleanup);

   // Create an embedded canvas and add to the main frame, centered in x and y
   // and with 30 pixel margins all around
   fCanvas = new TRootEmbeddedCanvas("Canvas", fMain, 600, 400);
   fLcan = new TGLayoutHints(kLHintsCenterX|kLHintsCenterY,30,30,30,30);
   fMain->AddFrame(fCanvas, fLcan);

   // Create a horizonal frame containing three text buttons
   fLhorz = new TGLayoutHints(kLHintsExpandX, 0, 0, 0, 30);
   fHorz = new TGHorizontalFrame(fMain, 100, 100);
   fMain->AddFrame(fHorz, fLhorz);

   // Create three text buttons to get objects from server
   // Add to horizontal frame
   fLbut = new TGLayoutHints(kLHintsCenterX, 10, 10, 0, 0);
   fHpx = new TGTextButton(fHorz, "Get hpx", 1);
   fHpx->SetState(kButtonDisabled);
   fHpx->Connect("Clicked()", "Spy", this, "DoButton()");
   fHorz->AddFrame(fHpx, fLbut);
   fHpxpy = new TGTextButton(fHorz, "Get hpxpy", 2);
   fHpxpy->SetState(kButtonDisabled);
   fHpxpy->Connect("Clicked()", "Spy", this, "DoButton()");
   fHorz->AddFrame(fHpxpy, fLbut);
   fHprof = new TGTextButton(fHorz, "Get hprof", 3);
   fHprof->SetState(kButtonDisabled);
   fHprof->Connect("Clicked()", "Spy", this, "DoButton()");
   fHorz->AddFrame(fHprof, fLbut);

   // Create a horizonal frame containing two text buttons
   fHorz2 = new TGHorizontalFrame(fMain, 100, 100);
   fMain->AddFrame(fHorz2, fLhorz);

   // Create "Connect" and "Quit" buttons
   // Add to horizontal frame
   fConnect = new TGTextButton(fHorz2, "Connect");
   fConnect->Connect("Clicked()", "Spy", this, "Connect()");
   fHorz2->AddFrame(fConnect, fLbut);
   fQuit = new TGTextButton(fHorz2, "Quit");
   fQuit->SetCommand("gApplication->Terminate()");
   fHorz2->AddFrame(fQuit, fLbut);

   // Set main frame name, map sub windows (buttons), initialize layout
   // algorithm via Resize() and map main frame
   fMain->SetWindowName("Spy on SpyServ");
   fMain->MapSubwindows();
   fMain->Resize(fMain->GetDefaultSize());
   fMain->MapWindow();

   fHist = 0;
}

Spy::~Spy()
{
   // Clean up

   delete fHist;
   delete fSock;
   delete fLbut;
   delete fLhorz;
   delete fLcan;
   delete fHpx;
   delete fHpxpy;
   delete fHprof;
   delete fConnect;
   delete fQuit;
   delete fHorz;
   delete fHorz2;
   delete fCanvas;
   delete fMain;
}

void spy()
{
   new Spy;
}
 spy.C:1
 spy.C:2
 spy.C:3
 spy.C:4
 spy.C:5
 spy.C:6
 spy.C:7
 spy.C:8
 spy.C:9
 spy.C:10
 spy.C:11
 spy.C:12
 spy.C:13
 spy.C:14
 spy.C:15
 spy.C:16
 spy.C:17
 spy.C:18
 spy.C:19
 spy.C:20
 spy.C:21
 spy.C:22
 spy.C:23
 spy.C:24
 spy.C:25
 spy.C:26
 spy.C:27
 spy.C:28
 spy.C:29
 spy.C:30
 spy.C:31
 spy.C:32
 spy.C:33
 spy.C:34
 spy.C:35
 spy.C:36
 spy.C:37
 spy.C:38
 spy.C:39
 spy.C:40
 spy.C:41
 spy.C:42
 spy.C:43
 spy.C:44
 spy.C:45
 spy.C:46
 spy.C:47
 spy.C:48
 spy.C:49
 spy.C:50
 spy.C:51
 spy.C:52
 spy.C:53
 spy.C:54
 spy.C:55
 spy.C:56
 spy.C:57
 spy.C:58
 spy.C:59
 spy.C:60
 spy.C:61
 spy.C:62
 spy.C:63
 spy.C:64
 spy.C:65
 spy.C:66
 spy.C:67
 spy.C:68
 spy.C:69
 spy.C:70
 spy.C:71
 spy.C:72
 spy.C:73
 spy.C:74
 spy.C:75
 spy.C:76
 spy.C:77
 spy.C:78
 spy.C:79
 spy.C:80
 spy.C:81
 spy.C:82
 spy.C:83
 spy.C:84
 spy.C:85
 spy.C:86
 spy.C:87
 spy.C:88
 spy.C:89
 spy.C:90
 spy.C:91
 spy.C:92
 spy.C:93
 spy.C:94
 spy.C:95
 spy.C:96
 spy.C:97
 spy.C:98
 spy.C:99
 spy.C:100
 spy.C:101
 spy.C:102
 spy.C:103
 spy.C:104
 spy.C:105
 spy.C:106
 spy.C:107
 spy.C:108
 spy.C:109
 spy.C:110
 spy.C:111
 spy.C:112
 spy.C:113
 spy.C:114
 spy.C:115
 spy.C:116
 spy.C:117
 spy.C:118
 spy.C:119
 spy.C:120
 spy.C:121
 spy.C:122
 spy.C:123
 spy.C:124
 spy.C:125
 spy.C:126
 spy.C:127
 spy.C:128
 spy.C:129
 spy.C:130
 spy.C:131
 spy.C:132
 spy.C:133
 spy.C:134
 spy.C:135
 spy.C:136
 spy.C:137
 spy.C:138
 spy.C:139
 spy.C:140
 spy.C:141
 spy.C:142
 spy.C:143
 spy.C:144
 spy.C:145
 spy.C:146
 spy.C:147
 spy.C:148
 spy.C:149
 spy.C:150
 spy.C:151
 spy.C:152
 spy.C:153
 spy.C:154
 spy.C:155
 spy.C:156
 spy.C:157
 spy.C:158
 spy.C:159
 spy.C:160
 spy.C:161
 spy.C:162
 spy.C:163
 spy.C:164
 spy.C:165
 spy.C:166
 spy.C:167
 spy.C:168
 spy.C:169
 spy.C:170
 spy.C:171
 spy.C:172
 spy.C:173
 spy.C:174
 spy.C:175
 spy.C:176
 spy.C:177
 spy.C:178
 spy.C:179