Logo ROOT  
Reference Guide
TRecorder.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Katerina Opocenska 11/09/2008
3 
4 /*************************************************************************
5 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // ROOT EVENT RECORDING SYSTEM //
15 // ================================================================== //
16 // //
17 // TRecorder class provides interface for recording and replaying //
18 // events in ROOT. //
19 // Recorded events are: //
20 // - Commands typed by user in commandline ('new TCanvas') //
21 // - GUI events (mouse movement, button clicks, ...) //
22 // //
23 // All the recorded events from one session are stored in one TFile //
24 // and can be replayed again anytime. //
25 // //
26 // Recording //
27 // ================================================================== //
28 // //
29 // 1] To start recording //
30 // //
31 // TRecorder r(const char *filename, "NEW") //
32 // TRecorder r(const char *filename, "RECREATE") //
33 // //
34 // or: //
35 // //
36 // TRecorder *recorder = new TRecorder; //
37 // recorder->Start(const char *filename, ...) //
38 // //
39 // -filename Name of ROOT file in which to save //
40 // recorded events. //
41 // //
42 // 2] To stop recording //
43 // //
44 // recorder->Stop() //
45 // //
46 // //
47 // IMPORTANT: //
48 // State capturing is part of recording. It means that if you want to //
49 // record events for some object (window), creation of this object //
50 // must be also recorded. //
51 // //
52 // Example: //
53 // -------- //
54 // t = new TRecorder(); // Create a new recorder //
55 // t->Start("logfile.root"); // ! Start recording first //
56 // //
57 // c = new TCanvas(); // ! Then, create an object //
58 // c->Dump(); // Work with that object //
59 // //
60 // t->Stop(); // Stop recording //
61 // //
62 // It is strongly recommended to start recording with empty ROOT //
63 // environment, at least with no previously created ROOT GUI. //
64 // This ensures that only events for well known windows are stored. //
65 // Events for windows, which were not created during recording, //
66 // cannot be replayed. //
67 // //
68 // Replaying //
69 // =================================================================== //
70 // //
71 // 1] To start replaying //
72 // //
73 // TRecorder r(const char *filename) //
74 // TRecorder r(const char *filename, "READ") //
75 // //
76 // or: //
77 // //
78 // TRecorder *recorder = new TRecorder; //
79 // recorder->Replay(const char *filename, //
80 // Bool_t showMouseCursor = kTRUE); //
81 // //
82 // -filename A name of file with recorded events //
83 // previously created with TRecorder::Start //
84 // //
85 // -showMouseCursor If kTRUE, mouse cursor is replayed as well. //
86 // In that case it is not recommended to use mouse //
87 // during replaying. //
88 // //
89 // In general, it is not recommended to use mouse to change positions //
90 // and states of ROOT windows during replaying. //
91 // //
92 // IMPORTANT: //
93 // The state of ROOT environment before replaying of some events //
94 // must be exactly the same as before recording them. //
95 // Therefore it is strongly recommended to start both recording //
96 // and replaying with empty ROOT environment. //
97 // //
98 // 2] To pause replaying //
99 // //
100 // recorder->Pause() //
101 // //
102 // Replaying is stopped until recorder->Resume() is called. //
103 // //
104 // //
105 // 3] To resume paused replaying //
106 // //
107 // recorder->Resume() //
108 // //
109 // Resumes previously stopped replaying. //
110 // //
111 // //
112 // 4] To stop replaying before its end //
113 // //
114 // recorder->Stop() //
115 // //
116 //////////////////////////////////////////////////////////////////////////
117 
118 #include "TRecorder.h"
119 
120 #include "TROOT.h"
121 #include "TFile.h"
122 #include "TTimer.h"
123 #include "TTree.h"
124 #include "TSystem.h"
125 #include "TMutex.h"
126 #include "TGButton.h"
127 #include "TGFileDialog.h"
128 #include "TGLabel.h"
129 #include "TGWindow.h"
130 #include "Buttons.h"
131 #include "TKey.h"
132 #include "TPaveLabel.h"
133 #include "TLatex.h"
134 #include "TVirtualDragManager.h"
135 #include "TGPicture.h"
136 #include "KeySymbols.h"
137 #include "TVirtualX.h"
138 
139 #include <iomanip>
140 
141 // Names of ROOT GUI events. Used for listing event logs.
142 const char *kRecEventNames[] = {
143  "KeyPress",
144  "KeyRelease",
145  "ButtonPress",
146  "ButtonRelease",
147  "MotionNotify",
148  "EnterNotify",
149  "LeaveNotify",
150  "FocusIn",
151  "FocusOut",
152  "Expose",
153  "ConfigureNotify",
154  "MapNotify",
155  "UnmapNotify",
156  "DestroyNotify",
157  "ClientMessage",
158  "SelectionClear",
159  "SelectionRequest",
160  "SelectionNotify",
161  "ColormapNotify",
162  "ButtonDoubleClick",
163  "OtherEvent"
164 };
165 
166 // Names of TTrees in the TFile with recorded events
167 const char *kCmdEventTree = "CmdEvents"; // Name of TTree with commandline events
168 const char *kGuiEventTree = "GuiEvents"; // Name of TTree with GUI events
169 const char *kWindowsTree = "WindowsTree"; // Name of TTree with window IDs
170 const char *kExtraEventTree = "ExtraEvents"; // Name of TTree with extra events (PaveLabels and Texts)
171 const char *kBranchName = "MainBranch"; // Name of the main branch in all TTress
172 
174 
175 
176 //_____________________________________________________________________________
177 //
178 // TGCursorWindow
179 //
180 // Window used as fake mouse cursor wile replaying events.
181 //_____________________________________________________________________________
182 
183 class TGCursorWindow : public TGFrame {
184 
185 protected:
186  Pixmap_t fPic, fMask; // Pixmaps used as Window shape
187 
188 public:
189  TGCursorWindow();
190  virtual ~TGCursorWindow();
191 };
192 
193 static TGCursorWindow *gCursorWin = 0;
194 static Int_t gDecorWidth = 0;
195 static Int_t gDecorHeight = 0;
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// TGCursorWindow constructor.
199 
200 TGCursorWindow::TGCursorWindow() :
201  TGFrame(gClient->GetDefaultRoot(), 32, 32, kTempFrame)
202 {
203  SetWindowAttributes_t wattr;
204  const TGPicture *pbg = fClient->GetPicture("recursor.png");
205  fPic = pbg->GetPicture();
206  fMask = pbg->GetMask();
207 
208  gVirtualX->ShapeCombineMask(fId, 0, 0, fMask);
209  SetBackgroundPixmap(fPic);
210 
212  wattr.fSaveUnder = kTRUE;
213  wattr.fOverrideRedirect = kTRUE;
214 
215  gVirtualX->ChangeWindowAttributes(fId, &wattr);
216 }
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Destructor.
220 
221 TGCursorWindow::~TGCursorWindow()
222 {
223 }
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Creates initial INACTIVE state for the recorder
227 
229 {
230  fFilename = "";
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Creates a recorder with filename to replay or to record,
236 /// depending on option (NEW or RECREATE will start recording,
237 /// READ will start replaying)
238 
239 TRecorder::TRecorder(const char *filename, Option_t *option)
240 {
241  TString opt(option);
242  fFilename = "";
244  if ((opt == "NEW") || (opt == "RECREATE"))
245  Start(filename, option);
246  else
247  Replay(filename);
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Destructor.
252 
254 {
255  delete fRecorderState;
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Browse the recorder from a ROOT file. This allows to replay a
260 /// session from the browser.
261 
263 {
264  Replay(fFilename);
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Starts recording events
269 
270 void TRecorder::Start(const char *filename, Option_t *option, Window_t *w,
271  Int_t winCount)
272 {
273  fRecorderState->Start(this, filename, option, w, winCount);
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// Stopps recording events
278 
279 void TRecorder::Stop(Bool_t guiCommand)
280 {
281  fRecorderState->Stop(this, guiCommand);
282 }
283 
284 ////////////////////////////////////////////////////////////////////////////////
285 /// Replays events from 'filename'
286 
287 Bool_t TRecorder::Replay(const char *filename, Bool_t showMouseCursor,
289 {
290  return fRecorderState->Replay(this, filename, showMouseCursor, mode);
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 /// Pauses replaying
295 
297 {
298  fRecorderState->Pause(this);
299 }
300 
301 ////////////////////////////////////////////////////////////////////////////////
302 /// Resumes replaying
303 
305 {
306  fRecorderState->Resume(this);
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Cancells replaying
311 
313 {
314  fRecorderState->ReplayStop(this);
315 }
316 
317 ////////////////////////////////////////////////////////////////////////////////
318 /// Prints out recorded commandline events
319 
320 void TRecorder::ListCmd(const char *filename)
321 {
322  fRecorderState->ListCmd(filename);
323 }
324 
325 ////////////////////////////////////////////////////////////////////////////////
326 /// Prints out recorded GUI events
327 
328 void TRecorder::ListGui(const char *filename)
329 {
330  fRecorderState->ListGui(filename);
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// Changes state from the current to the passed one (newstate)
335 /// Deletes the old state if delPreviousState = KTRUE
336 
337 void TRecorder::ChangeState(TRecorderState *newstate, Bool_t delPreviousState)
338 {
339  if (delPreviousState)
340  delete fRecorderState;
341 
342  fRecorderState = newstate;
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Get current state of recorder.
347 
349 {
350  return fRecorderState->GetState();
351 }
352 
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Save previous canvases in a .root file
356 
357 void TRecorder::PrevCanvases(const char *filename, Option_t *option)
358 {
359  fRecorderState->PrevCanvases(filename,option);
360 }
361 
362 //______________________________________________________________________________
363 // Represents state of TRecorder when replaying
364 
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Allocates all necessary data structures used for replaying
369 /// What is allocated here is deleted in destructor
370 
372 {
373  fCanv = 0;
374  fCmdTree = 0;
375  fCmdTreeCounter = 0;
377  fExtraTree = 0;
378  fExtraTreeCounter = 0;
380  fGuiTree = 0;
381  fGuiTreeCounter = 0;
382  fNextEvent = 0;
383  fRecorder = 0;
384  fRegWinCounter = 0;
387  fWin = 0;
388  fWinTree = 0;
389  fWinTreeEntries = 0;
390  fFile = TFile::Open(filename);
391  fCmdEvent = new TRecCmdEvent();
392  fGuiEvent = new TRecGuiEvent();
393  fExtraEvent = new TRecExtraEvent();
394  fWindowList = new TList();
395  fTimer = new TTimer();
396  fMutex = new TMutex(kFALSE);
397  if (!gCursorWin)
398  gCursorWin = new TGCursorWindow();
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// Closes all signal-slot connections
403 /// Frees all memory allocated in contructor.
404 
406 {
407  fTimer->Disconnect(fTimer, "Timeout()", this, "ReplayRealtime()");
408  fTimer->TurnOff();
409  // delete fTimer;
410 
411  gClient->Disconnect(gClient, "RegisteredWindow(Window_t)", this,
412  "RegisterWindow(Window_t)");
413 
414  if (fFile) {
415  fFile->Close();
416  delete fFile;
417  }
418 
419  delete fWindowList;
420  delete fCmdEvent;
421  delete fGuiEvent;
422  delete fExtraEvent;
423  delete fMutex;
424  if (gCursorWin)
425  gCursorWin->DeleteWindow();
426  gCursorWin = 0;
427 }
428 
429 ////////////////////////////////////////////////////////////////////////////////
430 /// Initialization of data structures for replaying.
431 /// Start of replaying.
432 ///
433 /// Return value:
434 /// - kTRUE = everything is OK and replaying has begun
435 /// - kFALSE = non existing or invalid log file, replaying has not started
436 
439 {
440  fWin = 0;
441  fGuiTreeCounter = 0;
442  fCmdTreeCounter = 0;
443  fExtraTreeCounter = 0;
444  fRegWinCounter = 0;
445  fRecorder = 0;
446 
448 
450 
451  fEventReplayed = 1;
452 
453  fRecorder = r;
454  fShowMouseCursor = showMouseCursor;
455 
456  if (!fFile || fFile->IsZombie() || !fFile->IsOpen())
457  return kFALSE;
458 
463 
464  if (!fCmdTree || !fWinTree || ! fGuiTree || ! fExtraTree) {
465  Error("TRecorderReplaying::Initialize",
466  "The ROOT file is not valid event logfile.");
467  return kFALSE;
468  }
469 
470  try {
475  }
476  catch(...) {
477  Error("TRecorderReplaying::Initialize",
478  "The ROOT file is not valid event logfile");
479  return kFALSE;
480  }
481 
482  // No event to replay in given ROOT file
483  if (!PrepareNextEvent()) {
484  Info("TRecorderReplaying::Initialize",
485  "Log file empty. No event to replay.");
486  return kFALSE;
487  }
488 
489  // Number of registered windows during recording
491 
492  // When a window is registered during replaying,
493  // TRecorderReplaying::RegisterWindow(Window_t) is called
494  gClient->Connect("RegisteredWindow(Window_t)", "TRecorderReplaying",
495  this, "RegisterWindow(Window_t)");
496 
497  Info("TRecorderReplaying::Initialize", "Replaying of file %s started",
498  fFile->GetName());
499 
501  if (f && !f->IsZombie()) {
502  TIter nextkey(f->GetListOfKeys());
503  TKey *key;
504  TObject *obj;
505  while ((key = (TKey*)nextkey())) {
507  obj = key->ReadObj();
508  if (!obj->InheritsFrom("TCanvas"))
509  continue;
510  fCanv = (TCanvas*) obj;
511  fCanv->Draw();
512  }
513  TCanvas *canvas;
514  TIter nextc(gROOT->GetListOfCanvases());
515  while ((canvas = (TCanvas*)nextc())) {
516  canvas->SetWindowSize(canvas->GetWindowWidth(),
517  canvas->GetWindowHeight());
518  }
520  f->Close();
521  }
522 
523  gPad = 0;
524  // Starts replaying
525  fTimer->Connect("Timeout()","TRecorderReplaying",this,"ReplayRealtime()");
526  fTimer->Start(0);
527 
528  return kTRUE;
529 }
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// Creates mapping for the newly registered window w and adds this
533 /// mapping to fWindowList
534 ///
535 /// Called by signal whenever a new window is registered during replaying.
536 ///
537 /// The new window ID is mapped to the old one with the same number in the
538 /// list of registered windows.
539 /// It means that 1st new window is mapped to the 1st original,
540 /// 2nd to the 2nd, Nth new to the Nth original.
541 
543 {
544  if (fFilterStatusBar) {
545  TGWindow *win = gClient->GetWindowById(w);
546  if (win) {
547  if (win->GetParent()->InheritsFrom("TGStatusBar")) {
549  return;
550  }
551  }
552  }
553 
554  // Get original window ID that was registered as 'fRegWinCounter'th
557  }
558  else {
559  // More windows registered when replaying then when recording.
560  // Cannot continue
561  Error("TRecorderReplaying::RegisterWindow",
562  "More windows registered than expected");
563  //ReplayStop(fRecorder);
564  return;
565  }
566 
567  if ((gDebug > 0) && (fWaitingForWindow)) {
568  std::ios::fmtflags f = std::cout.flags(); // store flags
569  std::cout << " Window registered: new ID: " << std::hex << w <<
570  " previous ID: " << fWin << std::dec << std::endl;
571  std::cout.flags( f ); // restore flags (reset std::hex)
572  }
573 
574  // Lock mutex for guarding access to fWindowList
575  fMutex->Lock();
576 
577  // Increases counter of registered windows
578  fRegWinCounter++;
579 
580  // Creates new mapping of original window (fWin) and a new one (w)
581  TRecWinPair *ids = new TRecWinPair(fWin, w);
582  // Saves the newly created mapping
583  fWindowList->Add(ids);
584 
585  // If we are waiting for this window to be registered
586  // (Replaying was stopped because of that)
588 
589  if (gDebug > 0) {
590  std::ios::fmtflags f = std::cout.flags(); // store flags
591  std::cout << " Window " << std::hex << fGuiEvent->fWindow <<
592  " registered." << std::dec << std::endl;
593  std::cout.flags( f ); // restore flags (reset std::hex)
594  }
595 
597  // Sets that we do not wait for this window anymore
599 
600  // Start replaying of events again
601  fTimer->Start(25);
602  }
603  fMutex->UnLock();
604 }
605 
606 ////////////////////////////////////////////////////////////////////////////////
607 /// All references to the old windows (IDs) in fNextEvent are replaced by
608 /// new ones according to the mappings in fWindowList
609 
611 {
612  // Lock mutex for guarding access to fWindowList
613  fMutex->Lock();
614 
615  TRecWinPair *ids;
617 
618  Bool_t found = kFALSE;
619 
620  // Iterates through the whole list of mappings
621  while ((ids = (TRecWinPair*)it.Next())) {
622  // Window that the event belongs to
623  if (!found && fGuiEvent->fWindow == 0) {
624  fGuiEvent->fWindow = gVirtualX->GetDefaultRootWindow();
625  found = kTRUE;
626  }
627  else if (!found && ids->fKey == fGuiEvent->fWindow) {
628  fGuiEvent->fWindow = ids->fValue;
629  found = kTRUE;
630  }
631  for (Int_t i = 0; i < 5; ++i) {
632  if ((Long_t) ids->fKey == fGuiEvent->fUser[i])
633  fGuiEvent->fUser[i] = ids->fValue;
634  }
635  if (fGuiEvent->fMasked && ids->fKey == fGuiEvent->fMasked) {
636  fGuiEvent->fMasked = ids->fValue;
637  }
638  }
639 
640  if (!found && fGuiEvent->fWindow == 0) {
641  fGuiEvent->fWindow = gVirtualX->GetDefaultRootWindow();
642  found = kTRUE;
643  }
644  // Mapping for the event found
645  if (found) {
646  fMutex->UnLock();
647  return kTRUE;
648  }
649 
650  if (gDebug > 0) {
651  // save actual formatting flags
652  std::ios_base::fmtflags org_flags = std::cout.flags();
653  std::cout << "fGuiTreeCounter = " << std::dec << fGuiTreeCounter <<
654  " No mapping found for ID " << std::hex << fGuiEvent->fWindow << std::endl;
656  // restore original formatting flags
657  std::cout.flags(org_flags);
658  }
659 
660  // Stopps timer and waits for the appropriate window to be registered
661  fTimer->Stop();
663 
664  fMutex->UnLock();
665  return kFALSE;
666 }
667 
668 ////////////////////////////////////////////////////////////////////////////////
669 
671 {
672  // Not all the recorded events are replayed.
673  // Some of them are generated automatically in ROOT
674  // as a consequence of other events.
675  //
676  // RETURN VALUE:
677  // - kTRUE = passed TRecGuiEvent *e should be filtered
678  // (should not be replayed)
679  // - kFALSE = passed TRecGuiEvent *e should not be filtered
680  // (should be replayed)
681 
682  // We do not replay any client messages except closing of windows
683  if (e->fType == kClientMessage) {
684  if ((e->fFormat == 32) && (e->fHandle != TRecGuiEvent::kROOT_MESSAGE)
685  && ((Atom_t)e->fUser[0] == TRecGuiEvent::kWM_DELETE_WINDOW))
686  return kFALSE;
687  else
688  return kTRUE;
689  }
690 
691  // See TRecorderRecording::SetTypeOfConfigureNotify to get know
692  // which kConfigureNotify events are filtered
693  if (e->fType == kConfigureNotify && e->fUser[4] == TRecGuiEvent::kCNFilter) {
694  return kTRUE;
695  }
696 
697  if (e->fType == kOtherEvent) {
698  if (e->fFormat >= kGKeyPress && e->fFormat < kOtherEvent)
699  return kFALSE;
700  return kTRUE;
701  }
702 
703  return kFALSE;
704 }
705 
706 ////////////////////////////////////////////////////////////////////////////////
707 /// Finds the next event in log file to replay and sets it to fNextEvent
708 ///
709 /// Reads both from CmdTree and GuiTree and chooses that event that becomes
710 /// earlier
711 /// - fCmdTreeCounter determines actual position in fCmdTree
712 /// - fGuiTreeCounter determines actual position in fCmdTree
713 ///
714 /// If GUI event should be replayed, we must first make sure that there is
715 /// appropriate mapping for this event
716 ///
717 /// RETURN VALUE:
718 /// kFALSE = there is no event to be replayed
719 /// kTRUE = there is still at least one event to be replayed. Cases:
720 /// - fNextEvent = 0 => We are waiting for the appropriate
721 /// window to be registered
722 /// - fNextEvent != 0 => fNextEvent can be replayed (windows are
723 /// ready)
724 
726 {
727  fCmdEvent = 0;
728  fGuiEvent = 0;
729  fExtraEvent = 0;
730  fNextEvent = 0;
731 
732  // Reads the next unreplayed commandline event to fCmdEvent
735 
736  // Reads the next unreplayed extra event to fExtraEvent
739 
740  // Reads the next unreplayed GUI event to fGuiEvent
741  // Skips GUI events that should not be replayed (FilterEvent call)
742  while (fGuiTree->GetEntries() > fGuiTreeCounter) {
744  if (!fGuiEvent || !FilterEvent(fGuiEvent))
745  break;
746  fGuiTreeCounter++;
747  }
748 
749  // Chooses which one will be fNextEvent (the next event to be replayed)
750  if (fCmdEvent && fGuiEvent && fExtraEvent) {
751  // If there are all uf them, compares their times and chooses the
752  // earlier one
753  if ((fCmdEvent->GetTime() <= fGuiEvent->GetTime()) &&
756  else {
757  if (fGuiEvent->GetTime() <= fExtraEvent->GetTime())
759  else
761  }
762  }
763  else if (fCmdEvent && fGuiEvent) {
764  // If there are both of them, compares their times and chooses the
765  // earlier one
766  if (fCmdEvent->GetTime() <= fGuiEvent->GetTime())
768  else
770  }
771  else if (fCmdEvent && fExtraEvent ) {
772  // If there are both of them, compares their times and chooses the
773  // earlier one
774  if (fCmdEvent->GetTime() <= fExtraEvent->GetTime())
776  else
778  }
779  else if (fGuiEvent && fExtraEvent) {
780  // If there are both of them, compares their times and chooses the
781  // earlier one
782  if (fExtraEvent->GetTime() <= fGuiEvent->GetTime())
784  else
786  }
787 
788  // Nor commandline neither event to replay
789  else if (!fCmdEvent && !fGuiEvent && !fExtraEvent)
790  fNextEvent = 0;
791  // Only GUI event to replay
792  else if (fGuiEvent)
794  // Only commandline event to replay
795  else if (fCmdEvent)
797  else
799 
800  // Nothing to replay
801  if (fNextEvent == 0)
802  return kFALSE;
803 
804  // Commandline event to replay
805  if (fNextEvent == fCmdEvent)
806  fCmdTreeCounter++;
807 
808  // Extra event to replay
809  if (fNextEvent == fExtraEvent)
811 
812  // GUI event to replay
813  if (fNextEvent == fGuiEvent) {
814  // We have the new window to send this event to
815  if (RemapWindowReferences())
816  fGuiTreeCounter++;
817  // We do not have it yet (waiting for registraion)
818  else
819  fNextEvent = 0;
820  }
821  return kTRUE;
822 }
823 
824 ////////////////////////////////////////////////////////////////////////////////
825 /// ButtonPress and ButtonRelease must be sometimes replayed more times
826 /// Example: pressing of a button opens small window and user chooses
827 /// something from that window (color)
828 /// Window must be opened while user is choosing
829 
831 {
832  if (!fGuiEvent) {
833  Error("TRecorderReplaying::CanOverlap()", "fGuiEvent = 0");
834  return kFALSE;
835  }
836 
837  // only GUI events overlapping is allowed
839  return kFALSE;
840 
841 
842  if (gDebug > 0) {
843  std::cout << "Event overlapping " <<
844  kRecEventNames[((TRecGuiEvent*)fNextEvent)->fType] << std::endl;
846  }
847 
848  // GUI event
850 
851  // Overlapping allowed for ButtonPress, ButtonRelease and MotionNotify
852  if (e->fType == kButtonPress || e->fType == kButtonRelease ||
853  e->fType == kMotionNotify)
854  return kTRUE;
855 
856  return kFALSE;
857 }
858 
859 ////////////////////////////////////////////////////////////////////////////////
860 /// Replays the next event.
861 ///
862 /// It is called when fTimer times out.
863 /// Every time fTimer is set again to time equal to time difference between
864 /// current two events being replayed.
865 ///
866 /// It can happen that execution of an event lasts different time during the
867 /// recording and during the replaying.
868 /// If fTimer times out too early and the previous event has not been yet
869 /// replayed, it is usually postponed in order
870 /// to keep events execution in the right order.
871 /// The excpetions are determined by TRecorderReplaying::CanOverlap()
872 ///
873 
875 {
876  UInt_t keysym;
877  char str[2];
878 
879  if ((gROOT->GetEditorMode() == kText) ||
880  (gROOT->GetEditorMode() == kPaveLabel)){
881  gROOT->SetEditorMode();
882  }
883 
884  // If there are automatically generated ROOT events in the queue, they
885  // are let to be handled first
886  if (gVirtualX->EventsPending()) {
888  return;
889  }
890 
891  // Previous event has not been replayed yet and it is not allowed for
892  // this event to be replayed more times
893  if (!fEventReplayed && !CanOverlap())
894  return;
895 
896  // Event to replay prepared
897  if (fNextEvent) {
898  // Sets that fNextEvent has not been replayed yet
899  fEventReplayed = 0;
900 
901  // Remembers its execution time to compute time difference with
902  // the next event
904 
905  // Special execution of events causing potential deadlocks
908  if (ev->fType == kGKeyPress && ev->fState & kKeyControlMask) {
909  Event_t *e = ev->CreateEvent(ev);
910  gVirtualX->LookupString(e, str, sizeof(str), keysym);
911  // catch the ctrl-s event
912  if ((keysym & ~0x20) == kKey_S) {
913  fEventReplayed = 1;
916  return;
917  }
918  }
919  }
920 
921  // REPLAYS CURRENT EVENT
923 
924  // Sets that fNextEvent has been replayed
925  fEventReplayed = 1;
926  }
927 
928  // Prepares new event for replaying
929  if (!PrepareNextEvent()) {
930  // No more events to be replayed (replaying has finished).
931 
932  // Switches recorder back to INACTIVE state
933  Info("TRecorderReplaying::ReplayRealtime", "Replaying finished");
935  return;
936  }
937  else {
938  // We have event to replay here.
939 
940  // It will be replayed with the same time difference to the previous
941  // one as when recording.
942  // After given time, timer will call this method again
943  if (fNextEvent)
945  }
946 }
947 
948 ////////////////////////////////////////////////////////////////////////////////
949 /// Pauses replaying
950 
952 {
953  fTimer->Stop();
954  r->ChangeState(new TRecorderPaused(this), kFALSE);
955  Info("TRecorderReplaying::Pause", "Replaying paused.");
956 }
957 
958 ////////////////////////////////////////////////////////////////////////////////
959 /// Cancels replaying
960 
962 {
963  Info("TRecorderReplaying::ReplayStop", "Replaying cancelled");
964  r->ChangeState(new TRecorderInactive());
965 }
966 
967 ////////////////////////////////////////////////////////////////////////////////
968 /// Continues previously paused replaying
969 
971 {
972  if (fNextEvent)
974 }
975 
976 //______________________________________________________________________________
977 // Represents state of TRecorder after its creation
978 
980 
981 ////////////////////////////////////////////////////////////////////////////////
982 /// Switches from INACTIVE state to RECORDING and starts recording
983 
984 void TRecorderInactive::Start(TRecorder *r, const char *filename,
985  Option_t *option, Window_t *w, Int_t winCount)
986 {
987  // const char *filename = name of ROOT file where to store recorded events
988  // Option_t *option = option for creation of ROOT file
989  // Window_t *w = list of IDs of recorder windows (if GUI for
990  // recorder is used) [0 by default]
991  // Int_t winCount = number of IDs it this list [0 by default]
992 
993  TRecorderRecording *rec = new TRecorderRecording(r, filename, option, w, winCount);
994  if (rec->StartRecording()) {
995  r->ChangeState(rec);
996  r->fFilename = gSystem->BaseName(filename);
997  }
998  else
999  delete rec;
1000 }
1001 
1002 ////////////////////////////////////////////////////////////////////////////////
1003 /// Switches from INACTIVE state of recorder to REPLAYING
1004 /// Return kTRUE if replaying has started or kFALSE if it is not possible
1005 /// (bad file etc.)
1006 
1008  Bool_t showMouseCursor,
1010 {
1011  // const char *filename = name of ROOT file from where to replay recorded
1012  // events
1013  // TRecorder::EReplayModes mode = mode of replaying
1014 
1015  TRecorderReplaying *replay = new TRecorderReplaying(filename);
1016 
1017  if (replay->Initialize(r, showMouseCursor, mode)) {
1018  r->ChangeState(replay);
1019  r->fFilename = gSystem->BaseName(filename);
1020  return kTRUE;
1021  }
1022  else {
1023  delete replay;
1024  return kFALSE;
1025  }
1026 }
1027 
1028 ////////////////////////////////////////////////////////////////////////////////
1029 /// Prints out commandline events recorded in given file
1030 
1031 void TRecorderInactive::ListCmd(const char *filename)
1032 {
1033  /*
1034  if (!TClassTable::GetDict(" TRecCmdEvent")) {
1035  Error("TRecorderInactive::List", " TRecCmdEvent not in dictionary.");
1036  return;
1037  }*/
1038 
1039  TFile *file = TFile::Open(filename);
1040  if (!file) return;
1041  if (file->IsZombie() || !file->IsOpen()) {
1042  delete file;
1043  return;
1044  }
1045  TTree *t1 = (TTree*)file->Get(kCmdEventTree);
1046 
1047  if (!t1) {
1048  Error("TRecorderInactive::List",
1049  "The ROOT file is not valid event logfile.");
1050  delete file;
1051  return;
1052  }
1053 
1054  TRecCmdEvent *fCmdEvent = new TRecCmdEvent();
1055  t1->SetBranchAddress(kBranchName, &fCmdEvent);
1056 
1057  Int_t entries = t1->GetEntries();
1058  for (Int_t i = 0; i < entries; ++i) {
1059  t1->GetEntry(i);
1060  std::cout << "[" << i << "] " << "fTime=" <<
1061  (ULong64_t) fCmdEvent->GetTime() << " fText=" <<
1062  fCmdEvent->GetText() << std::endl;
1063  }
1064  std::cout << std::endl;
1065 
1066  delete fCmdEvent;
1067  delete file;
1068 }
1069 
1070 ////////////////////////////////////////////////////////////////////////////////
1071 /// Prints out GUI events recorded in given file
1072 
1073 void TRecorderInactive::ListGui(const char *filename)
1074 {
1075  /*
1076  if (!TClassTable::GetDict("TRecGuiEvent")) {
1077  Error("TRecorderInactive::ListGui",
1078  "TRecGuiEvent not in the dictionary.");
1079  return;
1080  }*/
1081 
1082  TFile *file = TFile::Open(filename);
1083  if (!file) return;
1084  if (file->IsZombie() || !file->IsOpen()) {
1085  delete file;
1086  return;
1087  }
1088  TTree *t1 = (TTree*)file->Get(kGuiEventTree);
1089 
1090  if (!t1) {
1091  Error("TRecorderInactive::ListGui",
1092  "The ROOT file is not valid event logfile.");
1093  delete file;
1094  return;
1095  }
1096 
1097  TRecGuiEvent *guiEvent = new TRecGuiEvent();
1098  t1->SetBranchAddress(kBranchName, &guiEvent);
1099 
1100  Int_t entries = t1->GetEntries();
1101 
1102  for (Int_t i = 0; i < entries ; ++i) {
1103  t1->GetEntry(i);
1104  DumpRootEvent(guiEvent, i);
1105  }
1106 
1107  delete file;
1108  delete guiEvent;
1109 }
1110 
1111 ////////////////////////////////////////////////////////////////////////////////
1112 /// Prints out attributes of one GUI event TRecGuiEvent *e
1113 /// Int_n n is number of event if called in cycle
1114 
1116 {
1117  std::ios::fmtflags f = std::cout.flags(); // store flags
1118  std::cout << "[" << n << "] " << std::dec << std::setw(10)
1119  << e->GetTime().AsString() << std::setw(15) << kRecEventNames[e->fType]
1120  << " fW:" << std::hex << e->fWindow
1121  << " t:" << std::dec << e->fTime
1122  << " x:" << DisplayValid(e->fX)
1123  << " y:" << DisplayValid(e->fY)
1124  << " fXR:" << DisplayValid(e->fXRoot)
1125  << " fYR:" << DisplayValid(e->fYRoot)
1126  << " c:" << DisplayValid(e->fCode)
1127  << " s:" << DisplayValid(e->fState)
1128  << " w:" << DisplayValid(e->fWidth)
1129  << " h:" << DisplayValid(e->fHeight)
1130  << " cnt:" << DisplayValid(e->fCount)
1131  << " se:" << e->fSendEvent
1132  << " h:" << e->fHandle
1133  << " fF:" << DisplayValid(e->fFormat)
1134  << " | ";
1135 
1136  for (Int_t i=0; i<5; ++i)
1137  if (DisplayValid(e->fUser[i]) != -1)
1138  std::cout << "[" << i << "]=" << DisplayValid(e->fUser[i]);
1139 
1140  if (e->fMasked)
1141  std::cout << " | fM:" << std::hex << e->fMasked;
1142 
1143  std::cout << std::endl;
1144  std::cout.flags( f ); // restore flags (reset std::hex)
1145 }
1146 
1147 ////////////////////////////////////////////////////////////////////////////////
1148 /// Save previous canvases in a .root file
1149 
1150 void TRecorderInactive::PrevCanvases(const char *filename, Option_t *option)
1151 {
1152  fCollect = gROOT->GetListOfCanvases();
1153  TFile *f = TFile::Open(filename, option);
1154  if (f && !f->IsZombie()) {
1155  fCollect->Write();
1156  f->Close();
1157  delete f;
1158  }
1159 }
1160 
1161 //______________________________________________________________________________
1162 // Represents state of TRecorder when paused
1163 
1165 
1166 ////////////////////////////////////////////////////////////////////////////////
1167 /// Rememeber the recorder state that is paused
1168 
1170 {
1171  fReplayingState = state;
1172 }
1173 
1174 ////////////////////////////////////////////////////////////////////////////////
1175 /// Continues replaying
1176 
1178 {
1180  Info("TRecorderPaused::Resume", "Replaying resumed");
1181 
1182  // Switches back to the previous replaying state
1183  r->ChangeState(fReplayingState);
1184 }
1185 
1186 ////////////////////////////////////////////////////////////////////////////////
1187 /// Replaying is cancelled
1188 
1190 {
1191  delete fReplayingState;
1192 
1193  Info("TRecorderReplaying::ReplayStop", "Reaplying cancelled");
1194  r->ChangeState(new TRecorderInactive());
1195 }
1196 
1197 
1198 //______________________________________________________________________________
1199 // Represents state of TRecorder when recording events
1200 
1202 
1203 ////////////////////////////////////////////////////////////////////////////////
1204 /// Initializes TRecorderRecording for recording
1205 /// What is allocated here is deleted in destructor
1206 
1208  Option_t *option, Window_t *w,
1209  Int_t winCount)
1210 {
1211  fRecorder = r;
1212  fBeginPave = 0;
1213 
1214  // Remember window IDs of GUI recorder (appropriate events are
1215  // filtered = not recorded)
1216  fFilteredIdsCount = winCount;
1218  for(Int_t i=0; i < fFilteredIdsCount; ++i)
1219  fFilteredIds[i] = w[i];
1220 
1221  // No unhandled commandline event in the beginning
1223 
1224  // Filer pave events (mouse button move)
1226 
1227  // No registered windows in the beginning
1228  fRegWinCounter = 0;
1229 
1230  // New timer for recording
1231  fTimer = new TTimer(25, kTRUE);
1232 
1233  fMouseTimer = new TTimer(50, kTRUE);
1234  fMouseTimer->Connect("Timeout()", "TRecorderRecording", this,
1235  "RecordMousePosition()");
1236 
1237  // File where store recorded events
1238  fFile = TFile::Open(filename, option);
1239 
1240  // TTrees with windows, commandline events and GUi events
1241  fWinTree = new TTree(kWindowsTree, "Windows");
1242  fCmdTree = new TTree(kCmdEventTree, "Commandline events");
1243  fGuiTree = new TTree(kGuiEventTree, "GUI events");
1244  fExtraTree = new TTree(kExtraEventTree, "Extra events");
1245 
1246  fWin = 0;
1247  fCmdEvent = new TRecCmdEvent();
1248  fGuiEvent = new TRecGuiEvent();
1249  fExtraEvent = new TRecExtraEvent();
1250 }
1251 
1252 ////////////////////////////////////////////////////////////////////////////////
1253 /// Freeing of allocated memory
1254 
1256 {
1257  delete[] fFilteredIds;
1258 
1259  if (fFile)
1260  delete fFile;
1261  delete fMouseTimer;
1262  delete fTimer;
1263  delete fCmdEvent;
1264  delete fGuiEvent;
1265  delete fExtraEvent;
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Connects appropriate signals and slots in order to gain all registered
1270 /// windows and processed events in ROOT and then starts recording
1271 
1273 {
1274  if (!fFile || fFile->IsZombie() || !fFile->IsOpen())
1275  return kFALSE;
1276 
1277  // When user types something in the commandline,
1278  // TRecorderRecording::RecordCmdEvent(const char *line) is called
1279  gApplication->Connect("LineProcessed(const char*)", "TRecorderRecording",
1280  this, "RecordCmdEvent(const char*)");
1281 
1282  // When a new window in ROOT is registered,
1283  // TRecorderRecording::RegisterWindow(Window_t) is called
1284  gClient->Connect("RegisteredWindow(Window_t)", "TRecorderRecording", this,
1285  "RegisterWindow(Window_t)");
1286 
1287  // When a GUI event (different from kConfigureNotify) is processed in
1288  // TGClient::HandleEvent or in TGClient::HandleMaskEvent,
1289  // TRecorderRecording::RecordGuiEvent(Event_t*, Window_t) is called
1290  gClient->Connect("ProcessedEvent(Event_t*, Window_t)", "TRecorderRecording",
1291  this, "RecordGuiEvent(Event_t*, Window_t)");
1292 
1293  // When a kConfigureNotify event is processed in TGFrame::HandleEvent,
1294  // TRecorderRecording::RecordGuiCNEvent(Event_t*) is called
1295  TQObject::Connect("TGFrame", "ProcessedConfigure(Event_t*)",
1296  "TRecorderRecording", this, "RecordGuiCNEvent(Event_t*)");
1297 
1298  // When a PaveLabel is created, TRecorderRecording::RecordPave(TObject*)
1299  // is called
1300  TQObject::Connect("TPad", "RecordPave(const TObject*)", "TRecorderRecording",
1301  this, "RecordPave(const TObject*)");
1302 
1303  // When a Text is created, TRecorderRecording::RecordText() is called
1304  TQObject::Connect("TPad", "RecordLatex(const TObject*)",
1305  "TRecorderRecording", this, "RecordText(const TObject*)");
1306 
1307  // When a PaveLabel is created, TRecorderRecording::FilterEventPave()
1308  // is called to filter mouse clicks events.
1309  TQObject::Connect("TPad", "EventPave()", "TRecorderRecording", this,
1310  "FilterEventPave()");
1311 
1312  // When starting editing a TLatex or a TPaveLabel, StartEditing()
1313  // is called to memorize edition starting time.
1314  TQObject::Connect("TPad", "StartEditing()", "TRecorderRecording", this,
1315  "StartEditing()");
1316 
1317  // Gui Builder specific events.
1318  TQObject::Connect("TGuiBldDragManager", "TimerEvent(Event_t*)",
1319  "TRecorderRecording", this, "RecordGuiBldEvent(Event_t*)");
1320 
1321  // Creates in TTrees appropriate branches to store registered windows,
1322  // commandline events and GUI events
1323  fWinTree->Branch(kBranchName, &fWin, "fWin/l");
1324  fCmdTree->Branch(kBranchName, " TRecCmdEvent", &fCmdEvent);
1325  fGuiTree->Branch(kBranchName, "TRecGuiEvent", &fGuiEvent);
1326  fExtraTree->Branch(kBranchName, "TRecExtraEvent", &fExtraEvent);
1327 
1328  Int_t numCanvases = gROOT->GetListOfCanvases()->LastIndex();
1329 
1330  if (numCanvases >= 0){
1331 
1332  TIter nextwindow (gClient->GetListOfWindows());
1333  TGWindow *twin;
1334  Window_t twin2;
1335  Int_t cnt = 0;
1336  while ((twin = (TGWindow*) nextwindow())) {
1337  twin2 = (Window_t) twin->GetId();
1338  if (IsFiltered(twin2)) {
1339  if (gDebug > 0) {
1340  std::cout << "WindowID "<< twin2 << " filtered" << std::endl;
1341  }
1342  }
1343  else if (twin != gClient->GetRoot()) {
1344  RegisterWindow(twin2);
1345  }
1346  cnt++;
1347  }
1348  //Info("TRecorderRecording::StartRecording", "Previous Canvases");
1349  }
1350 
1351  // Starts the timer for recording
1352  fTimer->TurnOn();
1353 
1354  // start mouse events recording timer
1355  fMouseTimer->Start(50);
1356 
1357  Info("TRecorderRecording::StartRecording", "Recording started. Log file: %s",
1358  fFile->GetName());
1359 
1360  return kTRUE;
1361 }
1362 
1363 ////////////////////////////////////////////////////////////////////////////////
1364 /// Disconnects all slots and stopps recording.
1365 
1367 {
1368  TQObject::Disconnect("TGuiBldDragManager", "TimerEvent(Event_t*)", this,
1369  "RecordGuiBldEvent(Event_t*)");
1370  TQObject::Disconnect("TGFrame", "ProcessedConfigure(Event_t*)", this,
1371  "RecordGuiCNEvent(Event_t*)");
1372  TQObject::Disconnect("TPad", "RecordPave(const TObject*)", this,
1373  "RecordPave(const TObject*)");
1374  TQObject::Disconnect("TPad", "RecordLatex(const TObject*)", this,
1375  "RecordText(const TObject*)");
1376  TQObject::Disconnect("TPad", "EventPave()", this, "FilterEventPave()");
1377  TQObject::Disconnect("TPad", "StartEditing()", this, "StartEditing()");
1378  gClient->Disconnect(gClient, "ProcessedEvent(Event_t*, Window_t)", this,
1379  "RecordGuiEvent(Event_t*, Window_t)");
1380  gClient->Disconnect(gClient, "RegisteredWindow(Window_t)", this,
1381  "RegisterWindow(Window_t)");
1382  gApplication->Disconnect(gApplication, "LineProcessed(const char*)", this,
1383  "RecordCmdEvent(const char*)");
1384 
1385  // Decides if to store the last event. It is stored if GUI recorder is used,
1386  // otherwise it is 'TEventRecorded::Stop' and should not be stored
1387  if (fCmdEventPending && guiCommand)
1388  fCmdTree->Fill();
1389 
1390  fRecorder->Write("recorder");
1391  fFile->Write();
1392  fFile->Close();
1393  fTimer->TurnOff();
1394 
1395  fMouseTimer->TurnOff();
1396 
1397  Info("TRecorderRecording::Stop", "Recording finished.");
1398 
1400 }
1401 
1402 ////////////////////////////////////////////////////////////////////////////////
1403 /// This method is called when RegisteredWindow(Window_t) is emitted from
1404 /// TGClient.
1405 
1407 {
1408  // Stores ID of the registered window in appropriate TTree
1409  fWin = (ULong64_t) w;
1410  fWinTree->Fill();
1411 }
1412 
1413 ////////////////////////////////////////////////////////////////////////////////
1414 /// Records commandline event (text and time) ans saves the previous
1415 /// commandline event
1416 /// This 1 event delay in saving ensures that the last commandline events
1417 /// 'TRecorder::Stop' will be not stored
1418 
1420 {
1421  // If there is some previously recorded event, saves it in TTree now
1422  if (fCmdEventPending)
1423  fCmdTree->Fill();
1424 
1425  // Fill information about this new commandline event: command text and
1426  // time of event execution
1428  fCmdEvent->SetText((char*)line);
1429 
1430  // This event will be stored next time (if it is not the last one
1431  // 'TRecorder::Stop')
1433  return;
1434 }
1435 
1436 ////////////////////////////////////////////////////////////////////////////////
1437 /// Records GUI Event_t *e different from kConfigureNotify (they are
1438 /// recorded in TRecorderRecording::RecordGuiCNEvent)
1439 ///
1440 /// It is called via signal-slot when an event is processed in
1441 /// TGClient::HandleEvent(Event_t *event)
1442 /// or in TGClient::HandleMaskEvent(Event_t *event, Window_t wid)
1443 ///
1444 /// If signal is emitted from TGClient::HandleEvent(Event_t *event),
1445 /// then wid = 0
1446 
1448 {
1449  // If this event is caused by a recorder itself (GUI recorder),
1450  // it is not recorded
1451  if (fFilteredIdsCount && IsFiltered(e->fWindow))
1452  return;
1453 
1454  // Doesn't record the mouse clicks when a pavelabel is recorded
1455  if (fFilterEventPave && (e->fCode == 1)) {
1457  return;
1458  }
1460 
1461  // don't record any copy/paste event, as event->fUser[x] parameters
1462  // will be invalid when replaying on a different OS
1463  if (e->fType == kSelectionClear || e->fType == kSelectionRequest ||
1464  e->fType == kSelectionNotify)
1465  return;
1466 
1467  // Copies all items of e to fGuiEvent
1468  CopyEvent(e, wid);
1469 
1470  // Saves time of recording
1472 
1473  // Saves recorded event itself in TTree
1474  fGuiTree->Fill();
1475 }
1476 
1477 ////////////////////////////////////////////////////////////////////////////////
1478 /// Special case for the gui builder, having a timer handling some of the
1479 /// events.
1480 
1482 {
1483  e->fFormat = e->fType;
1484  e->fType = kOtherEvent;
1485 
1486  // Copies all items of e to fGuiEvent
1487  CopyEvent(e, 0);
1488 
1489  // Saves time of recording
1491 
1492  // Saves recorded event itself in TTree
1493  fGuiTree->Fill();
1494 }
1495 
1496 ////////////////////////////////////////////////////////////////////////////////
1497 /// Try to record all mouse moves...
1498 
1500 {
1501  Window_t dum;
1502  Event_t ev;
1503  ev.fCode = 0;
1504  ev.fType = kMotionNotify;
1505  ev.fState = 0;
1506  ev.fWindow = 0;
1507  ev.fUser[0] = ev.fUser[1] = ev.fUser[2] = ev.fUser[3] = ev.fUser[4] = 0;
1508  ev.fCount = 0;
1509  ev.fFormat = 0;
1510  ev.fHandle = 0;
1511  ev.fHeight = 0;
1512  ev.fSendEvent = 0;
1513  ev.fTime = 0;
1514  ev.fWidth = 0;
1515 
1516  gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(), dum, dum,
1517  ev.fXRoot, ev.fYRoot, ev.fX, ev.fY, ev.fState);
1518  ev.fXRoot -= gDecorWidth;
1519  ev.fYRoot -= gDecorHeight;
1520 
1521  RecordGuiEvent(&ev, 0);
1522  fMouseTimer->Reset();
1523 }
1524 
1525 ////////////////////////////////////////////////////////////////////////////////
1526 /// Records GUI Event_t *e of type kConfigureNotify.
1527 /// It is called via signal-slot when an kConfigureNotify event is processed
1528 /// in TGFrame::HandleEvent
1529 
1531 {
1532  // If this event is caused by a recorder itself, it is not recorded
1533  if (fFilteredIdsCount && IsFiltered(e->fWindow))
1534  return;
1535 
1536  // Sets fUser[4] value to one of EConfigureNotifyType
1537  // According to this value, event is or is not replayed in the future
1539 
1540  // Copies all items of e to fGuiEvent
1541  CopyEvent(e, 0);
1542 
1543  // Saves time of recording
1545 
1546  // Saves recorded event itself in TTree
1547  fGuiTree->Fill();
1548 }
1549 
1550 ////////////////////////////////////////////////////////////////////////////////
1551 /// Records TPaveLabel object created in TCreatePrimitives::Pave()
1552 
1554 {
1555  Long64_t extratime = fBeginPave;
1556  Long64_t interval = (Long64_t)fTimer->GetAbsTime() - fBeginPave;
1557  TPaveLabel *pavel = (TPaveLabel *) obj;
1558  const char *label;
1559  label = pavel->GetLabel();
1560  TString aux = "";
1561  TString cad = "";
1562  cad = "TPaveLabel *p = new TPaveLabel(";
1563  cad += pavel->GetX1();
1564  cad += ",";
1565  cad += pavel->GetY1();
1566  cad += ",";
1567  cad += pavel->GetX2();
1568  cad += ",";
1569  cad += pavel->GetY2();
1570  cad += ",\"\"); p->Draw(); gPad->Modified(); gPad->Update();";
1571  Int_t i, len = (Int_t)strlen(label);
1572  interval /= (len + 2);
1573  RecordExtraEvent(cad, extratime);
1574  for (i=0; i < len; ++i) {
1575  cad = "p->SetLabel(\"";
1576  cad += (aux += label[i]);
1577  cad += "\"); ";
1578 #ifndef R__WIN32
1579  cad += " p->SetTextFont(83); p->SetTextSizePixels(14); ";
1580 #endif
1581  cad += " gPad->Modified(); gPad->Update();";
1582  extratime += interval;
1583  RecordExtraEvent(cad, extratime);
1584  }
1585  cad = "p->SetTextFont(";
1586  cad += pavel->GetTextFont();
1587  cad += "); p->SetTextSize(";
1588  cad += pavel->GetTextSize();
1589  cad += "); gPad->Modified(); gPad->Update();";
1590  extratime += interval;
1591  RecordExtraEvent(cad, extratime);
1592 }
1593 
1594 ////////////////////////////////////////////////////////////////////////////////
1595 /// Records TLatex object created in TCreatePrimitives::Text()
1596 
1598 {
1599  Long64_t extratime = fBeginPave;
1600  Long64_t interval = (Long64_t)fTimer->GetAbsTime() - fBeginPave;
1601  TLatex *texto = (TLatex *) obj;
1602  const char *label;
1603  label = texto->GetTitle();
1604  TString aux = "";
1605  TString cad = "";
1606  cad = "TLatex *l = new TLatex(";
1607  cad += texto->GetX();
1608  cad += ",";
1609  cad += texto->GetY();
1610  cad += ",\"\"); l->Draw(); gPad->Modified(); gPad->Update();";
1611  Int_t i, len = (Int_t)strlen(label);
1612  interval /= (len + 2);
1613  RecordExtraEvent(cad, extratime);
1614  for (i=0; i < len; ++i) {
1615  cad = "l->SetTitle(\"";
1616  cad += (aux += label[i]);
1617  cad += "\"); ";
1618 #ifndef R__WIN32
1619  cad += " l->SetTextFont(83); l->SetTextSizePixels(14); ";
1620 #endif
1621  cad += " gPad->Modified(); gPad->Update();";
1622  extratime += interval;
1623  RecordExtraEvent(cad, extratime);
1624  }
1625  cad = "l->SetTextFont(";
1626  cad += texto->GetTextFont();
1627  cad += "); l->SetTextSize(";
1628  cad += texto->GetTextSize();
1629  cad += "); gPad->Modified(); gPad->Update();";
1630  cad += " TVirtualPad *spad = gPad->GetCanvas()->GetSelectedPad();";
1631  cad += " gPad->GetCanvas()->Selected(spad, l, kButton1Down);";
1632  extratime += interval;
1633  RecordExtraEvent(cad, extratime);
1634 }
1635 
1636 ////////////////////////////////////////////////////////////////////////////////
1637 /// Change the state of the flag to kTRUE when you are recording a pavelabel.
1638 
1640 {
1642 }
1643 
1644 ////////////////////////////////////////////////////////////////////////////////
1645 /// Memorize the starting time of editinga TLatex or a TPaveLabel
1646 
1648 {
1650 }
1651 
1652 ////////////////////////////////////////////////////////////////////////////////
1653 /// Records TLatex or TPaveLabel object created in TCreatePrimitives,
1654 /// ExtTime is needed for the correct replay of these events.
1655 
1657 {
1658  fExtraEvent->SetTime(extTime);
1660  fExtraTree->Fill();
1661 }
1662 
1663 ////////////////////////////////////////////////////////////////////////////////
1664 /// Copies all items of given event to fGuiEvent
1665 
1667 {
1668  fGuiEvent->fType = e->fType;
1669  fGuiEvent->fWindow = e->fWindow;
1670  fGuiEvent->fTime = e->fTime;
1671 
1672  fGuiEvent->fX = e->fX;
1673  fGuiEvent->fY = e->fY;
1674  fGuiEvent->fXRoot = e->fXRoot;
1675  fGuiEvent->fYRoot = e->fYRoot;
1676 
1677  fGuiEvent->fCode = e->fCode;
1678  fGuiEvent->fState = e->fState;
1679 
1680  fGuiEvent->fWidth = e->fWidth;
1681  fGuiEvent->fHeight = e->fHeight;
1682 
1683  fGuiEvent->fCount = e->fCount;
1684  fGuiEvent->fSendEvent = e->fSendEvent;
1685  fGuiEvent->fHandle = e->fHandle;
1686  fGuiEvent->fFormat = e->fFormat;
1687 
1690 
1691  for(Int_t i=0; i<5; ++i)
1692  fGuiEvent->fUser[i] = e->fUser[i];
1693 
1694  if (fGuiEvent->fUser[0] == (Int_t)gWM_DELETE_WINDOW)
1696 
1697  if (e->fType == kGKeyPress || e->fType == kKeyRelease) {
1698  char tmp[10] = {0};
1699  UInt_t keysym = 0;
1700  gVirtualX->LookupString(e, tmp, sizeof(tmp), keysym);
1701  fGuiEvent->fCode = keysym;
1702  }
1703 
1704  fGuiEvent->fMasked = wid;
1705 }
1706 
1707 ////////////////////////////////////////////////////////////////////////////////
1708 /// Returns kTRUE if passed id belongs to window IDs of recorder GUI itself
1709 
1711 {
1712  for(Int_t i=0; i < fFilteredIdsCount; ++i)
1713  if (id == fFilteredIds[i])
1714  return kTRUE;
1715 
1716  return kFALSE;
1717 }
1718 
1719 ////////////////////////////////////////////////////////////////////////////////
1720 /// Sets type of kConfigureNotify event to one of EConfigureNotify
1721 ///
1722 /// On Linux paremeters of GUI event kConfigureNotify are different
1723 /// than parameters of the same event executed on Windows.
1724 /// Therefore we need to distinguish [on Linux], if the event is movement
1725 /// or resize event.
1726 /// On Windows, we do not need to distinguish them.
1727 
1729 {
1730  // On both platforms, we mark the events matching the criteria
1731  // (automatically generated in ROOT) as events that should be filtered
1732  // when replaying (TRecGuiEvent::kCNFilter)
1733  if ((e->fX == 0 && e->fY == 0)) { // || e->fFormat == 32 ) {
1734  e->fUser[4] = TRecGuiEvent::kCNFilter;
1735  return;
1736  }
1737 
1738 #ifdef WIN32
1739 
1740  // No need to distinguish between move and resize on Windows
1741  e->fUser[4] = TRecGuiEvent::kCNMoveResize;
1742 
1743 #else
1744 
1745  TGWindow *w = gClient->GetWindowById(e->fWindow);
1746  if (w) {
1747  TGFrame *t = (TGFrame *)w;
1748 
1749  // If this event does not cause any change in position or size ->
1750  // automatically generated event
1751  if (t->GetWidth() == e->fWidth && t->GetHeight() == e->fHeight &&
1752  e->fX == t->GetX() && e->fY == t->GetY()) {
1753  e->fUser[4] = TRecGuiEvent::kCNFilter;
1754  }
1755  else {
1756  // Size of the window did not change -> move
1757  if (t->GetWidth() == e->fWidth && t->GetHeight() == e->fHeight) {
1758  e->fUser[4] = TRecGuiEvent::kCNMove;
1759  }
1760  // Size of the window changed -> resize
1761  else {
1762  e->fUser[4] = TRecGuiEvent::kCNResize;
1763  }
1764  }
1765  }
1766 
1767 #endif
1768 }
1769 
1770 
1771 
1772 //______________________________________________________________________________
1773 // The GUI for the recorder
1774 
1776 
1777 ////////////////////////////////////////////////////////////////////////////////
1778 /// The GUI for the recorder
1779 
1781  TGMainFrame(p ? p : gClient->GetRoot(), w, h)
1782 {
1783  TGHorizontalFrame *hframe;
1784  TGVerticalFrame *vframe;
1786  fRecorder = new TRecorder();
1787  fFilteredIds[0] = GetId();
1788 
1789  // Create a horizontal frame widget with buttons
1790  hframe = new TGHorizontalFrame(this, 200, 75, kChildFrame | kFixedHeight,
1791  (Pixel_t)0x000000);
1792  fFilteredIds[1] = hframe->GetId();
1793 
1794  // LABEL WITH TIME
1795 
1796  vframe = new TGVerticalFrame(hframe, 200, 75, kChildFrame | kFixedHeight,
1797  (Pixel_t)0x000000);
1798  fFilteredIds[2] = vframe->GetId();
1799 
1800  TGLabel *fStatusLabel = new TGLabel(vframe, "Status:");
1801  fStatusLabel->SetTextColor(0x7cffff);
1802  fStatusLabel->SetBackgroundColor((Pixel_t)0x000000);
1803  vframe->AddFrame(fStatusLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,
1804  2, 2, 2, 2));
1805  fFilteredIds[3] = fStatusLabel->GetId();
1806 
1807  TGLabel *fTimeLabel = new TGLabel(vframe, "Time: ");
1808  fTimeLabel->SetTextColor(0x7cffff);
1809  fTimeLabel->SetBackgroundColor((Pixel_t)0x000000);
1810  vframe->AddFrame(fTimeLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop,
1811  2, 2, 13, 2));
1812  fFilteredIds[4] = fTimeLabel->GetId();
1813 
1814  hframe->AddFrame(vframe, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
1815 
1816  vframe = new TGVerticalFrame(hframe, 200, 75, kChildFrame | kFixedHeight,
1817  (Pixel_t)0x000000);
1818  fFilteredIds[5] = vframe->GetId();
1819 
1820  fStatus = new TGLabel(vframe, "Inactive");
1821  fStatus->SetTextColor(0x7cffff);
1822  fStatus->SetBackgroundColor((Pixel_t)0x000000);
1824  2, 2, 2, 2));
1825  fFilteredIds[6] = fStatus->GetId();
1826 
1827  fTimeDisplay = new TGLabel(vframe, "00:00:00");
1828  fTimeDisplay->SetTextColor(0x7cffff);
1829  fTimeDisplay->SetTextFont("Helvetica -34", kFALSE);
1832  2, 2, 2, 2));
1834 
1835  hframe->AddFrame(vframe, new TGLayoutHints(kLHintsLeft | kLHintsExpandY,
1836  10, 0, 0, 0));
1837  AddFrame(hframe, new TGLayoutHints(kLHintsExpandX, 2, 2, 2, 2));
1838 
1839  // Create a horizontal frame widget with buttons
1840  hframe = new TGHorizontalFrame(this, 200, 200);
1841  fFilteredIds[8] = hframe->GetId();
1842 
1843  // START-STOP button
1844  fStartStop = new TGPictureButton(hframe,gClient->GetPicture("record.png"));
1845  fStartStop->SetStyle(gClient->GetStyle());
1846  fStartStop->Connect("Clicked()","TGRecorder",this,"StartStop()");
1848  2, 2, 2, 2));
1849  fStartStop->Resize(40,40);
1850  fFilteredIds[9] = fStartStop->GetId();
1851 
1852  // REPLAY button
1853  fReplay = new TGPictureButton(hframe,gClient->GetPicture("replay.png"));
1854  fReplay->SetStyle(gClient->GetStyle());
1855  fReplay->Connect("Clicked()","TGRecorder",this,"Replay()");
1857  2, 2, 2, 2));
1858  fReplay->Resize(40,40);
1859  fFilteredIds[10] = fReplay->GetId();
1860 
1861  // MOUSE CURSOR CHECKBOX
1862  fCursorCheckBox = new TGCheckButton(this,"Show mouse cursor");
1865 
1866  // Timer
1867  fTimer = new TTimer(25);
1868  fTimer->Connect("Timeout()", "TGRecorder", this, "Update()");
1869 
1870  AddFrame(hframe, new TGLayoutHints(kLHintsCenterX, 2, 2, 2, 2));
1871 
1873  SetWindowName("ROOT Event Recorder");
1874  MapSubwindows();
1875  Layout();
1876  MapWindow();
1877 
1878  SetDefault();
1879 }
1880 
1881 ////////////////////////////////////////////////////////////////////////////////
1882 /// Sets GUI to the default inactive state
1883 
1885 {
1886  fTimeDisplay->SetText("00:00:00");
1887 
1888  fReplay->SetPicture(gClient->GetPicture("replay.png"));
1890 
1893 
1894  fStartStop->SetPicture(gClient->GetPicture("record.png"));
1896 }
1897 
1898 ////////////////////////////////////////////////////////////////////////////////
1899 /// Called when fTimer timeouts (every 0.025 second)
1900 /// Updates GUI of recorder
1901 
1903 {
1904  struct tm *running;
1905  static int cnt = 0;
1906  TString stime;
1907  time( &fElapsed );
1908  time_t elapsed_time = (time_t)difftime( fElapsed, fStart );
1909  running = gmtime( &elapsed_time );
1910 
1911  switch(fRecorder->GetState()) {
1912 
1913  // When recording or replaying, updates timer
1914  // and displays new value of seconds counter
1915  case TRecorder::kRecording:
1916  case TRecorder::kReplaying:
1917 
1918  // Every whole second: updates timer and displays new value
1919  if (cnt >= 10) {
1921  fStatus->SetText("Replaying");
1922  else
1923  fStatus->SetText("Recording");
1924  stime.Form("%02d:%02d:%02d", running->tm_hour,
1925  running->tm_min, running->tm_sec);
1926  fTimeDisplay->SetText(stime.Data());
1927 
1928  cnt = 0;
1929  if (gVirtualX->EventsPending()) {
1930  fStatus->SetText("Waiting...");
1931  fStatus->SetTextColor((Pixel_t)0xff0000);
1932  }
1933  else {
1934  fStatus->SetTextColor((Pixel_t)0x7cffff);
1935  }
1936  fStatus->Resize();
1937  fTimeDisplay->Resize();
1938  }
1939  else
1940  ++cnt;
1941 
1942  // Changes background color according to the queue of pending events
1943  fTimer->Reset();
1944  break;
1945 
1946  // End of replaying or recording. Sets recorder GUI to default state
1947  case TRecorder::kInactive:
1948  fStatus->SetText("Inactive");
1949  fStatus->SetTextColor((Pixel_t)0x7cffff);
1950  fStatus->Resize();
1951  fTimer->TurnOff();
1952  SetDefault();
1953  break;
1954 
1955  default:
1956  break;
1957  }
1958 }
1959 
1960 ////////////////////////////////////////////////////////////////////////////////
1961 /// Handles push of the fStartStop button
1962 /// according to the current recorder state
1963 
1965 {
1966  static const char *gFiletypes[] = {
1967  "All files", "*", "Text files", "*.txt", "ROOT files", "*.root", 0, 0
1968  };
1969  TGFileInfo fi;
1970 
1971  switch(fRecorder->GetState()) {
1972 
1973  // Starts recording
1974  case TRecorder::kInactive:
1975 
1976  fi.fFileTypes = gFiletypes;
1977  fi.fOverwrite = kFALSE;
1978 
1979  new TGFileDialog(gClient->GetDefaultRoot(),
1980  gClient->GetDefaultRoot(),
1981  kFDSave,&fi);
1982 
1983  if (fi.fFilename && strlen(fi.fFilename)) {
1984 
1985  if (!gROOT->GetListOfCanvases()->IsEmpty()) {
1986  fRecorder->PrevCanvases(fi.fFilename, "RECREATE");
1987  fRecorder->Start(fi.fFilename, "UPDATE", fFilteredIds,
1988  fgWidgetsCount);
1989  }
1990  else {
1991  fRecorder->Start(fi.fFilename, "RECREATE", fFilteredIds,
1992  fgWidgetsCount);
1993  }
1995  fStartStop->SetPicture(gClient->GetPicture("stop.png"));
1997  fTimer->TurnOn();
1998  time( &fStart );
1999  }
2000  break;
2001 
2002  // Stops recording
2003  case TRecorder::kRecording:
2004  fRecorder->Stop(kTRUE);
2005  break;
2006 
2007  // Pauses replaying
2008  case TRecorder::kReplaying:
2009  fRecorder->Pause();
2010  fStartStop->SetPicture(gClient->GetPicture("replay.png"));
2011  break;
2012 
2013  // Resumes replaying
2014  case TRecorder::kPaused:
2015  fRecorder->Resume();
2016  fStartStop->SetPicture(gClient->GetPicture("pause.png"));
2017  break;
2018 
2019  default:
2020  break;
2021  } // switch
2022 }
2023 
2024 ////////////////////////////////////////////////////////////////////////////////
2025 /// Handles push of fReplay button
2026 /// according to the current recorder state
2027 
2029 {
2030  TGFileInfo fi;
2031 
2032  switch(fRecorder->GetState()) {
2033 
2034  // Starts replaying
2035  case TRecorder::kInactive:
2036 
2037  new TGFileDialog(gClient->GetDefaultRoot(),
2038  gClient->GetDefaultRoot(),
2039  kFDOpen, &fi);
2040 
2041  if (fi.fFilename && strlen(fi.fFilename)) {
2043 
2044  fTimer->TurnOn();
2045  time( &fStart );
2046 
2047  fReplay->SetPicture(gClient->GetPicture("stop.png"));
2048  fStartStop->SetPicture(gClient->GetPicture("pause.png"));
2049 
2050  if (fCursorCheckBox->IsOn())
2052 
2054  }
2055  }
2056  break;
2057 
2058  // Stops replaying
2059  case TRecorder::kReplaying:
2060  case TRecorder::kPaused:
2061  fRecorder->ReplayStop();
2062  break;
2063 
2064  default:
2065  break;
2066 
2067  } // switch
2068 }
2069 
2070 ////////////////////////////////////////////////////////////////////////////////
2071 /// Destructor. Cleanup the GUI.
2072 
2074 {
2075  fTimer->TurnOff();
2076  delete fTimer;
2077  Cleanup();
2078 }
2079 
2080 //______________________________________________________________________________
2081 // Helper class
2082 
2085 
2086 ////////////////////////////////////////////////////////////////////////////////
2087 /// Replays stored GUI event
2088 
2089 void TRecGuiEvent::ReplayEvent(Bool_t showMouseCursor)
2090 {
2091  Int_t px, py, dx, dy;
2092  Window_t wtarget;
2093  Event_t *e = CreateEvent(this);
2094 
2095  // don't try to replay any copy/paste event, as event->fUser[x]
2096  // parameters are invalid on different OSes
2097  if (e->fType == kSelectionClear || e->fType == kSelectionRequest ||
2098  e->fType == kSelectionNotify) {
2099  delete e;
2100  return;
2101  }
2102 
2103  // Replays movement/resize event
2104  if (e->fType == kConfigureNotify) {
2105  TGWindow *w = gClient->GetWindowById(e->fWindow);
2106 
2107  // Theoretically, w should always exist (we found the right mapping,
2108  // otherwise we would not get here).
2109  // Anyway, it can happen that it was destroyed by some earlier ROOT event
2110  // We give higher priority to automatically generated
2111  // ROOT events in TRecorderReplaying::ReplayRealtime.
2112 
2113  if (w) {
2114  WindowAttributes_t attr;
2115  if (e->fUser[4] == TRecGuiEvent::kCNMove) {
2116  // Linux: movement of the window
2117  // first get window attribute to compensate the border size
2118  gVirtualX->GetWindowAttributes(e->fWindow, attr);
2119  if ((e->fX - attr.fX > 0) && (e->fY - attr.fY > 0))
2120  w->Move(e->fX - attr.fX, e->fY - attr.fY);
2121  }
2122  else {
2123  if (e->fUser[4] == TRecGuiEvent::kCNResize) {
2124  // Linux: resize of the window
2125  w->Resize(e->fWidth, e->fHeight);
2126  }
2127  else {
2128  if (e->fUser[4] == TRecGuiEvent::kCNMoveResize) {
2129  // Windows: movement or resize of the window
2130  w->MoveResize(e->fX, e->fY, e->fWidth, e->fHeight);
2131  }
2132  else {
2133  if (gDebug > 0)
2134  Error("TRecGuiEvent::ReplayEvent",
2135  "kConfigureNotify: Unknown value: fUser[4] = %ld ",
2136  e->fUser[4]);
2137  }
2138  }
2139  }
2140  }
2141  else {
2142  // w = 0
2143  if (gDebug > 0)
2144  Error("TRecGuiEvent::ReplayEvent",
2145  "kConfigureNotify: Window does not exist anymore ");
2146  }
2147  delete e;
2148  return;
2149 
2150  } // kConfigureNotify
2151 
2152  if (showMouseCursor && e->fType == kButtonPress) {
2153  gVirtualX->TranslateCoordinates(e->fWindow, gVirtualX->GetDefaultRootWindow(),
2154  e->fX, e->fY, px, py, wtarget);
2155  dx = px - gCursorWin->GetX();
2156  dy = py - gCursorWin->GetY();
2157  if (TMath::Abs(dx) > 5) gDecorWidth += dx;
2158  if (TMath::Abs(dy) > 5) gDecorHeight += dy;
2159  }
2160  // Displays fake mouse cursor for MotionNotify event
2161  if (showMouseCursor && e->fType == kMotionNotify) {
2162  if (gCursorWin && e->fWindow == gVirtualX->GetDefaultRootWindow()) {
2163  if (!gCursorWin->IsMapped()) {
2164  gCursorWin->MapRaised();
2165  }
2166  if (gVirtualX->GetDrawMode() == TVirtualX::kCopy) {
2167 //#ifdef R__MACOSX
2168  // this may have side effects (e.g. stealing focus)
2169  gCursorWin->RaiseWindow();
2170 //#endif
2171  gCursorWin->Move(e->fXRoot + gDecorWidth, e->fYRoot + gDecorHeight);
2172  }
2173  }
2174  }
2175 
2176  // Lets all the other events to be handled the same way as when recording
2177  // first, special case for the gui builder, having a timer handling
2178  // some of the events
2179  if (e->fType == kOtherEvent && e->fFormat >= kGKeyPress &&
2180  e->fFormat < kOtherEvent) {
2181  e->fType = (EGEventType)e->fFormat;
2182  if (gDragManager)
2184  delete e;
2185  return;
2186  }
2187  else { // then the normal cases
2188  if (!fMasked)
2189  gClient->HandleEvent(e);
2190  else
2191  gClient->HandleMaskEvent(e, fMasked);
2192  }
2193  delete e;
2194 }
2195 
2196 ////////////////////////////////////////////////////////////////////////////////
2197 /// Converts TRecGuiEvent type to Event_t type
2198 
2200 {
2201  Event_t *e = new Event_t();
2202 
2203  // Copies all data items
2204 
2205  e->fType = ge->fType;
2206  e->fWindow = ge->fWindow;
2207  e->fTime = ge->fTime;
2208 
2209  e->fX = ge->fX;
2210  e->fY = ge->fY;
2211  e->fXRoot = ge->fXRoot;
2212  e->fYRoot = ge->fYRoot;
2213 
2214  e->fCode = ge->fCode;
2215  e->fState = ge->fState;
2216 
2217  e->fWidth = ge->fWidth;
2218  e->fHeight = ge->fHeight;
2219 
2220  e->fCount = ge->fCount;
2221  e->fSendEvent = ge->fSendEvent;
2222 
2223  e->fHandle = ge->fHandle;
2224  e->fFormat = ge->fFormat;
2225 
2226  if (e->fHandle == TRecGuiEvent::kROOT_MESSAGE)
2227  e->fHandle = gROOT_MESSAGE;
2228 
2229  for(Int_t i=0; i<5; ++i)
2230  e->fUser[i] = ge->fUser[i];
2231 
2232  if (e->fUser[0] == TRecGuiEvent::kWM_DELETE_WINDOW)
2233  e->fUser[0] = gWM_DELETE_WINDOW;
2234 
2235  if (ge->fType == kGKeyPress || ge->fType == kKeyRelease) {
2236  e->fCode = gVirtualX->KeysymToKeycode(ge->fCode);
2237 #ifdef R__WIN32
2238  e->fUser[1] = 1;
2239  e->fUser[2] = e->fCode;
2240 #endif
2241  }
2242 
2243  return e;
2244 }
2245 
kPaveLabel
@ kPaveLabel
Definition: Buttons.h:31
TGRecorder
Definition: TRecorder.h:785
Event_t::fType
EGEventType fType
Definition: GuiTypes.h:174
TRecCmdEvent::SetText
void SetText(const char *text)
Definition: TRecorder.h:204
n
const Int_t n
Definition: legend1.C:16
Event_t::fState
UInt_t fState
Definition: GuiTypes.h:180
TRecExtraEvent
Definition: TRecorder.h:236
TGButton::SetEnabled
virtual void SetEnabled(Bool_t e=kTRUE)
Set enabled or disabled state of button.
Definition: TGButton.cxx:412
SetWindowAttributes_t::fSaveUnder
Bool_t fSaveUnder
Definition: GuiTypes.h:103
TRecorderRecording::fFilterEventPave
Bool_t fFilterEventPave
Definition: TRecorder.h:680
TGPictureButton::SetPicture
virtual void SetPicture(const TGPicture *new_pic)
Change a picture in a picture button.
Definition: TGButton.cxx:993
TGFrame::GetHeight
UInt_t GetHeight() const
Definition: TGFrame.h:250
TRecorderRecording::RecordGuiBldEvent
void RecordGuiBldEvent(Event_t *e)
Special case for the gui builder, having a timer handling some of the events.
Definition: TRecorder.cxx:1481
TRecorderReplaying::fNextEvent
TRecEvent * fNextEvent
Definition: TRecorder.h:594
TQObject::Disconnect
Bool_t Disconnect(const char *signal=0, void *receiver=0, const char *slot=0)
Disconnects signal of this object from slot of receiver.
Definition: TQObject.cxx:1022
Event_t::fY
Int_t fY
Definition: GuiTypes.h:177
Event_t::fX
Int_t fX
Definition: GuiTypes.h:177
TBrowser
Definition: TBrowser.h:37
TGWindow
Definition: TGWindow.h:31
kLHintsCenterX
@ kLHintsCenterX
Definition: TGLayout.h:38
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
Pixmap_t
Handle_t Pixmap_t
Definition: GuiTypes.h:29
TRecorderRecording::fBeginPave
Long64_t fBeginPave
Definition: TRecorder.h:658
e
#define e(i)
Definition: RSha256.hxx:121
TRecorderReplaying::~TRecorderReplaying
virtual ~TRecorderReplaying()
Closes all signal-slot connections Frees all memory allocated in contructor.
Definition: TRecorder.cxx:405
TGMainFrame
Definition: TGFrame.h:444
TRecorderState::ReplayStop
virtual void ReplayStop(TRecorder *)
Definition: TRecorder.h:529
TRecGuiEvent::fX
Int_t fX
Definition: TRecorder.h:290
TGPicture
Definition: TGPicture.h:36
TRecGuiEvent::kROOT_MESSAGE
@ kROOT_MESSAGE
Definition: TRecorder.h:319
f
#define f(i)
Definition: RSha256.hxx:122
TRecorder::TRecorderInactive
friend class TRecorderInactive
Definition: TRecorder.h:432
TGFrame::SetBackgroundColor
virtual void SetBackgroundColor(Pixel_t back)
Set background color (override from TGWindow base class).
Definition: TGFrame.cxx:297
kGuiEventTree
const char * kGuiEventTree
Definition: TRecorder.cxx:168
TRecorderReplaying::TRecorderPaused
friend class TRecorderPaused
Definition: TRecorder.h:617
TGRecorder::fElapsed
time_t fElapsed
Definition: TRecorder.h:798
TRecorderReplaying::fEventReplayed
Bool_t fEventReplayed
Definition: TRecorder.h:605
TRecorderReplaying::Pause
virtual void Pause(TRecorder *r)
Pauses replaying.
Definition: TRecorder.cxx:951
TCollection::Write
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write all objects in this collection.
Definition: TCollection.cxx:672
TRecorderRecording::fCmdEventPending
Bool_t fCmdEventPending
Definition: TRecorder.h:670
TRecEvent::SetTime
virtual void SetTime(TTime t)
Definition: TRecorder.h:176
TRecorderPaused
Definition: TRecorder.h:757
TSystem::BaseName
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:933
gVirtualX
#define gVirtualX
Definition: TVirtualX.h:338
TRecorderRecording::fCmdEvent
TRecCmdEvent * fCmdEvent
Definition: TRecorder.h:667
TTimer::GetAbsTime
TTime GetAbsTime() const
Definition: TTimer.h:84
TRecGuiEvent::ReplayEvent
virtual void ReplayEvent(Bool_t showMouseCursor=kTRUE)
Replays stored GUI event.
Definition: TRecorder.cxx:2089
TMutex::Lock
Int_t Lock()
Lock the mutex.
Definition: TMutex.cxx:46
TRecorderRecording::~TRecorderRecording
virtual ~TRecorderRecording()
Freeing of allocated memory.
Definition: TRecorder.cxx:1255
TString::Data
const char * Data() const
Definition: TString.h:369
kLHintsTop
@ kLHintsTop
Definition: TGLayout.h:40
Pixel_t
ULong_t Pixel_t
Definition: GuiTypes.h:39
TRecorderReplaying::CanOverlap
Bool_t CanOverlap()
ButtonPress and ButtonRelease must be sometimes replayed more times Example: pressing of a button ope...
Definition: TRecorder.cxx:830
TRecGuiEvent::kWM_DELETE_WINDOW
@ kWM_DELETE_WINDOW
Definition: TRecorder.h:318
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:54
TGPicture.h
TVirtualDragManager::HandleTimerEvent
virtual Bool_t HandleTimerEvent(Event_t *, TTimer *)
Definition: TVirtualDragManager.h:68
TGCheckButton::IsOn
virtual Bool_t IsOn() const
Definition: TGButton.h:311
Event_t::fHeight
UInt_t fHeight
Definition: GuiTypes.h:181
TBox::GetX1
Double_t GetX1() const
Definition: TBox.h:50
Buttons.h
TRecorder::ERecorderState
ERecorderState
Definition: TRecorder.h:449
TRecorderRecording::FilterEventPave
void FilterEventPave()
Change the state of the flag to kTRUE when you are recording a pavelabel.
Definition: TRecorder.cxx:1639
TRecorderReplaying::fCmdEvent
TRecCmdEvent * fCmdEvent
Definition: TRecorder.h:580
r
ROOT::R::TRInterface & r
Definition: Object.C:4
TRecorderPaused::ReplayStop
virtual void ReplayStop(TRecorder *r)
Replaying is cancelled.
Definition: TRecorder.cxx:1189
TTimer::Start
virtual void Start(Long_t milliSec=-1, Bool_t singleShot=kFALSE)
Starts the timer with a milliSec timeout.
Definition: TTimer.cxx:211
kLHintsLeft
@ kLHintsLeft
Definition: TGLayout.h:37
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TGRecorder::StartStop
void StartStop()
Handles push of the fStartStop button according to the current recorder state.
Definition: TRecorder.cxx:1964
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
gCursorWin
static TGCursorWindow * gCursorWin
Definition: TRecorder.cxx:193
TGPicture::GetMask
Pixmap_t GetMask() const
Definition: TGPicture.h:66
TRecorderReplaying::TRecorderReplaying
TRecorderReplaying(const char *filename)
Allocates all necessary data structures used for replaying What is allocated here is deleted in destr...
Definition: TRecorder.cxx:371
TGLabel
Definition: TGLabel.h:32
TGCompositeFrame::Cleanup
virtual void Cleanup()
Cleanup and delete all objects contained in this composite frame.
Definition: TGFrame.cxx:952
kConfigureNotify
@ kConfigureNotify
Definition: GuiTypes.h:61
TRecorderReplaying::fWin
ULong64_t fWin
Definition: TRecorder.h:578
TTree
Definition: TTree.h:79
TTree::SetBranchAddress
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition: TTree.cxx:8205
TRecorderRecording::RecordCmdEvent
void RecordCmdEvent(const char *line)
Records commandline event (text and time) ans saves the previous commandline event This 1 event delay...
Definition: TRecorder.cxx:1419
TGWindow::kEditDisable
@ kEditDisable
Definition: TGWindow.h:58
WindowAttributes_t
Definition: GuiTypes.h:113
TGRecorder::fgWidgetsCount
static const Int_t fgWidgetsCount
Definition: TRecorder.h:800
TRecGuiEvent::fTime
Time_t fTime
Definition: TRecorder.h:289
kExtraEventTree
const char * kExtraEventTree
Definition: TRecorder.cxx:170
TFile::Open
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition: TFile.cxx:3946
TRecorderReplaying::fExtraEvent
TRecExtraEvent * fExtraEvent
Definition: TRecorder.h:581
TGRecorder::SetDefault
void SetDefault()
Sets GUI to the default inactive state.
Definition: TRecorder.cxx:1884
TRecorderState::Replay
virtual Bool_t Replay(TRecorder *, const char *, Bool_t, TRecorder::EReplayModes)
Definition: TRecorder.h:526
TRecorderReplaying::fWaitingForWindow
Bool_t fWaitingForWindow
Definition: TRecorder.h:599
gDragManager
R__EXTERN TVirtualDragManager * gDragManager
Definition: TVirtualDragManager.h:82
Int_t
int Int_t
Definition: RtypesCore.h:45
TRecorderReplaying::fCmdTreeCounter
Int_t fCmdTreeCounter
Definition: TRecorder.h:585
kTempFrame
@ kTempFrame
Definition: GuiTypes.h:393
TGRecorder::fFilteredIds
Window_t fFilteredIds[fgWidgetsCount]
Definition: TRecorder.h:801
TRecEvent::GetTime
virtual TTime GetTime() const
Definition: TRecorder.h:171
Event_t::fFormat
Int_t fFormat
Definition: GuiTypes.h:185
TRecorderReplaying::fGuiEvent
TRecGuiEvent * fGuiEvent
Definition: TRecorder.h:579
TRecorderRecording::StartRecording
Bool_t StartRecording()
Connects appropriate signals and slots in order to gain all registered windows and processed events i...
Definition: TRecorder.cxx:1272
TRecorder::ReplayStop
void ReplayStop()
Cancells replaying.
Definition: TRecorder.cxx:312
TRecorderState::ListCmd
virtual void ListCmd(const char *)
Definition: TRecorder.h:531
kClientMessage
@ kClientMessage
Definition: GuiTypes.h:62
TRecorderPaused::Resume
virtual void Resume(TRecorder *r)
Continues replaying.
Definition: TRecorder.cxx:1177
TRecorderState::PrevCanvases
virtual void PrevCanvases(const char *, Option_t *)
Definition: TRecorder.h:534
TGCompositeFrame::SetEditDisabled
virtual void SetEditDisabled(UInt_t on=1)
Set edit disable flag for this frame and subframes.
Definition: TGFrame.cxx:1007
TRecorderInactive::ListGui
virtual void ListGui(const char *filename)
Prints out GUI events recorded in given file.
Definition: TRecorder.cxx:1073
TRecorder::PrevCanvases
void PrevCanvases(const char *filename, Option_t *option)
Save previous canvases in a .root file.
Definition: TRecorder.cxx:357
TTimer::TurnOff
virtual void TurnOff()
Remove timer from system timer list.
Definition: TTimer.cxx:229
gDecorWidth
static Int_t gDecorWidth
Definition: TRecorder.cxx:194
TLatex
Definition: TLatex.h:18
TGMainFrame::SetWindowName
void SetWindowName(const char *name=0)
Set window name. This is typically done via the window manager.
Definition: TGFrame.cxx:1749
TRecGuiEvent::CreateEvent
static Event_t * CreateEvent(TRecGuiEvent *ge)
Converts TRecGuiEvent type to Event_t type.
Definition: TRecorder.cxx:2199
TRecorder::kReplaying
@ kReplaying
Definition: TRecorder.h:453
TRecorderReplaying::Initialize
Bool_t Initialize(TRecorder *r, Bool_t showMouseCursor, TRecorder::EReplayModes mode)
Initialization of data structures for replaying.
Definition: TRecorder.cxx:437
TRecorderState::Resume
virtual void Resume(TRecorder *)
Definition: TRecorder.h:528
TVirtualX.h
kSelectionClear
@ kSelectionClear
Definition: GuiTypes.h:62
TMutex::UnLock
Int_t UnLock()
Unlock the mutex.
Definition: TMutex.cxx:68
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TGHorizontalFrame
Definition: TGFrame.h:423
TTree::Fill
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4527
TTimer.h
TRecorderRecording::fCmdTree
TTree * fCmdTree
Definition: TRecorder.h:662
TRecGuiEvent::fFormat
Int_t fFormat
Definition: TRecorder.h:301
TRecorder::kPaused
@ kPaused
Definition: TRecorder.h:452
TRecWinPair::fKey
Window_t fKey
Definition: TRecorder.h:352
TRecorderReplaying::fTimer
TTimer * fTimer
Definition: TRecorder.h:571
TTree.h
TRecorderRecording::fGuiTree
TTree * fGuiTree
Definition: TRecorder.h:661
TRecorderRecording::fFilteredIds
Window_t * fFilteredIds
Definition: TRecorder.h:678
TString
Definition: TString.h:136
TRecorderRecording::fWin
ULong64_t fWin
Definition: TRecorder.h:665
TGFrame
Definition: TGFrame.h:105
TRecorder::Start
void Start(const char *filename, Option_t *option="RECREATE", Window_t *w=0, Int_t winCount=0)
Starts recording events.
Definition: TRecorder.cxx:270
SetWindowAttributes_t::fMask
Mask_t fMask
Definition: GuiTypes.h:109
TRecGuiEvent::fCount
Int_t fCount
Definition: TRecorder.h:298
TGObject::GetId
Handle_t GetId() const
Definition: TGObject.h:47
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
TRecorderRecording::fFilteredIdsCount
Int_t fFilteredIdsCount
Definition: TRecorder.h:677
TRecorderReplaying::RegisterWindow
void RegisterWindow(Window_t w)
Creates mapping for the newly registered window w and adds this mapping to fWindowList.
Definition: TRecorder.cxx:542
TTree::GetEntry
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition: TTree.cxx:5537
TGWindow.h
TFile::Write
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsiz=0) override
Write memory objects to this file.
Definition: TFile.cxx:2300
TFile.h
TGLabel::SetText
virtual void SetText(TGString *newText)
Set new text in label.
Definition: TGLabel.cxx:179
TRecCmdEvent::GetText
const char * GetText() const
Definition: TRecorder.h:209
TGFrame::MapWindow
virtual void MapWindow()
map window
Definition: TGFrame.h:229
bool
TPaveLabel.h
TListIter
Definition: TList.h:197
TGFrame::GetWidth
UInt_t GetWidth() const
Definition: TGFrame.h:249
TRecorderInactive::fCollect
TSeqCollection * fCollect
Definition: TRecorder.h:723
TRecorderRecording::Stop
virtual void Stop(TRecorder *r, Bool_t guiCommand)
Disconnects all slots and stopps recording.
Definition: TRecorder.cxx:1366
TGCheckButton::SetDisabledAndSelected
virtual void SetDisabledAndSelected(Bool_t)
Set the state of a check button to disabled and either on or off.
Definition: TGButton.cxx:1263
kWASaveUnder
const Mask_t kWASaveUnder
Definition: GuiTypes.h:149
TGFileDialog.h
TRecorderReplaying::Continue
virtual void Continue()
Continues previously paused replaying.
Definition: TRecorder.cxx:970
TRecorderReplaying::fExtraTreeCounter
Int_t fExtraTreeCounter
Definition: TRecorder.h:586
TROOT.h
TRecGuiEvent::fWidth
UInt_t fWidth
Definition: TRecorder.h:296
TRecorderReplaying::FilterEvent
Bool_t FilterEvent(TRecGuiEvent *e)
Definition: TRecorder.cxx:670
TGRecorder::fRecorder
TRecorder * fRecorder
Definition: TRecorder.h:788
TRecorderRecording::fTimer
TTimer * fTimer
Definition: TRecorder.h:656
gClient
#define gClient
Definition: TGClient.h:166
TCanvas::Draw
virtual void Draw(Option_t *option="")
Draw a canvas.
Definition: TCanvas.cxx:841
TRecorderPaused::fReplayingState
TRecorderReplaying * fReplayingState
Definition: TRecorder.h:762
TRecorder::kInactive
@ kInactive
Definition: TRecorder.h:450
kText
@ kText
Definition: Buttons.h:30
TListIter::Next
TObject * Next()
Return next object in the list. Returns 0 when no more objects in list.
Definition: TList.cxx:1112
TRecGuiEvent::fType
EGEventType fType
Definition: TRecorder.h:287
TGCheckButton
Definition: TGButton.h:264
kKey_S
@ kKey_S
Definition: KeySymbols.h:150
TString::Form
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
TRecGuiEvent::kCNResize
@ kCNResize
Definition: TRecorder.h:312
TRecorderInactive::DumpRootEvent
static void DumpRootEvent(TRecGuiEvent *e, Int_t n)
Prints out attributes of one GUI event TRecGuiEvent *e Int_n n is number of event if called in cycle.
Definition: TRecorder.cxx:1115
TRecGuiEvent::fWindow
Window_t fWindow
Definition: TRecorder.h:288
TRecorderReplaying::ReplayRealtime
void ReplayRealtime()
Replays the next event.
Definition: TRecorder.cxx:874
TTimer
Definition: TTimer.h:51
TGFileInfo::fOverwrite
Bool_t fOverwrite
Definition: TGFileDialog.h:65
TRecGuiEvent::kCNMove
@ kCNMove
Definition: TRecorder.h:311
TDirectoryFile::Get
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
Definition: TDirectoryFile.cxx:909
TRecGuiEvent::fUser
Long_t fUser[5]
Definition: TRecorder.h:302
TRecorderReplaying::fPreviousEventTime
TTime fPreviousEventTime
Definition: TRecorder.h:596
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
TRecorder::Browse
void Browse(TBrowser *)
Browse the recorder from a ROOT file.
Definition: TRecorder.cxx:262
TText::GetX
Double_t GetX() const
Definition: TText.h:53
TRecorderRecording::RecordPave
void RecordPave(const TObject *obj)
Records TPaveLabel object created in TCreatePrimitives::Pave()
Definition: TRecorder.cxx:1553
kSelectionRequest
@ kSelectionRequest
Definition: GuiTypes.h:62
TRecorder::ChangeState
void ChangeState(TRecorderState *newstate, Bool_t deletePreviousState=kTRUE)
Changes state from the current to the passed one (newstate) Deletes the old state if delPreviousState...
Definition: TRecorder.cxx:337
TGRecorder::fReplay
TGPictureButton * fReplay
Definition: TRecorder.h:791
TRecorderInactive::Start
virtual void Start(TRecorder *r, const char *filename, Option_t *option, Window_t *w=0, Int_t winCount=0)
Switches from INACTIVE state to RECORDING and starts recording.
Definition: TRecorder.cxx:984
Event_t::fHandle
Handle_t fHandle
Definition: GuiTypes.h:184
kFixedHeight
@ kFixedHeight
Definition: GuiTypes.h:389
TRecorderInactive
Definition: TRecorder.h:719
TGWindow::kEditDisableGrab
@ kEditDisableGrab
Definition: TGWindow.h:60
TGRecorder::fStartStop
TGPictureButton * fStartStop
Definition: TRecorder.h:790
kBranchName
const char * kBranchName
Definition: TRecorder.cxx:171
TSystem.h
TRecorderRecording::TRecorderInactive
friend class TRecorderInactive
Definition: TRecorder.h:683
TText::GetY
Double_t GetY() const
Definition: TText.h:61
kOtherEvent
@ kOtherEvent
Definition: GuiTypes.h:63
TRecorderState::ListGui
virtual void ListGui(const char *)
Definition: TRecorder.h:532
kKeyRelease
@ kKeyRelease
Definition: GuiTypes.h:59
TRecorderRecording::fMouseTimer
TTimer * fMouseTimer
Definition: TRecorder.h:657
TRecorderReplaying::fMutex
TMutex * fMutex
Definition: TRecorder.h:590
TRecorderRecording::SetTypeOfConfigureNotify
void SetTypeOfConfigureNotify(Event_t *e)
Sets type of kConfigureNotify event to one of EConfigureNotify.
Definition: TRecorder.cxx:1728
TRecorder::Stop
void Stop(Bool_t guiCommand=kFALSE)
Stopps recording events.
Definition: TRecorder.cxx:279
h
#define h(i)
Definition: RSha256.hxx:124
kGKeyPress
@ kGKeyPress
Definition: GuiTypes.h:59
TBox::GetY1
Double_t GetY1() const
Definition: TBox.h:52
TGCompositeFrame::MapSubwindows
virtual void MapSubwindows()
Map all sub windows that are part of the composite frame.
Definition: TGFrame.cxx:1149
SetWindowAttributes_t::fOverrideRedirect
Bool_t fOverrideRedirect
Definition: GuiTypes.h:106
TGVerticalFrame
Definition: TGFrame.h:412
TTree::Branch
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
Definition: TTree.h:349
TRecorderState::Pause
virtual void Pause(TRecorder *)
Definition: TRecorder.h:527
TRecorderRecording::RecordGuiEvent
void RecordGuiEvent(Event_t *e, Window_t wid)
Records GUI Event_t *e different from kConfigureNotify (they are recorded in TRecorderRecording::Reco...
Definition: TRecorder.cxx:1447
TMutex.h
TGFrame::Resize
virtual void Resize(UInt_t w=0, UInt_t h=0)
Resize the frame.
Definition: TGFrame.cxx:590
gWM_DELETE_WINDOW
R__EXTERN Atom_t gWM_DELETE_WINDOW
Definition: TVirtualX.h:38
Atom_t
Handle_t Atom_t
Definition: GuiTypes.h:36
Event_t::fSendEvent
Bool_t fSendEvent
Definition: GuiTypes.h:183
Event_t::fCode
UInt_t fCode
Definition: GuiTypes.h:179
TRecorderReplaying::fWindowList
TList * fWindowList
Definition: TRecorder.h:592
TFile::IsOpen
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1382
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
Event_t::fWidth
UInt_t fWidth
Definition: GuiTypes.h:181
kButtonPress
@ kButtonPress
Definition: GuiTypes.h:59
gDebug
R__EXTERN Int_t gDebug
Definition: RtypesCore.h:119
Long_t
long Long_t
Definition: RtypesCore.h:54
TRecorder::ListGui
void ListGui(const char *filename)
Prints out recorded GUI events.
Definition: TRecorder.cxx:328
TTime
Definition: TTime.h:27
TGFileInfo
Definition: TGFileDialog.h:54
kButtonRelease
@ kButtonRelease
Definition: GuiTypes.h:59
TRecorderReplaying::fCmdTree
TTree * fCmdTree
Definition: TRecorder.h:575
TRecorder::~TRecorder
virtual ~TRecorder()
Destructor.
Definition: TRecorder.cxx:253
TGLayoutHints
Definition: TGLayout.h:57
TRecorderRecording::fRegWinCounter
Int_t fRegWinCounter
Definition: TRecorder.h:674
TBox::GetY2
Double_t GetY2() const
Definition: TBox.h:53
TRecEvent::GetType
virtual ERecEventType GetType() const =0
TRecorderRecording::CopyEvent
void CopyEvent(Event_t *e, Window_t wid)
Copies all items of given event to fGuiEvent.
Definition: TRecorder.cxx:1666
gApplication
R__EXTERN TApplication * gApplication
Definition: TApplication.h:166
Window_t
Handle_t Window_t
Definition: GuiTypes.h:28
TRecorderReplaying::fRecorder
TRecorder * fRecorder
Definition: TRecorder.h:562
kMotionNotify
@ kMotionNotify
Definition: GuiTypes.h:60
TCanvas::GetWindowWidth
UInt_t GetWindowWidth() const
Definition: TCanvas.h:159
TRecorder::Resume
void Resume()
Resumes replaying.
Definition: TRecorder.cxx:304
TRecorder::EReplayModes
EReplayModes
Definition: TRecorder.h:444
TRecorderReplaying::fGuiTree
TTree * fGuiTree
Definition: TRecorder.h:574
TCanvas::GetWindowHeight
UInt_t GetWindowHeight() const
Definition: TCanvas.h:160
TRecGuiEvent::fHandle
Handle_t fHandle
Definition: TRecorder.h:300
kLHintsExpandY
@ kLHintsExpandY
Definition: TGLayout.h:44
TRecorder::Replay
void Replay()
Definition: TRecorder.h:475
TRecorderState::Start
virtual void Start(TRecorder *, const char *, Option_t *, Window_t *, Int_t)
Definition: TRecorder.h:524
kCmdEventTree
const char * kCmdEventTree
Definition: TRecorder.cxx:167
TBox::GetX2
Double_t GetX2() const
Definition: TBox.h:51
KeySymbols.h
TRecorder::fRecorderState
TRecorderState * fRecorderState
Definition: TRecorder.h:425
TRecorderReplaying::fShowMouseCursor
Bool_t fShowMouseCursor
Definition: TRecorder.h:611
WindowAttributes_t::fY
Int_t fY
Definition: GuiTypes.h:114
Event_t::fXRoot
Int_t fXRoot
Definition: GuiTypes.h:178
kWindowsTree
const char * kWindowsTree
Definition: TRecorder.cxx:169
TRecorderRecording::fExtraEvent
TRecExtraEvent * fExtraEvent
Definition: TRecorder.h:668
kFDSave
@ kFDSave
Definition: TGFileDialog.h:45
TGFrame::GetX
Int_t GetX() const
Definition: TGFrame.h:256
line
TLine * line
Definition: entrylistblock_figure1.C:235
TRecorderRecording::RecordText
void RecordText(const TObject *obj)
Records TLatex object created in TCreatePrimitives::Text()
Definition: TRecorder.cxx:1597
TRecGuiEvent::kCNMoveResize
@ kCNMoveResize
Definition: TRecorder.h:313
gROOT_MESSAGE
R__EXTERN Atom_t gROOT_MESSAGE
Definition: TVirtualX.h:40
Event_t::fWindow
Window_t fWindow
Definition: GuiTypes.h:175
TRecGuiEvent::fY
Int_t fY
Definition: TRecorder.h:291
Event_t::fYRoot
Int_t fYRoot
Definition: GuiTypes.h:178
TFile
Definition: TFile.h:54
TGButton::SetStyle
virtual void SetStyle(UInt_t newstyle)
Set the button style (modern or classic).
Definition: TGButton.cxx:224
TRecorderRecording::fExtraTree
TTree * fExtraTree
Definition: TRecorder.h:663
TRecorder::GetState
virtual TRecorder::ERecorderState GetState() const
Get current state of recorder.
Definition: TRecorder.cxx:348
unsigned int
TGLabel::SetTextFont
virtual void SetTextFont(TGFont *font, Bool_t global=kFALSE)
Changes text font specified by pointer to TGFont object.
Definition: TGLabel.cxx:323
TRecorder::TRecorder
TRecorder()
Creates initial INACTIVE state for the recorder.
Definition: TRecorder.cxx:228
TRecorderPaused::TRecorderPaused
TRecorderPaused(TRecorderReplaying *state)
Rememeber the recorder state that is paused.
Definition: TRecorder.cxx:1169
TRecorderInactive::Replay
virtual Bool_t Replay(TRecorder *r, const char *filename, Bool_t showMouseCursor, TRecorder::EReplayModes mode)
Switches from INACTIVE state of recorder to REPLAYING Return kTRUE if replaying has started or kFALSE...
Definition: TRecorder.cxx:1007
TRecorderReplaying::fWinTree
TTree * fWinTree
Definition: TRecorder.h:573
TObject::IsZombie
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
TRecorderRecording
Definition: TRecorder.h:644
TRecorderRecording::RecordMousePosition
void RecordMousePosition()
Try to record all mouse moves...
Definition: TRecorder.cxx:1499
TKey
Definition: TKey.h:28
kKeyControlMask
const Mask_t kKeyControlMask
Definition: GuiTypes.h:196
TPaveLabel
Definition: TPaveLabel.h:20
TKey::ReadObj
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition: TKey.cxx:750
TGLabel.h
TGRecorder::TGRecorder
TGRecorder(const TGWindow *p=0, UInt_t w=230, UInt_t h=150)
The GUI for the recorder.
Definition: TRecorder.cxx:1780
ULong64_t
unsigned long long ULong64_t
Definition: RtypesCore.h:74
TGWindow::GetParent
const TGWindow * GetParent() const
Definition: TGWindow.h:84
TGRecorder::fCursorCheckBox
TGCheckButton * fCursorCheckBox
Definition: TRecorder.h:795
TGFileInfo::fFileTypes
const char ** fFileTypes
Definition: TGFileDialog.h:63
TRecorderReplaying::fFile
TFile * fFile
Definition: TRecorder.h:565
TTimer::Stop
virtual void Stop()
Definition: TTimer.h:99
TQObject::Connect
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot.
Definition: TQObject.cxx:864
TRecorderRecording::RegisterWindow
void RegisterWindow(Window_t w)
This method is called when RegisteredWindow(Window_t) is emitted from TGClient.
Definition: TRecorder.cxx:1406
TRecorderReplaying::fWinTreeEntries
Int_t fWinTreeEntries
Definition: TRecorder.h:588
TGPictureButton
Definition: TGButton.h:228
TCanvas
Definition: TCanvas.h:23
TRecorderRecording::RecordGuiCNEvent
void RecordGuiCNEvent(Event_t *e)
Records GUI Event_t *e of type kConfigureNotify.
Definition: TRecorder.cxx:1530
TLatex.h
TRecorderRecording::IsFiltered
Bool_t IsFiltered(Window_t id)
Returns kTRUE if passed id belongs to window IDs of recorder GUI itself.
Definition: TRecorder.cxx:1710
t1
auto * t1
Definition: textangle.C:20
TRecorderInactive::ListCmd
virtual void ListCmd(const char *filename)
Prints out commandline events recorded in given file.
Definition: TRecorder.cxx:1031
TGLabel::SetTextColor
virtual void SetTextColor(Pixel_t color, Bool_t global=kFALSE)
Changes text color.
Definition: TGLabel.cxx:361
Info
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition: TError.cxx:220
TRecGuiEvent::fMasked
Window_t fMasked
Definition: TRecorder.h:306
TGPicture::GetPicture
Pixmap_t GetPicture() const
Definition: TGPicture.h:65
TGWindow::Resize
virtual void Resize(UInt_t w, UInt_t h)
Resize the window.
Definition: TGWindow.cxx:260
file
Definition: file.py:1
TRecGuiEvent::kCNFilter
@ kCNFilter
Definition: TRecorder.h:314
TCanvas::SetWindowSize
void SetWindowSize(UInt_t ww, UInt_t wh)
Set canvas window size.
Definition: TCanvas.cxx:2197
Event_t::fTime
Time_t fTime
Definition: GuiTypes.h:176
TObject::Write
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:795
TList::Add
virtual void Add(TObject *obj)
Definition: TList.h:87
TObject
Definition: TObject.h:37
TGWindow::Move
virtual void Move(Int_t x, Int_t y)
Move the window.
Definition: TGWindow.cxx:252
kSelectionNotify
@ kSelectionNotify
Definition: GuiTypes.h:62
TFile::Close
void Close(Option_t *option="") override
Close a file.
Definition: TFile.cxx:876
TGButton.h
TRecWinPair::fValue
Window_t fValue
Definition: TRecorder.h:353
TRecorderRecording::fFile
TFile * fFile
Definition: TRecorder.h:655
TRecorderState::GetState
virtual TRecorder::ERecorderState GetState() const =0
TGRecorder::Update
void Update()
Called when fTimer timeouts (every 0.025 second) Updates GUI of recorder.
Definition: TRecorder.cxx:1902
TRecGuiEvent::fState
UInt_t fState
Definition: TRecorder.h:295
TRecGuiEvent::fHeight
UInt_t fHeight
Definition: TRecorder.h:297
Event_t
Definition: GuiTypes.h:173
TRecEvent::ReplayEvent
virtual void ReplayEvent(Bool_t showMouseCursor=kTRUE)=0
TRecorderReplaying
Definition: TRecorder.h:552
TRecorderRecording::fGuiEvent
TRecGuiEvent * fGuiEvent
Definition: TRecorder.h:666
TRecorderReplaying::PrepareNextEvent
Bool_t PrepareNextEvent()
Finds the next event in log file to replay and sets it to fNextEvent.
Definition: TRecorder.cxx:725
kDeepCleanup
@ kDeepCleanup
Definition: TGFrame.h:51
TRecorderReplaying::RemapWindowReferences
Bool_t RemapWindowReferences()
All references to the old windows (IDs) in fNextEvent are replaced by new ones according to the mappi...
Definition: TRecorder.cxx:610
TRecorderRecording::fRecorder
TRecorder * fRecorder
Definition: TRecorder.h:652
TRecorder.h
gDecorHeight
static Int_t gDecorHeight
Definition: TRecorder.cxx:195
TGFrame::GetY
Int_t GetY() const
Definition: TGFrame.h:257
TRecorder::kRecording
@ kRecording
Definition: TRecorder.h:451
TRecorderReplaying::TRecorderInactive
friend class TRecorderInactive
Definition: TRecorder.h:616
gPad
#define gPad
Definition: TVirtualPad.h:287
TRecorderInactive::PrevCanvases
void PrevCanvases(const char *filename, Option_t *option)
Save previous canvases in a .root file.
Definition: TRecorder.cxx:1150
TRecExtraEvent::SetText
void SetText(TString text)
Definition: TRecorder.h:246
TIter
Definition: TCollection.h:233
TGButton::SetOn
virtual void SetOn(Bool_t on=kTRUE, Bool_t emit=kFALSE)
Definition: TGButton.h:120
TRecWinPair
Definition: TRecorder.h:347
TRecorder
Definition: TRecorder.h:422
TRecorderState
Definition: TRecorder.h:516
kLHintsExpandX
@ kLHintsExpandX
Definition: TGLayout.h:43
WindowAttributes_t::fX
Int_t fX
Definition: GuiTypes.h:114
TRecGuiEvent::fYRoot
Int_t fYRoot
Definition: TRecorder.h:293
TRecorderReplaying::fCanv
TCanvas * fCanv
Definition: TRecorder.h:568
TRecEvent::kGuiEvent
@ kGuiEvent
Definition: TRecorder.h:161
TRecGuiEvent::fSendEvent
Bool_t fSendEvent
Definition: TRecorder.h:299
TRecGuiEvent
Definition: TRecorder.h:279
TGRecorder::fTimer
TTimer * fTimer
Definition: TRecorder.h:797
TGCompositeFrame::SetCleanup
virtual void SetCleanup(Int_t mode=kLocalCleanup)
Turn on automatic cleanup of child frames in dtor.
Definition: TGFrame.cxx:1057
TRecorderState::Stop
virtual void Stop(TRecorder *, Bool_t)
Definition: TRecorder.h:525
xmlio::cnt
const char * cnt
Definition: TXMLSetup.cxx:81
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
TGRecorder::Replay
void Replay()
Handles push of fReplay button according to the current recorder state.
Definition: TRecorder.cxx:2028
TVirtualDragManager.h
Event_t::fCount
Int_t fCount
Definition: GuiTypes.h:182
TRecorderRecording::RecordExtraEvent
void RecordExtraEvent(TString line, TTime extTime)
Records TLatex or TPaveLabel object created in TCreatePrimitives, ExtTime is needed for the correct r...
Definition: TRecorder.cxx:1656
kWAOverrideRedirect
const Mask_t kWAOverrideRedirect
Definition: GuiTypes.h:148
TKey.h
TTimer::TurnOn
virtual void TurnOn()
Add the timer to the system timer list.
Definition: TTimer.cxx:241
TVirtualX::kCopy
@ kCopy
Definition: TVirtualX.h:49
TRecorderReplaying::fGuiTreeCounter
Int_t fGuiTreeCounter
Definition: TRecorder.h:584
TGRecorder::fStart
time_t fStart
Definition: TRecorder.h:798
TTimer::Reset
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
TRecorderReplaying::fRegWinCounter
Int_t fRegWinCounter
Definition: TRecorder.h:583
TMutex
Definition: TMutex.h:30
TRecorderInactive::DisplayValid
static long DisplayValid(Long_t n)
Definition: TRecorder.h:738
TGCompositeFrame::AddFrame
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
Add frame to the composite frame using the specified layout hints.
Definition: TGFrame.cxx:1102
TTree::GetEntries
virtual Long64_t GetEntries() const
Definition: TTree.h:458
Event_t::fUser
Long_t fUser[5]
Definition: GuiTypes.h:186
TRecorderReplaying::fExtraTree
TTree * fExtraTree
Definition: TRecorder.h:576
TGCompositeFrame::Layout
virtual void Layout()
Layout the elements of the composite frame.
Definition: TGFrame.cxx:1242
TGRecorder::~TGRecorder
virtual ~TGRecorder()
Destructor. Cleanup the GUI.
Definition: TRecorder.cxx:2073
TGRecorder::fTimeDisplay
TGLabel * fTimeDisplay
Definition: TRecorder.h:794
TRecorder::ListCmd
void ListCmd(const char *filename)
Prints out recorded commandline events.
Definition: TRecorder.cxx:320
TRecorderRecording::StartEditing
void StartEditing()
Memorize the starting time of editinga TLatex or a TPaveLabel.
Definition: TRecorder.cxx:1647
TRecGuiEvent::fCode
UInt_t fCode
Definition: TRecorder.h:294
TRecCmdEvent
Definition: TRecorder.h:194
TRecorder::Pause
void Pause()
Pauses replaying.
Definition: TRecorder.cxx:296
TRecorderRecording::fWinTree
TTree * fWinTree
Definition: TRecorder.h:660
TSystem::ProcessEvents
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:417
EGEventType
EGEventType
Definition: GuiTypes.h:58
TPaveLabel::GetLabel
const char * GetLabel() const
Definition: TPaveLabel.h:41
TGWindow::MoveResize
virtual void MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
Move and resize the window.
Definition: TGWindow.cxx:268
kRecEventNames
const char * kRecEventNames[]
Definition: TRecorder.cxx:142
TRecorder::fFilename
TString fFilename
Definition: TRecorder.h:437
TRecorder::Replay
Bool_t Replay(const char *filename, Bool_t showMouseCursor=kTRUE, TRecorder::EReplayModes mode=kRealtime)
Replays events from 'filename'.
Definition: TRecorder.cxx:287
TList
Definition: TList.h:44
TGRecorder::fStatus
TGLabel * fStatus
Definition: TRecorder.h:793
TRecGuiEvent::fXRoot
Int_t fXRoot
Definition: TRecorder.h:292
TRecorderReplaying::fFilterStatusBar
Bool_t fFilterStatusBar
Definition: TRecorder.h:613
TRecorderRecording::TRecorderRecording
TRecorderRecording(TRecorder *r, const char *filename, Option_t *option, Window_t *w, Int_t winCount)
Initializes TRecorderRecording for recording What is allocated here is deleted in destructor.
Definition: TRecorder.cxx:1207
TRecorderReplaying::ReplayStop
virtual void ReplayStop(TRecorder *r)
Cancels replaying.
Definition: TRecorder.cxx:961
gROOT
#define gROOT
Definition: TROOT.h:406
TGFileDialog
Definition: TGFileDialog.h:80
kFDOpen
@ kFDOpen
Definition: TGFileDialog.h:44
kChildFrame
@ kChildFrame
Definition: GuiTypes.h:379
int
SetWindowAttributes_t
Definition: GuiTypes.h:92
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
TGFileInfo::fFilename
char * fFilename
Definition: TGFileDialog.h:61
gFiletypes
static const char * gFiletypes[]
Definition: TGTextEdit.cxx:48