// @(#)root/gui:$Id: TGSpeedo.cxx
// Author: Bertrand Bellenot   26/10/06

/*************************************************************************
 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGSpeedo                                                             //
//                                                                      //
// TGSpeedo is a widget looking like a speedometer, with a needle,      //
// a counter and a small odometer window.                               //
//                                                                      //
//Begin_Html
/*
<img src="gif/speedometer.gif">
*/
//End_Html                                                              //
//                                                                      //
// Three thresholds are configurable, with their glowing color          //
// A peak mark can be enabled, allowing to keep track of the highest    //
// value displayed. The mark can be reset by right-clicking on the      //
// widget.                                                              //
// Two signals are available:                                           //
//    OdoClicked(): when user click on the small odometer window        //
//    LedClicked(): when user click on the small led near the counter   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TSystem.h"
#include "TGClient.h"
#include "TGResourcePool.h"
#include "TImage.h"
#include "TEnv.h"
#include "TMath.h"

#include "TGSpeedo.h"


ClassImp(TGSpeedo)

//______________________________________________________________________________
TGSpeedo::TGSpeedo(const TGWindow *p, int id)
   : TGFrame(p, 1, 1), TGWidget (id), fImage(0), fImage2(0), fBase(0)
{
   // TGSpeedo widget constructor.

   fAngleMin = -133.5;
   fAngleMax =  133.5;
   fAngle    = -133.5;
   fScaleMin = 0.0;
   fScaleMax = 100.0;
   fValue    = 0.0;
   fCounter  = 0;
   fPeakMark = kFALSE;
   fMeanMark = kFALSE;
   fPeakVal  = 0.0;
   fMeanVal  = 0.0;
   fTextFS = fCounterFS = kNone;
   fThreshold[0] = fThreshold[1] = fThreshold[2] = 0.0;
   fThresholdColor[0] = kGreen;
   fThresholdColor[1] = kOrange;
   fThresholdColor[2] = kRed;
   fThresholdActive = kFALSE;
   fPicName  = "speedo.gif";
   fImage = TImage::Open(fPicName);
   if (!fImage || !fImage->IsValid())
      Error("TGSpeedo::Build", "%s not found", fPicName.Data());
   Build();
   AddInput(kButtonPressMask | kButtonReleaseMask);
}

//______________________________________________________________________________
TGSpeedo::TGSpeedo(const TGWindow *p, Float_t smin, Float_t smax,
                   const char *lbl1, const char *lbl2, const char *dsp1,
                   const char *dsp2, int id)
   : TGFrame(p, 1, 1), TGWidget (id), fImage(0), fImage2(0), fBase(0)
{
   // TGSpeedo widget constructor.

   fAngleMin = -133.5;
   fAngleMax =  133.5;
   fAngle    = -133.5;
   fScaleMin = smin;
   fScaleMax = smax;
   fValue    = smin;
   fCounter  = 0;
   fLabel1   = lbl1;
   fLabel2   = lbl2;
   fDisplay1 = dsp1;
   fDisplay2 = dsp2;
   fPeakMark = kFALSE;
   fMeanMark = kFALSE;
   fPeakVal  = 0.0;
   fMeanVal  = 0.0;
   fTextFS = fCounterFS = kNone;
   fThreshold[0] = fThreshold[1] = fThreshold[2] = 0.0;
   fThresholdColor[0] = kGreen;
   fThresholdColor[1] = kOrange;
   fThresholdColor[2] = kRed;
   fThresholdActive = kFALSE;
   fPicName  = "speedo.gif";
   fImage = TImage::Open(fPicName);
   if (!fImage || !fImage->IsValid())
      Error("TGSpeedo::Build", "%s not found", fPicName.Data());
   Build();
   AddInput(kButtonPressMask | kButtonReleaseMask);
}

//______________________________________________________________________________
void TGSpeedo::Build()
{
   // Build TGSpeedo widget.

   TString sc;
   Float_t step, mark[5];
   TString fp = gEnv->GetValue("Root.TTFontPath", "");
   TString ar = fp + "/arialbd.ttf";
   Int_t i, nexe, offset;

   const TGFont *counterFont = fClient->GetFont("-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*");
   if (!counterFont) return;
   fCounterFS = counterFont->GetFontStruct();

   const TGFont *textFont = fClient->GetFont("-*-helvetica-bold-r-*-*-8-*-*-*-*-*-*-*");
   if (!textFont) return;
   fTextFS = textFont->GetFontStruct();

   const TGFont *labelFont = fClient->GetFont("-*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*");
   if (!labelFont) return;
   FontStruct_t labelFS = labelFont->GetFontStruct();

   if (fImage && fImage->IsValid()) {
      fBase = fClient->GetPicturePool()->GetPicture(gSystem->BaseName(fPicName.Data()),
              fImage->GetPixmap(), fImage->GetMask());
      // center of the image
      Float_t xc = (Float_t)(fBase ? (fBase->GetWidth() + 1) / 2 : 96.0);
      Float_t yc = (Float_t)(fBase ? (fBase->GetHeight() + 1) / 2 : 96.0);

      // compute scale ticks steps
      step = (fScaleMax - fScaleMin) / 4.0;
      mark[0] = fScaleMin;
      mark[4] = fScaleMax;
      for (i=1; i<4; i++) {
         mark[i] = mark[i-1] + step;
      }
      // format tick labels
      if (fScaleMax >= 1000.0) {
         nexe = 0;
         while (1) {
            nexe++;
            for (i=0; i<5; i++) {
               mark[i] /= 10.0;
            }
            // coverity[loop_condition]: ignore - false positive
            if (mark[4] < 1000.0) break;
         }
         // draw multiplier
         fImage->DrawText((Int_t)xc - 11, (Int_t)yc + 15, "x10", 12, "#ffffff", ar);
         sc.Form("%d", nexe);
         fImage->DrawText((Int_t)xc + 11, (Int_t)yc + 13, sc.Data(), 10, "#ffffff", ar);
      }
      else if (fScaleMax < 100.0) {
         nexe = 0;
         while (1) {
            nexe--;
            for (i=0; i<5; i++) {
               mark[i] *= 10.0;
            }
            // coverity[loop_condition]: ignore - false positive
            if (mark[4] > 99.9 ) break;
         }
         // draw multiplier
         fImage->DrawText((Int_t)xc - 11, (Int_t)yc + 15, "x10", 12, "#ffffff", ar);
         sc.Form("%d", nexe);
         fImage->DrawText((Int_t)xc + 11, (Int_t)yc + 13, sc.Data(), 10, "#ffffff", ar);
      }
      // Format and draw scale tickmarks
      sc.Form("%d",(Int_t)mark[0]);
      fImage->DrawText((Int_t)xc - 51, (Int_t)yc + 30, sc.Data(), 14, "#ffffff", ar);
      sc.Form("%d",(Int_t)mark[1]);
      fImage->DrawText((Int_t)xc - 59, (Int_t)yc - 29, sc.Data(), 14, "#ffffff", ar);
      sc.Form("%d",(Int_t)mark[2]);
      offset = gVirtualX->TextWidth(labelFS, sc.Data(), sc.Length()) / 2;
      fImage->DrawText((Int_t)xc - offset, (Int_t)yc - 65, sc.Data(), 14, "#ffffff", ar);
      sc.Form("%d",(Int_t)mark[3]);
      offset = 60 - gVirtualX->TextWidth(labelFS, sc.Data(), sc.Length());
      fImage->DrawText((Int_t)xc + offset, (Int_t)yc - 29, sc.Data(), 14, "#ffffff", ar);
      sc.Form("%d",(Int_t)mark[4]);
      offset = 52 - gVirtualX->TextWidth(labelFS, sc.Data(), sc.Length());
      fImage->DrawText((Int_t)xc + offset, (Int_t)yc + 30, sc.Data(), 14, "#ffffff", ar);
      // draw main label (two lines)
      fImage->DrawText((Int_t)xc + 13, (Int_t)yc - 17, fLabel1.Data(), 14, "#ffffff", ar);
      fImage->DrawText((Int_t)xc + 13, (Int_t)yc -  4, fLabel2.Data(), 12, "#ffffff", ar);
      if (fBase)
         gVirtualX->ShapeCombineMask(fId, 0, 0, fBase->GetMask());
   }
}

//______________________________________________________________________________
TGSpeedo::~TGSpeedo()
{
   // TGSpeedo widget Destructor.

   if (fImage && fImage->IsValid())
      delete fImage;
   if (fImage2 && fImage2->IsValid())
      delete fImage2;
   if (fBase)
      fClient->FreePicture(fBase);
}

//______________________________________________________________________________
TGDimension TGSpeedo::GetDefaultSize() const
{
   // Return default dimension of the widget.

   if (fBase)
      return TGDimension(fBase->GetWidth(), fBase->GetHeight());
   return TGDimension(100, 100);
}

//______________________________________________________________________________
void TGSpeedo::Glow(EGlowColor col)
{
   // Make speedo glowing.

   static EGlowColor act_col = kNoglow;
   TImage *glowImage = 0;

   if (col == act_col)
      return;

   if (fImage && fImage->IsValid())
      delete fImage;

   switch (col) {
      case kNoglow:
         break;
      case kGreen:
         glowImage = TImage::Open("glow_green.png");
         if (!glowImage || !glowImage->IsValid()) {
            Error("TGSpeedo::Glow", "glow_green.png not found");
            glowImage = 0;
         }
         break;
      case kOrange:
         glowImage = TImage::Open("glow_orange.png");
         if (!glowImage || !glowImage->IsValid()) {
            Error("TGSpeedo::Glow", "glow_orange.png not found");
            glowImage = 0;
         }
         break;
      case kRed:
         glowImage = TImage::Open("glow_red.png");
         if (!glowImage || !glowImage->IsValid()) {
            Error("TGSpeedo::Glow", "glow_red.png not found");
            glowImage = 0;
         }
         break;
   }
   fImage = TImage::Open(fPicName);
   if (fImage && fImage->IsValid() && glowImage && glowImage->IsValid()) {
      fImage->Merge(glowImage);
      delete glowImage;
   }
   act_col = col;
   Build();
   DrawText();
}

//______________________________________________________________________________
Bool_t TGSpeedo::HandleButton(Event_t *event)
{
   // Handle mouse button event.

   if (fBase) {
      int xc = (fBase->GetWidth() + 1) / 2;
      int yc = (fBase->GetHeight() + 1) / 2;
      if (event->fType == kButtonRelease && event->fCode == kButton1) {
         // check if in the selector area
         if ((event->fX > (xc - 26)) && (event->fX < (xc + 26)) &&
             (event->fY < (yc + 50)) && (event->fY > (yc + 28))) {
            OdoClicked();
         }
         // check if in the led area
         else if ((event->fX > (xc + 30)) && (event->fX < (xc + 40)) &&
                  (event->fY > (yc + 57)) && (event->fY < (yc + 67))) {
            LedClicked();
         }
      }
      if (event->fType == kButtonRelease && event->fCode == kButton3) {
         ResetPeakVal();
      }
   }
   return kTRUE;
}

//______________________________________________________________________________
void TGSpeedo::SetOdoValue(Int_t val)
{
   // Set actual value of odo meter.

   // avoid useless redraw
   if (val == fCounter)
      return;
   fCounter = val;
   DrawText();
   DrawNeedle();
}

//______________________________________________________________________________
void TGSpeedo::SetDisplayText(const char *text1, const char *text2)
{
   // Set small display text (two lines).

   if (!(fDisplay1.CompareTo(text1)) &&
       !(fDisplay2.CompareTo(text2)))
      return;
   fDisplay1 = text1;
   fDisplay2 = text2;
   DrawText();
   DrawNeedle();
}

//______________________________________________________________________________
void TGSpeedo::SetLabelText(const char *text1, const char *text2)
{
   // Set main label text (two lines).

   if (fImage && fImage->IsValid())
      delete fImage;
   fLabel1 = text1;
   fLabel2 = text2;
   fImage = TImage::Open(fPicName);
   if (!fImage || !fImage->IsValid())
      Error("TGSpeedo::Build", "%s not found", fPicName.Data());
   Build();
   DrawText();
}

//______________________________________________________________________________
void TGSpeedo::SetMinMaxScale(Float_t min, Float_t max)
{
   // Set min and max scale values.

   if (fImage && fImage->IsValid())
      delete fImage;
   fScaleMin = min;
   fScaleMax = max;
   fImage = TImage::Open(fPicName);
   if (!fImage || !fImage->IsValid())
      Error("TGSpeedo::Build", "%s not found", fPicName.Data());
   Build();
   DrawText();
}

//______________________________________________________________________________
void TGSpeedo::SetScaleValue(Float_t val)
{
   // Set actual scale (needle position) value.

   // avoid useless redraw
   if (val == fValue)
      return;

   fValue = val;
   if (fValue > fScaleMax)
      fValue = fScaleMax;
   else if (fValue < fScaleMin)
      fValue = fScaleMin;

   if (fThresholdActive) {
      if (fValue < fThreshold[0])
         Glow(kNoglow);
      if (fValue >= fThreshold[0] && fValue < fThreshold[1])
         Glow(fThresholdColor[0]);
      if (fValue >= fThreshold[1] && fValue < fThreshold[2])
         Glow(fThresholdColor[1]);
      if (fValue >= fThreshold[2])
         Glow(fThresholdColor[2]);
   }
   if (fValue > fPeakVal)
      fPeakVal = fValue;

   fAngle = fAngleMin + (fValue / ((fScaleMax - fScaleMin) /
           (fAngleMax - fAngleMin)));

   if (fAngle > fAngleMax)
      fAngle = fAngleMax;
   else if (fAngle < fAngleMin)
      fAngle = fAngleMin;
   DrawNeedle();
}

//______________________________________________________________________________
void TGSpeedo::SetScaleValue(Float_t val, Int_t damping)
{
   // Set actual scale (needle position) value.

   Float_t i;
   Float_t old_val = fValue;
   Float_t step, new_val = val;
   // avoid useless redraw
   if (val == fValue)
      return;

   if ((damping > 0) || (gVirtualX->InheritsFrom("TGX11")))
      step = 2.0;
   else
      step = 0.15;

   Float_t diff_angle = fAngleMax - fAngleMin;
   Float_t diff_scale = fScaleMax - fScaleMin;
   Float_t diff_ratio = diff_scale / diff_angle;
   Float_t old_angle  = fAngleMin + (old_val / diff_ratio);
   Float_t new_angle  = fAngleMin + (new_val / diff_ratio);

   if (new_angle > old_angle) {
      for (i=old_angle; i<new_angle; i+=step) {
         new_val = (i - fAngleMin) * diff_ratio;
         SetScaleValue(new_val);
         if (damping > 0)
            gSystem->Sleep(damping);
      }
   }
   if (new_angle < old_angle) {
      for (i=old_angle; i>new_angle; i-=step) {
         new_val = (i - fAngleMin) * diff_ratio;
         SetScaleValue(new_val);
         if (damping > 0)
            gSystem->Sleep(damping);
      }
   }
   // Last step
   SetScaleValue(val);
}

//______________________________________________________________________________
void TGSpeedo::StepScale(Float_t step)
{
   // Increment/decrement scale (needle position) of "step" value.

   SetScaleValue(fValue + step);
}

//______________________________________________________________________________
void TGSpeedo::Translate(Float_t val, Float_t angle, Int_t *x, Int_t *y)
{
   // Translate distance from center and angle to xy coordinates.

   Float_t xc = (Float_t)(fBase ? (fBase->GetWidth() + 1) / 2 : 96.0);
   Float_t yc = (Float_t)(fBase ? (fBase->GetHeight() + 1) / 2 : 96.0);
   *x = (Int_t)(xc + val * sin(angle * TMath::Pi() / 180) + 0.5);
   *y = (Int_t)(yc - val * cos(angle * TMath::Pi() / 180) + 0.5);
}

//______________________________________________________________________________
void TGSpeedo::DrawNeedle()
{
   // Draw needle in speedo widget.

   Int_t xch0, xch1, ych0, ych1;
   Int_t xpk0, ypk0, xpk1, ypk1;
   Int_t xmn0, ymn0, xmn1, ymn1;
   fValue = (fAngle - fAngleMin) * ((fScaleMax - fScaleMin) /
            (fAngleMax - fAngleMin));

   // compute x/y position of the needle
   Translate(9.0, fAngle, &xch0, &ych0);
   Translate(73.0, fAngle, &xch1, &ych1);

   // compute x/y position of the peak mark
   Float_t angle = fAngleMin + (fPeakVal / ((fScaleMax - fScaleMin) /
                  (fAngleMax - fAngleMin)));
   Translate(80.0, angle, &xpk0, &ypk0);
   Translate(67.0, angle, &xpk1, &ypk1);

   // compute x/y position of the peak mark
   angle = fAngleMin + (fMeanVal / ((fScaleMax - fScaleMin) /
          (fAngleMax - fAngleMin)));
   Translate(80.0, angle, &xmn0, &ymn0);
   Translate(70.0, angle, &xmn1, &ymn1);

   if (fImage2 && fImage2->IsValid()) {
      // First clone original image.
      TImage *img = (TImage*)fImage2->Clone("img");
      if (!img || !img->IsValid()) return;
      if (fPeakMark) {
         img->DrawLine(xpk0, ypk0, xpk1, ypk1, "#00ff00", 3);
         img->DrawLine(xpk0, ypk0, xpk1, ypk1, "#ffffff", 1);
      }
      if (fMeanMark) {
         img->DrawLine(xmn0, ymn0, xmn1, ymn1, "#ffff00", 3);
         img->DrawLine(xmn0, ymn0, xmn1, ymn1, "#ff0000", 1);
      }
      // draw line (used to render the needle) directly on the image
      img->DrawLine(xch0, ych0, xch1, ych1, "#ff0000", 2);
      // finally paint image to the widget
      img->PaintImage(fId, 0, 0, 0, 0, 0, 0, "opaque");
      // and finally, to avoid memory leaks
      delete img;
   }
   gVirtualX->Update();
}

//______________________________________________________________________________
void TGSpeedo::DrawText()
{
   // Draw text in speedo widget.

   char sval[80];
   char dsval[80];
   Int_t strSize;

   // center of the image
   Float_t xc = fBase ? (fBase->GetWidth() + 1) / 2 : 96.0;
   Float_t yc = fBase ? (fBase->GetHeight() + 1) / 2 : 96.0;

   if (fImage && fImage->IsValid()) {
      // First clone original image.
      if (fImage2 && fImage2->IsValid())
         delete fImage2;
      fImage2 = (TImage*)fImage->Clone("fImage2");
      if (!fImage2 || !fImage2->IsValid()) return;
      TString fp = gEnv->GetValue("Root.TTFontPath", "");
      TString ar = fp + "/arialbd.ttf";
      // format counter value
      Int_t nexe = 0;
      Int_t ww = fCounter;
      if (fCounter >= 10000) {
         while (1) {
            nexe++;
            ww /= 10;
            if (nexe%3 == 0 && ww < 10000) break;
         }
         fImage2->DrawText((Int_t)xc - 9, (Int_t)yc + 72, "x10", 10, "#ffffff", ar);
         snprintf(sval, 80, "%d", nexe);
         fImage2->DrawText((Int_t)xc + 9, (Int_t)yc + 69, sval, 8, "#ffffff", ar);
      }
      snprintf(sval, 80, "%04d", (int)ww);
      snprintf(dsval, 80, "%c %c %c %c", sval[0], sval[1], sval[2], sval[3]);
      // draw text in the counter
      if (gVirtualX->InheritsFrom("TGX11")) {
         // as there is a small difference between Windows and Linux...
         fImage2->DrawText((Int_t)xc - 18, (Int_t)yc + 55, dsval, 12, "#ffffff", ar);
      }
      else {
         fImage2->DrawText((Int_t)xc - 16, (Int_t)yc + 56, dsval, 12, "#ffffff", ar);
      }
      // compute the size of the string to draw in the small display box
      // first line
      strSize = gVirtualX->TextWidth(fTextFS, fDisplay1.Data(), fDisplay1.Length()) - 6;
      // draw text directly on the imaget_t)yc + 29, fDispla
      fImage2->DrawText((Int_t)xc - (strSize / 2), (Int_t)yc + 29, fDisplay1.Data(), 8, "#ffffff", ar);
      // second line
      strSize = gVirtualX->TextWidth(fTextFS, fDisplay2.Data(), fDisplay2.Length()) - 6;
      fImage2->DrawText((Int_t)xc - (strSize / 2), (Int_t)yc + 38, fDisplay2.Data(), 8, "#ffffff", ar);
   }
}

//______________________________________________________________________________
void TGSpeedo::DoRedraw()
{
   // Redraw speedo widget.

   char sval[80];
   char dsval[80];
   Int_t strSize;
   Int_t xch0, xch1, ych0, ych1;
   Int_t xpk0, ypk0, xpk1, ypk1;
   Int_t xmn0, ymn0, xmn1, ymn1;
   static Bool_t first = kTRUE;
   if (first) {
      TGFrame::DoRedraw();
      first = kFALSE;
   }
   fValue = (fAngle - fAngleMin) * ((fScaleMax - fScaleMin) /
            (fAngleMax - fAngleMin));

   // center of the image
   Float_t xc = fBase ? (fBase->GetWidth() + 1) / 2 : 96.0;
   Float_t yc = fBase ? (fBase->GetHeight() + 1) / 2 : 96.0;

   // compute x/y position of the needle
   Translate(9.0, fAngle, &xch0, &ych0);
   Translate(73.0, fAngle, &xch1, &ych1);

   // compute x/y position of the peak mark
   Float_t angle = fAngleMin + (fPeakVal / ((fScaleMax - fScaleMin) /
                  (fAngleMax - fAngleMin)));
   Translate(80.0, angle, &xpk0, &ypk0);
   Translate(67.0, angle, &xpk1, &ypk1);

   // compute x/y position of the peak mark
   angle = fAngleMin + (fMeanVal / ((fScaleMax - fScaleMin) /
          (fAngleMax - fAngleMin)));
   Translate(80.0, angle, &xmn0, &ymn0);
   Translate(70.0, angle, &xmn1, &ymn1);

   if (fImage && fImage->IsValid()) {
      // First clone original image.
      if (fImage2 && fImage2->IsValid())
         delete fImage2;
      fImage2 = (TImage*)fImage->Clone("fImage2");
      if (!fImage2 || !fImage2->IsValid()) return;
      TString fp = gEnv->GetValue("Root.TTFontPath", "");
      TString ar = fp + "/arialbd.ttf";
      // format counter value
      Int_t nexe = 0;
      Int_t ww = fCounter;
      if (fCounter >= 10000) {
         while (1) {
            nexe++;
            ww /= 10;
            if (nexe%3 == 0 && ww < 10000) break;
         }
         fImage2->DrawText((Int_t)xc - 9, (Int_t)yc + 72, "x10", 10, "#ffffff", ar);
         snprintf(sval, 80, "%d", nexe);
         fImage2->DrawText((Int_t)xc + 9, (Int_t)yc + 69, sval, 8, "#ffffff", ar);
      }
      snprintf(sval, 80, "%04d", (int)ww);
      snprintf(dsval, 80, "%c %c %c %c", sval[0], sval[1], sval[2], sval[3]);
      // draw text in the counter
      if (gVirtualX->InheritsFrom("TGX11")) {
         // as there is a small difference between Windows and Linux...
         fImage2->DrawText((Int_t)xc - 18, (Int_t)yc + 55, dsval, 12, "#ffffff", ar);
      }
      else {
         fImage2->DrawText((Int_t)xc - 16, (Int_t)yc + 56, dsval, 12, "#ffffff", ar);
      }
      // compute the size of the string to draw in the small display box
      // first line
      strSize = gVirtualX->TextWidth(fTextFS, fDisplay1.Data(), fDisplay1.Length()) - 6;
      // draw text directly on the imaget_t)yc + 29, fDispla
      fImage2->DrawText((Int_t)xc - (strSize / 2), (Int_t)yc + 29, fDisplay1.Data(), 8, "#ffffff", ar);
      // second line
      strSize = gVirtualX->TextWidth(fTextFS, fDisplay2.Data(), fDisplay2.Length()) - 6;
      fImage2->DrawText((Int_t)xc - (strSize / 2), (Int_t)yc + 38, fDisplay2.Data(), 8, "#ffffff", ar);
      TImage *img = (TImage*)fImage2->Clone("img");
      if (!img || !img->IsValid()) return;
      if (fPeakMark) {
         img->DrawLine(xpk0, ypk0, xpk1, ypk1, "#00ff00", 3);
         img->DrawLine(xpk0, ypk0, xpk1, ypk1, "#ffffff", 1);
      }
      if (fMeanMark) {
         img->DrawLine(xmn0, ymn0, xmn1, ymn1, "#ffff00", 3);
         img->DrawLine(xmn0, ymn0, xmn1, ymn1, "#ff0000", 1);
      }
      // draw line (used to render the needle) directly on the image
      img->DrawLine(xch0, ych0, xch1, ych1, "#ff0000", 2);
      // finally paint image to the widget
      img->PaintImage(fId, 0, 0, 0, 0, 0, 0, "opaque");
      // and finally, to avoid memory leaks
      delete img;
   }
}
 TGSpeedo.cxx:1
 TGSpeedo.cxx:2
 TGSpeedo.cxx:3
 TGSpeedo.cxx:4
 TGSpeedo.cxx:5
 TGSpeedo.cxx:6
 TGSpeedo.cxx:7
 TGSpeedo.cxx:8
 TGSpeedo.cxx:9
 TGSpeedo.cxx:10
 TGSpeedo.cxx:11
 TGSpeedo.cxx:12
 TGSpeedo.cxx:13
 TGSpeedo.cxx:14
 TGSpeedo.cxx:15
 TGSpeedo.cxx:16
 TGSpeedo.cxx:17
 TGSpeedo.cxx:18
 TGSpeedo.cxx:19
 TGSpeedo.cxx:20
 TGSpeedo.cxx:21
 TGSpeedo.cxx:22
 TGSpeedo.cxx:23
 TGSpeedo.cxx:24
 TGSpeedo.cxx:25
 TGSpeedo.cxx:26
 TGSpeedo.cxx:27
 TGSpeedo.cxx:28
 TGSpeedo.cxx:29
 TGSpeedo.cxx:30
 TGSpeedo.cxx:31
 TGSpeedo.cxx:32
 TGSpeedo.cxx:33
 TGSpeedo.cxx:34
 TGSpeedo.cxx:35
 TGSpeedo.cxx:36
 TGSpeedo.cxx:37
 TGSpeedo.cxx:38
 TGSpeedo.cxx:39
 TGSpeedo.cxx:40
 TGSpeedo.cxx:41
 TGSpeedo.cxx:42
 TGSpeedo.cxx:43
 TGSpeedo.cxx:44
 TGSpeedo.cxx:45
 TGSpeedo.cxx:46
 TGSpeedo.cxx:47
 TGSpeedo.cxx:48
 TGSpeedo.cxx:49
 TGSpeedo.cxx:50
 TGSpeedo.cxx:51
 TGSpeedo.cxx:52
 TGSpeedo.cxx:53
 TGSpeedo.cxx:54
 TGSpeedo.cxx:55
 TGSpeedo.cxx:56
 TGSpeedo.cxx:57
 TGSpeedo.cxx:58
 TGSpeedo.cxx:59
 TGSpeedo.cxx:60
 TGSpeedo.cxx:61
 TGSpeedo.cxx:62
 TGSpeedo.cxx:63
 TGSpeedo.cxx:64
 TGSpeedo.cxx:65
 TGSpeedo.cxx:66
 TGSpeedo.cxx:67
 TGSpeedo.cxx:68
 TGSpeedo.cxx:69
 TGSpeedo.cxx:70
 TGSpeedo.cxx:71
 TGSpeedo.cxx:72
 TGSpeedo.cxx:73
 TGSpeedo.cxx:74
 TGSpeedo.cxx:75
 TGSpeedo.cxx:76
 TGSpeedo.cxx:77
 TGSpeedo.cxx:78
 TGSpeedo.cxx:79
 TGSpeedo.cxx:80
 TGSpeedo.cxx:81
 TGSpeedo.cxx:82
 TGSpeedo.cxx:83
 TGSpeedo.cxx:84
 TGSpeedo.cxx:85
 TGSpeedo.cxx:86
 TGSpeedo.cxx:87
 TGSpeedo.cxx:88
 TGSpeedo.cxx:89
 TGSpeedo.cxx:90
 TGSpeedo.cxx:91
 TGSpeedo.cxx:92
 TGSpeedo.cxx:93
 TGSpeedo.cxx:94
 TGSpeedo.cxx:95
 TGSpeedo.cxx:96
 TGSpeedo.cxx:97
 TGSpeedo.cxx:98
 TGSpeedo.cxx:99
 TGSpeedo.cxx:100
 TGSpeedo.cxx:101
 TGSpeedo.cxx:102
 TGSpeedo.cxx:103
 TGSpeedo.cxx:104
 TGSpeedo.cxx:105
 TGSpeedo.cxx:106
 TGSpeedo.cxx:107
 TGSpeedo.cxx:108
 TGSpeedo.cxx:109
 TGSpeedo.cxx:110
 TGSpeedo.cxx:111
 TGSpeedo.cxx:112
 TGSpeedo.cxx:113
 TGSpeedo.cxx:114
 TGSpeedo.cxx:115
 TGSpeedo.cxx:116
 TGSpeedo.cxx:117
 TGSpeedo.cxx:118
 TGSpeedo.cxx:119
 TGSpeedo.cxx:120
 TGSpeedo.cxx:121
 TGSpeedo.cxx:122
 TGSpeedo.cxx:123
 TGSpeedo.cxx:124
 TGSpeedo.cxx:125
 TGSpeedo.cxx:126
 TGSpeedo.cxx:127
 TGSpeedo.cxx:128
 TGSpeedo.cxx:129
 TGSpeedo.cxx:130
 TGSpeedo.cxx:131
 TGSpeedo.cxx:132
 TGSpeedo.cxx:133
 TGSpeedo.cxx:134
 TGSpeedo.cxx:135
 TGSpeedo.cxx:136
 TGSpeedo.cxx:137
 TGSpeedo.cxx:138
 TGSpeedo.cxx:139
 TGSpeedo.cxx:140
 TGSpeedo.cxx:141
 TGSpeedo.cxx:142
 TGSpeedo.cxx:143
 TGSpeedo.cxx:144
 TGSpeedo.cxx:145
 TGSpeedo.cxx:146
 TGSpeedo.cxx:147
 TGSpeedo.cxx:148
 TGSpeedo.cxx:149
 TGSpeedo.cxx:150
 TGSpeedo.cxx:151
 TGSpeedo.cxx:152
 TGSpeedo.cxx:153
 TGSpeedo.cxx:154
 TGSpeedo.cxx:155
 TGSpeedo.cxx:156
 TGSpeedo.cxx:157
 TGSpeedo.cxx:158
 TGSpeedo.cxx:159
 TGSpeedo.cxx:160
 TGSpeedo.cxx:161
 TGSpeedo.cxx:162
 TGSpeedo.cxx:163
 TGSpeedo.cxx:164
 TGSpeedo.cxx:165
 TGSpeedo.cxx:166
 TGSpeedo.cxx:167
 TGSpeedo.cxx:168
 TGSpeedo.cxx:169
 TGSpeedo.cxx:170
 TGSpeedo.cxx:171
 TGSpeedo.cxx:172
 TGSpeedo.cxx:173
 TGSpeedo.cxx:174
 TGSpeedo.cxx:175
 TGSpeedo.cxx:176
 TGSpeedo.cxx:177
 TGSpeedo.cxx:178
 TGSpeedo.cxx:179
 TGSpeedo.cxx:180
 TGSpeedo.cxx:181
 TGSpeedo.cxx:182
 TGSpeedo.cxx:183
 TGSpeedo.cxx:184
 TGSpeedo.cxx:185
 TGSpeedo.cxx:186
 TGSpeedo.cxx:187
 TGSpeedo.cxx:188
 TGSpeedo.cxx:189
 TGSpeedo.cxx:190
 TGSpeedo.cxx:191
 TGSpeedo.cxx:192
 TGSpeedo.cxx:193
 TGSpeedo.cxx:194
 TGSpeedo.cxx:195
 TGSpeedo.cxx:196
 TGSpeedo.cxx:197
 TGSpeedo.cxx:198
 TGSpeedo.cxx:199
 TGSpeedo.cxx:200
 TGSpeedo.cxx:201
 TGSpeedo.cxx:202
 TGSpeedo.cxx:203
 TGSpeedo.cxx:204
 TGSpeedo.cxx:205
 TGSpeedo.cxx:206
 TGSpeedo.cxx:207
 TGSpeedo.cxx:208
 TGSpeedo.cxx:209
 TGSpeedo.cxx:210
 TGSpeedo.cxx:211
 TGSpeedo.cxx:212
 TGSpeedo.cxx:213
 TGSpeedo.cxx:214
 TGSpeedo.cxx:215
 TGSpeedo.cxx:216
 TGSpeedo.cxx:217
 TGSpeedo.cxx:218
 TGSpeedo.cxx:219
 TGSpeedo.cxx:220
 TGSpeedo.cxx:221
 TGSpeedo.cxx:222
 TGSpeedo.cxx:223
 TGSpeedo.cxx:224
 TGSpeedo.cxx:225
 TGSpeedo.cxx:226
 TGSpeedo.cxx:227
 TGSpeedo.cxx:228
 TGSpeedo.cxx:229
 TGSpeedo.cxx:230
 TGSpeedo.cxx:231
 TGSpeedo.cxx:232
 TGSpeedo.cxx:233
 TGSpeedo.cxx:234
 TGSpeedo.cxx:235
 TGSpeedo.cxx:236
 TGSpeedo.cxx:237
 TGSpeedo.cxx:238
 TGSpeedo.cxx:239
 TGSpeedo.cxx:240
 TGSpeedo.cxx:241
 TGSpeedo.cxx:242
 TGSpeedo.cxx:243
 TGSpeedo.cxx:244
 TGSpeedo.cxx:245
 TGSpeedo.cxx:246
 TGSpeedo.cxx:247
 TGSpeedo.cxx:248
 TGSpeedo.cxx:249
 TGSpeedo.cxx:250
 TGSpeedo.cxx:251
 TGSpeedo.cxx:252
 TGSpeedo.cxx:253
 TGSpeedo.cxx:254
 TGSpeedo.cxx:255
 TGSpeedo.cxx:256
 TGSpeedo.cxx:257
 TGSpeedo.cxx:258
 TGSpeedo.cxx:259
 TGSpeedo.cxx:260
 TGSpeedo.cxx:261
 TGSpeedo.cxx:262
 TGSpeedo.cxx:263
 TGSpeedo.cxx:264
 TGSpeedo.cxx:265
 TGSpeedo.cxx:266
 TGSpeedo.cxx:267
 TGSpeedo.cxx:268
 TGSpeedo.cxx:269
 TGSpeedo.cxx:270
 TGSpeedo.cxx:271
 TGSpeedo.cxx:272
 TGSpeedo.cxx:273
 TGSpeedo.cxx:274
 TGSpeedo.cxx:275
 TGSpeedo.cxx:276
 TGSpeedo.cxx:277
 TGSpeedo.cxx:278
 TGSpeedo.cxx:279
 TGSpeedo.cxx:280
 TGSpeedo.cxx:281
 TGSpeedo.cxx:282
 TGSpeedo.cxx:283
 TGSpeedo.cxx:284
 TGSpeedo.cxx:285
 TGSpeedo.cxx:286
 TGSpeedo.cxx:287
 TGSpeedo.cxx:288
 TGSpeedo.cxx:289
 TGSpeedo.cxx:290
 TGSpeedo.cxx:291
 TGSpeedo.cxx:292
 TGSpeedo.cxx:293
 TGSpeedo.cxx:294
 TGSpeedo.cxx:295
 TGSpeedo.cxx:296
 TGSpeedo.cxx:297
 TGSpeedo.cxx:298
 TGSpeedo.cxx:299
 TGSpeedo.cxx:300
 TGSpeedo.cxx:301
 TGSpeedo.cxx:302
 TGSpeedo.cxx:303
 TGSpeedo.cxx:304
 TGSpeedo.cxx:305
 TGSpeedo.cxx:306
 TGSpeedo.cxx:307
 TGSpeedo.cxx:308
 TGSpeedo.cxx:309
 TGSpeedo.cxx:310
 TGSpeedo.cxx:311
 TGSpeedo.cxx:312
 TGSpeedo.cxx:313
 TGSpeedo.cxx:314
 TGSpeedo.cxx:315
 TGSpeedo.cxx:316
 TGSpeedo.cxx:317
 TGSpeedo.cxx:318
 TGSpeedo.cxx:319
 TGSpeedo.cxx:320
 TGSpeedo.cxx:321
 TGSpeedo.cxx:322
 TGSpeedo.cxx:323
 TGSpeedo.cxx:324
 TGSpeedo.cxx:325
 TGSpeedo.cxx:326
 TGSpeedo.cxx:327
 TGSpeedo.cxx:328
 TGSpeedo.cxx:329
 TGSpeedo.cxx:330
 TGSpeedo.cxx:331
 TGSpeedo.cxx:332
 TGSpeedo.cxx:333
 TGSpeedo.cxx:334
 TGSpeedo.cxx:335
 TGSpeedo.cxx:336
 TGSpeedo.cxx:337
 TGSpeedo.cxx:338
 TGSpeedo.cxx:339
 TGSpeedo.cxx:340
 TGSpeedo.cxx:341
 TGSpeedo.cxx:342
 TGSpeedo.cxx:343
 TGSpeedo.cxx:344
 TGSpeedo.cxx:345
 TGSpeedo.cxx:346
 TGSpeedo.cxx:347
 TGSpeedo.cxx:348
 TGSpeedo.cxx:349
 TGSpeedo.cxx:350
 TGSpeedo.cxx:351
 TGSpeedo.cxx:352
 TGSpeedo.cxx:353
 TGSpeedo.cxx:354
 TGSpeedo.cxx:355
 TGSpeedo.cxx:356
 TGSpeedo.cxx:357
 TGSpeedo.cxx:358
 TGSpeedo.cxx:359
 TGSpeedo.cxx:360
 TGSpeedo.cxx:361
 TGSpeedo.cxx:362
 TGSpeedo.cxx:363
 TGSpeedo.cxx:364
 TGSpeedo.cxx:365
 TGSpeedo.cxx:366
 TGSpeedo.cxx:367
 TGSpeedo.cxx:368
 TGSpeedo.cxx:369
 TGSpeedo.cxx:370
 TGSpeedo.cxx:371
 TGSpeedo.cxx:372
 TGSpeedo.cxx:373
 TGSpeedo.cxx:374
 TGSpeedo.cxx:375
 TGSpeedo.cxx:376
 TGSpeedo.cxx:377
 TGSpeedo.cxx:378
 TGSpeedo.cxx:379
 TGSpeedo.cxx:380
 TGSpeedo.cxx:381
 TGSpeedo.cxx:382
 TGSpeedo.cxx:383
 TGSpeedo.cxx:384
 TGSpeedo.cxx:385
 TGSpeedo.cxx:386
 TGSpeedo.cxx:387
 TGSpeedo.cxx:388
 TGSpeedo.cxx:389
 TGSpeedo.cxx:390
 TGSpeedo.cxx:391
 TGSpeedo.cxx:392
 TGSpeedo.cxx:393
 TGSpeedo.cxx:394
 TGSpeedo.cxx:395
 TGSpeedo.cxx:396
 TGSpeedo.cxx:397
 TGSpeedo.cxx:398
 TGSpeedo.cxx:399
 TGSpeedo.cxx:400
 TGSpeedo.cxx:401
 TGSpeedo.cxx:402
 TGSpeedo.cxx:403
 TGSpeedo.cxx:404
 TGSpeedo.cxx:405
 TGSpeedo.cxx:406
 TGSpeedo.cxx:407
 TGSpeedo.cxx:408
 TGSpeedo.cxx:409
 TGSpeedo.cxx:410
 TGSpeedo.cxx:411
 TGSpeedo.cxx:412
 TGSpeedo.cxx:413
 TGSpeedo.cxx:414
 TGSpeedo.cxx:415
 TGSpeedo.cxx:416
 TGSpeedo.cxx:417
 TGSpeedo.cxx:418
 TGSpeedo.cxx:419
 TGSpeedo.cxx:420
 TGSpeedo.cxx:421
 TGSpeedo.cxx:422
 TGSpeedo.cxx:423
 TGSpeedo.cxx:424
 TGSpeedo.cxx:425
 TGSpeedo.cxx:426
 TGSpeedo.cxx:427
 TGSpeedo.cxx:428
 TGSpeedo.cxx:429
 TGSpeedo.cxx:430
 TGSpeedo.cxx:431
 TGSpeedo.cxx:432
 TGSpeedo.cxx:433
 TGSpeedo.cxx:434
 TGSpeedo.cxx:435
 TGSpeedo.cxx:436
 TGSpeedo.cxx:437
 TGSpeedo.cxx:438
 TGSpeedo.cxx:439
 TGSpeedo.cxx:440
 TGSpeedo.cxx:441
 TGSpeedo.cxx:442
 TGSpeedo.cxx:443
 TGSpeedo.cxx:444
 TGSpeedo.cxx:445
 TGSpeedo.cxx:446
 TGSpeedo.cxx:447
 TGSpeedo.cxx:448
 TGSpeedo.cxx:449
 TGSpeedo.cxx:450
 TGSpeedo.cxx:451
 TGSpeedo.cxx:452
 TGSpeedo.cxx:453
 TGSpeedo.cxx:454
 TGSpeedo.cxx:455
 TGSpeedo.cxx:456
 TGSpeedo.cxx:457
 TGSpeedo.cxx:458
 TGSpeedo.cxx:459
 TGSpeedo.cxx:460
 TGSpeedo.cxx:461
 TGSpeedo.cxx:462
 TGSpeedo.cxx:463
 TGSpeedo.cxx:464
 TGSpeedo.cxx:465
 TGSpeedo.cxx:466
 TGSpeedo.cxx:467
 TGSpeedo.cxx:468
 TGSpeedo.cxx:469
 TGSpeedo.cxx:470
 TGSpeedo.cxx:471
 TGSpeedo.cxx:472
 TGSpeedo.cxx:473
 TGSpeedo.cxx:474
 TGSpeedo.cxx:475
 TGSpeedo.cxx:476
 TGSpeedo.cxx:477
 TGSpeedo.cxx:478
 TGSpeedo.cxx:479
 TGSpeedo.cxx:480
 TGSpeedo.cxx:481
 TGSpeedo.cxx:482
 TGSpeedo.cxx:483
 TGSpeedo.cxx:484
 TGSpeedo.cxx:485
 TGSpeedo.cxx:486
 TGSpeedo.cxx:487
 TGSpeedo.cxx:488
 TGSpeedo.cxx:489
 TGSpeedo.cxx:490
 TGSpeedo.cxx:491
 TGSpeedo.cxx:492
 TGSpeedo.cxx:493
 TGSpeedo.cxx:494
 TGSpeedo.cxx:495
 TGSpeedo.cxx:496
 TGSpeedo.cxx:497
 TGSpeedo.cxx:498
 TGSpeedo.cxx:499
 TGSpeedo.cxx:500
 TGSpeedo.cxx:501
 TGSpeedo.cxx:502
 TGSpeedo.cxx:503
 TGSpeedo.cxx:504
 TGSpeedo.cxx:505
 TGSpeedo.cxx:506
 TGSpeedo.cxx:507
 TGSpeedo.cxx:508
 TGSpeedo.cxx:509
 TGSpeedo.cxx:510
 TGSpeedo.cxx:511
 TGSpeedo.cxx:512
 TGSpeedo.cxx:513
 TGSpeedo.cxx:514
 TGSpeedo.cxx:515
 TGSpeedo.cxx:516
 TGSpeedo.cxx:517
 TGSpeedo.cxx:518
 TGSpeedo.cxx:519
 TGSpeedo.cxx:520
 TGSpeedo.cxx:521
 TGSpeedo.cxx:522
 TGSpeedo.cxx:523
 TGSpeedo.cxx:524
 TGSpeedo.cxx:525
 TGSpeedo.cxx:526
 TGSpeedo.cxx:527
 TGSpeedo.cxx:528
 TGSpeedo.cxx:529
 TGSpeedo.cxx:530
 TGSpeedo.cxx:531
 TGSpeedo.cxx:532
 TGSpeedo.cxx:533
 TGSpeedo.cxx:534
 TGSpeedo.cxx:535
 TGSpeedo.cxx:536
 TGSpeedo.cxx:537
 TGSpeedo.cxx:538
 TGSpeedo.cxx:539
 TGSpeedo.cxx:540
 TGSpeedo.cxx:541
 TGSpeedo.cxx:542
 TGSpeedo.cxx:543
 TGSpeedo.cxx:544
 TGSpeedo.cxx:545
 TGSpeedo.cxx:546
 TGSpeedo.cxx:547
 TGSpeedo.cxx:548
 TGSpeedo.cxx:549
 TGSpeedo.cxx:550
 TGSpeedo.cxx:551
 TGSpeedo.cxx:552
 TGSpeedo.cxx:553
 TGSpeedo.cxx:554
 TGSpeedo.cxx:555
 TGSpeedo.cxx:556
 TGSpeedo.cxx:557
 TGSpeedo.cxx:558
 TGSpeedo.cxx:559
 TGSpeedo.cxx:560
 TGSpeedo.cxx:561
 TGSpeedo.cxx:562
 TGSpeedo.cxx:563
 TGSpeedo.cxx:564
 TGSpeedo.cxx:565
 TGSpeedo.cxx:566
 TGSpeedo.cxx:567
 TGSpeedo.cxx:568
 TGSpeedo.cxx:569
 TGSpeedo.cxx:570
 TGSpeedo.cxx:571
 TGSpeedo.cxx:572
 TGSpeedo.cxx:573
 TGSpeedo.cxx:574
 TGSpeedo.cxx:575
 TGSpeedo.cxx:576
 TGSpeedo.cxx:577
 TGSpeedo.cxx:578
 TGSpeedo.cxx:579
 TGSpeedo.cxx:580
 TGSpeedo.cxx:581
 TGSpeedo.cxx:582
 TGSpeedo.cxx:583
 TGSpeedo.cxx:584
 TGSpeedo.cxx:585
 TGSpeedo.cxx:586
 TGSpeedo.cxx:587
 TGSpeedo.cxx:588
 TGSpeedo.cxx:589
 TGSpeedo.cxx:590
 TGSpeedo.cxx:591
 TGSpeedo.cxx:592
 TGSpeedo.cxx:593
 TGSpeedo.cxx:594
 TGSpeedo.cxx:595
 TGSpeedo.cxx:596
 TGSpeedo.cxx:597
 TGSpeedo.cxx:598
 TGSpeedo.cxx:599
 TGSpeedo.cxx:600
 TGSpeedo.cxx:601
 TGSpeedo.cxx:602
 TGSpeedo.cxx:603
 TGSpeedo.cxx:604
 TGSpeedo.cxx:605
 TGSpeedo.cxx:606
 TGSpeedo.cxx:607
 TGSpeedo.cxx:608
 TGSpeedo.cxx:609
 TGSpeedo.cxx:610
 TGSpeedo.cxx:611
 TGSpeedo.cxx:612
 TGSpeedo.cxx:613
 TGSpeedo.cxx:614
 TGSpeedo.cxx:615
 TGSpeedo.cxx:616
 TGSpeedo.cxx:617
 TGSpeedo.cxx:618
 TGSpeedo.cxx:619
 TGSpeedo.cxx:620
 TGSpeedo.cxx:621
 TGSpeedo.cxx:622
 TGSpeedo.cxx:623
 TGSpeedo.cxx:624
 TGSpeedo.cxx:625
 TGSpeedo.cxx:626
 TGSpeedo.cxx:627
 TGSpeedo.cxx:628
 TGSpeedo.cxx:629
 TGSpeedo.cxx:630
 TGSpeedo.cxx:631
 TGSpeedo.cxx:632
 TGSpeedo.cxx:633
 TGSpeedo.cxx:634
 TGSpeedo.cxx:635
 TGSpeedo.cxx:636
 TGSpeedo.cxx:637
 TGSpeedo.cxx:638
 TGSpeedo.cxx:639
 TGSpeedo.cxx:640
 TGSpeedo.cxx:641
 TGSpeedo.cxx:642
 TGSpeedo.cxx:643
 TGSpeedo.cxx:644
 TGSpeedo.cxx:645
 TGSpeedo.cxx:646
 TGSpeedo.cxx:647
 TGSpeedo.cxx:648
 TGSpeedo.cxx:649
 TGSpeedo.cxx:650
 TGSpeedo.cxx:651
 TGSpeedo.cxx:652
 TGSpeedo.cxx:653
 TGSpeedo.cxx:654
 TGSpeedo.cxx:655
 TGSpeedo.cxx:656
 TGSpeedo.cxx:657
 TGSpeedo.cxx:658
 TGSpeedo.cxx:659
 TGSpeedo.cxx:660
 TGSpeedo.cxx:661
 TGSpeedo.cxx:662