ROOT logo
// @(#)root/gl:$Id$
// Author:  Timur Pocheptsov, Jun 2007

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

#include <stdexcept>
#include <vector>


#include "TVirtualX.h"
#include "TGClient.h"
#include "TError.h"
#include "TROOT.h"
#include "TVirtualMutex.h"

#include "TGLWidget.h"
#include "TGLIncludes.h"
#include "TGLWSIncludes.h"
#include "TGLUtil.h"
#include "TGLEventHandler.h"
#include "RConfigure.h"

/******************************************************************************/
// TGLWidget
/******************************************************************************/

//______________________________________________________________________________
//
// GL window with context. _Must_ _have_ a parent window
// (the 'parent' parameter of ctors). The current version inherits
// TGCanvas (I'm not sure about future versions), probably, in future
// multiple inheritance will be added - the second
// base class will be TGLPaintDevice or something like this.
//
// Usage:
// - Simply create TGLWidget as an embedded widget, and
//   connect your slots to signals you need: HandleExpose, HandleConfigureNotify, etc.
//   In your slots you can use gl API directly - under Win32 TGLWidget switches
//   between threads internally (look TGLPShapeObjEditor for such usage).
// - You can write your own class, derived from TGLWidget, with PaintGL and InitGL
//   overriden.
//
// Resources (and invariants):
// -fContainer (TGLWidgetContainer) - controlled by std::auto_ptr
// -fWindowIndex - controlled manually (see CreateWidget and dtor)
// -fGLContext - controlled manually (see CreateWidget and dtor)
// -visual info for X11 version, controlled manually (see CreateGLContainer and dtor)
//
// Exceptions:
// -can be thrown only during construction.
// -under win32 class does not throw itself (but some internal operations can throw)
// -under X11 can throw std::runtime_error (from CreateGLContext).
// -In case of exceptions resources will be freed.
//
// TGLWidget object is immutable as far as it was created.
//
// Boolean parameter defines, if you want to grab user's input or not.
// By default you want, but for example when not - see TGLPShapeObjEditor.
//
// Non-copyable.

ClassImp(TGLWidget);

//==============================================================================
// TGLWidget - system-independent methods
//==============================================================================

//______________________________________________________________________________
TGLWidget* TGLWidget::CreateDummy()
{
   // Static constructor for creating widget with default pixel format.

   TGLFormat format(Rgl::kNone);

   return Create(format, gClient->GetDefaultRoot(), kFALSE, kFALSE, 0, 1, 1);
}

//______________________________________________________________________________
TGLWidget* TGLWidget::Create(const TGWindow* parent, Bool_t selectInput,
              Bool_t shareDefault, const TGLPaintDevice *shareDevice,
              UInt_t width, UInt_t height)
{
   // Static constructor for creating widget with default pixel format.

   TGLFormat format;

   return Create(format, parent, selectInput, shareDefault, shareDevice,
                 width, height);
}

//______________________________________________________________________________
TGLWidget* TGLWidget::Create(const TGLFormat &format,
             const TGWindow* parent, Bool_t selectInput,
             Bool_t shareDefault, const TGLPaintDevice *shareDevice,
             UInt_t width, UInt_t height)
{
   // Static constructor for creating widget with given pixel format.

   // Make sure window-system dependent part of GL-util is initialized.
   TGLUtil::InitializeIfNeeded();

   std::pair<void *, void *> innerData;

   Window_t wid = CreateWindow(parent, format, width, height, innerData);

   TGLWidget* glw = new TGLWidget(wid, parent, selectInput);

#ifdef WIN32
   glw->fWindowIndex = (Int_t) innerData.second;
#elif defined(R__HAS_COCOA)
   glw->fWindowIndex = wid;
#else
   glw->fWindowIndex = gVirtualX->AddWindow(wid, width, height);
   glw->fInnerData   = innerData;
#endif
   glw->fGLFormat  = format;

   try
   {
      glw->SetFormat();
      glw->fGLContext = new TGLContext
         (glw, shareDefault, shareDevice && !shareDefault ? shareDevice->GetContext() : 0);
   }
   catch (const std::exception &)
   {
      delete glw;
      throw;
   }

   glw->fFromInit = kFALSE;

   return glw;
}

//______________________________________________________________________________
TGLWidget::TGLWidget(Window_t glw, const TGWindow* p, Bool_t selectInput)
   : TGFrame(gClient, glw, p),
     fGLContext(0),
     fWindowIndex(-1),
     fGLFormat(Rgl::kNone),
     fFromInit(kTRUE),
     fEventHandler(0)
{
   // Creates widget with default pixel format.

   if (selectInput)
   {
      gVirtualX->GrabButton(GetId(), kAnyButton, kAnyModifier,
                            kButtonPressMask | kButtonReleaseMask, kNone, kNone);
      gVirtualX->SelectInput(GetId(), kKeyPressMask | kKeyReleaseMask | kExposureMask |
                             kPointerMotionMask | kStructureNotifyMask | kFocusChangeMask |
                             kEnterWindowMask | kLeaveWindowMask);
      gVirtualX->SetInputFocus(GetId());
   }
}

//______________________________________________________________________________
TGLWidget::~TGLWidget()
{
   //Destructor. Deletes window ???? and XVisualInfo

#ifndef WIN32
#ifndef R__HAS_COCOA
   XFree(fInnerData.second);//free XVisualInfo
#endif
#endif
   if (fValidContexts.size() > 1u) {
      Warning("~TGLWidget", "There are some gl-contexts connected to this gl device"
                            "which have longer lifetime than lifetime of gl-device");
   }

   std::set<TGLContext *>::iterator it = fValidContexts.begin();
   for (; it != fValidContexts.end(); ++it) {
      (*it)->Release();
   }
   delete fGLContext;

   gVirtualX->SelectWindow(fWindowIndex);
   gVirtualX->CloseWindow();
}

//______________________________________________________________________________
void TGLWidget::InitGL()
{
   //Call glEnable(... in overrider of InitGL.
}

//______________________________________________________________________________
void TGLWidget::PaintGL()
{
   //Do actual drawing in overrider of PaintGL.
}

//______________________________________________________________________________
Bool_t TGLWidget::MakeCurrent()
{
   //Make the gl-context current.
   return fGLContext->MakeCurrent();
}

//______________________________________________________________________________
Bool_t TGLWidget::ClearCurrent()
{
   //Clear the current gl-context.
   return fGLContext->ClearCurrent();
}

//______________________________________________________________________________
void TGLWidget::SwapBuffers()
{
   //Swap buffers.
   fGLContext->SwapBuffers();
}

//______________________________________________________________________________
const TGLContext *TGLWidget::GetContext()const
{
   //Get gl context.
   return fGLContext;
}

//______________________________________________________________________________
const TGLFormat *TGLWidget::GetPixelFormat()const
{
   //Pixel format.
   return &fGLFormat;
}

//______________________________________________________________________________
std::pair<void *, void *> TGLWidget::GetInnerData()const
{
   //Dpy*, XVisualInfo *
   return fInnerData;
}

//______________________________________________________________________________
void TGLWidget::AddContext(TGLContext *ctx)
{
   //Register gl-context created for this window.
   fValidContexts.insert(ctx);
}

//______________________________________________________________________________
void TGLWidget::RemoveContext(TGLContext *ctx)
{
   //Remove context (no real deletion, done by TGLContex dtor).
   std::set<TGLContext *>::iterator it = fValidContexts.find(ctx);
   if (it != fValidContexts.end())
      fValidContexts.erase(it);
}

//______________________________________________________________________________
void TGLWidget::ExtractViewport(Int_t *vp)const
{
   //For camera.

   vp[0] = 0;
   vp[1] = 0;
   vp[2] = GetWidth();
   vp[3] = GetHeight();
}

//==============================================================================
// System specific methods and helper functions
//==============================================================================

//==============================================================================
#ifdef WIN32
//==============================================================================

namespace {

   struct LayoutCompatible_t {
      void          *fDummy0;
      void          *fDummy1;
      HWND          *fPHwnd;
      unsigned char  fDummy2;
      unsigned       fDummy3;
      unsigned short fDummy4;
      unsigned short fDummy5;
      void          *fDummy6;
      unsigned       fDummy7:2;
   };

   void fill_pfd(PIXELFORMATDESCRIPTOR *pfd, const TGLFormat &request)
   {
      pfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
      pfd->nVersion = 1;
      pfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
      if (request.IsDoubleBuffered())
         pfd->dwFlags |= PFD_DOUBLEBUFFER;
      pfd->iPixelType = PFD_TYPE_RGBA;
      pfd->cColorBits = 24;
      if (UInt_t acc = request.GetAccumSize())
         pfd->cAccumBits = acc;
      if (UInt_t depth = request.GetDepthSize())
         pfd->cDepthBits = depth;
      if (UInt_t stencil = request.GetStencilSize())
         pfd->cStencilBits = stencil;
   }

   void check_pixel_format(Int_t pixIndex, HDC hDC, TGLFormat &request)
   {
      PIXELFORMATDESCRIPTOR pfd = {};

      if (!DescribePixelFormat(hDC, pixIndex, sizeof pfd, &pfd)) {
         Warning("TGLContext::SetContext", "DescribePixelFormat failed");
         return;
      }

      if (pfd.cAccumBits)
         request.SetAccumSize(pfd.cAccumBits);

      if (pfd.cDepthBits)
         request.SetDepthSize(pfd.cDepthBits);

      if (pfd.cStencilBits)
         request.SetStencilSize(pfd.cStencilBits);
   }

}

//______________________________________________________________________________
Window_t TGLWidget::CreateWindow(const TGWindow* parent, const TGLFormat& /*format*/,
                                 UInt_t width, UInt_t  height,
                                 std::pair<void *, void *>& innerData)
{
   // CreateWidget.
   // Static function called prior to widget construction,
   // I've extracted this code from ctors to make WIN32/X11
   // separation simpler and because of gInterpreter usage.
   // new, TGLContext can throw
   // std::bad_alloc and std::runtime_error. Before try block, the only
   // resource allocated is pointed by fWindowIndex (InitWindow cannot throw).
   // In try block (and after successful constraction)
   // resources are controlled by std::auto_ptrs and dtor.

   Int_t widx = gVirtualX->InitWindow((ULong_t)parent->GetId());
   innerData.second = (void*) widx;
   Window_t win = gVirtualX->GetWindowID(widx);
   gVirtualX->ResizeWindow(win, width, height);
   return win;
}

//______________________________________________________________________________
void TGLWidget::SetFormat()
{
   // Set pixel format.
   // Resource - hDC, owned and freed by guard object.

   if (!fFromInit) {
      Error("TGLWidget::SetFormat", "Sorry, you should not call this function");
      return;
   }
   if (!gVirtualX->IsCmdThread())
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->SetFormat()", this));

   R__LOCKGUARD2(gROOTMutex);

   LayoutCompatible_t *trick =
      reinterpret_cast<LayoutCompatible_t *>(GetId());
   HWND hWND = *trick->fPHwnd;
   HDC  hDC  = GetWindowDC(hWND);

   if (!hDC) {
      Error("TGLWidget::SetFormat", "GetWindowDC failed");
      throw std::runtime_error("GetWindowDC failed");
   }

   const Rgl::TGuardBase &dcGuard = Rgl::make_guard(ReleaseDC, hWND, hDC);
   PIXELFORMATDESCRIPTOR pfd = {};
   fill_pfd(&pfd, fGLFormat);

   if (const Int_t pixIndex = ChoosePixelFormat(hDC, &pfd)) {
      check_pixel_format(pixIndex, hDC, fGLFormat);

      if (!SetPixelFormat(hDC, pixIndex, &pfd)) {
         Error("TGLWidget::SetFormat", "SetPixelFormat failed");
         throw std::runtime_error("SetPixelFormat failed");
      }
   } else {
      Error("TGLWidget::SetFormat", "ChoosePixelFormat failed");
      throw std::runtime_error("ChoosePixelFormat failed");
   }
}
//==============================================================================
#elif defined(R__HAS_COCOA) //MacOSX with Cocoa enabled.
//==============================================================================

//______________________________________________________________________________
Window_t TGLWidget::CreateWindow(const TGWindow* parent, const TGLFormat &format,
                                 UInt_t width, UInt_t height,
                                 std::pair<void *, void *>& /*internalData*/)
{
   // CreateWidget - MacOSX/Cocoa version.
   // Static function called prior to construction.

   typedef std::pair<UInt_t, Int_t> component_type;
   
   std::vector<component_type>formatComponents;

   if (format.HasDepth())
      formatComponents.push_back(component_type(Rgl::kDepth, format.GetDepthSize()));
   if (format.HasStencil())
      formatComponents.push_back(component_type(Rgl::kStencil, format.GetStencilSize()));
   if (format.HasAccumBuffer())
      formatComponents.push_back(component_type(Rgl::kAccum, format.GetAccumSize()));
   if (format.IsDoubleBuffered())
      formatComponents.push_back(component_type(Rgl::kDoubleBuffer, 0));
   if (format.IsStereo())
      formatComponents.push_back(component_type(Rgl::kStereo, 0));
   if (format.HasMultiSampling())
      formatComponents.push_back(component_type(Rgl::kMultiSample, format.GetSamples()));

   return gVirtualX->CreateOpenGLWindow(parent->GetId(), width, height, formatComponents);
}

//______________________________________________________________________________
void TGLWidget::SetFormat()
{
   // Set pixel format.
   // Empty version for X11.
}

//==============================================================================
#else // X11
//==============================================================================

namespace
{
   void fill_format(std::vector<Int_t> &format, const TGLFormat &request)
   {
      format.push_back(GLX_RGBA);
      format.push_back(GLX_RED_SIZE);
      format.push_back(8);
      format.push_back(GLX_GREEN_SIZE);
      format.push_back(8);
      format.push_back(GLX_BLUE_SIZE);
      format.push_back(8);

      if (request.IsDoubleBuffered())
         format.push_back(GLX_DOUBLEBUFFER);

      if (request.HasDepth()) {
         format.push_back(GLX_DEPTH_SIZE);
         format.push_back(request.GetDepthSize());
      }

      if (request.HasStencil()) {
         format.push_back(GLX_STENCIL_SIZE);
         format.push_back(request.GetStencilSize());
      }

      if (request.HasAccumBuffer()) {
         format.push_back(GLX_ACCUM_RED_SIZE);
         format.push_back(8);
         format.push_back(GLX_ACCUM_GREEN_SIZE);
         format.push_back(8);
         format.push_back(GLX_ACCUM_BLUE_SIZE);
         format.push_back(8);
      }

      if (request.IsStereo()) {
         format.push_back(GLX_STEREO);
      }

      if (request.HasMultiSampling())
      {
         format.push_back(GLX_SAMPLE_BUFFERS_ARB);
         format.push_back(1);
         format.push_back(GLX_SAMPLES_ARB);
         format.push_back(request.GetSamples());
      }

      format.push_back(None);
   }
}

//______________________________________________________________________________
Window_t TGLWidget::CreateWindow(const TGWindow* parent, const TGLFormat &format,
                                 UInt_t width, UInt_t height,
                                 std::pair<void *, void *>& innerData)
{
   // CreateWidget - X11 version.
   // Static function called prior to construction.
   // Can throw std::bad_alloc and std::runtime_error.
   // This version is bad - I do not check the results of
   // X11 calls.

   std::vector<Int_t> glxfmt;
   fill_format(glxfmt, format);

   Display *dpy = reinterpret_cast<Display *>(gVirtualX->GetDisplay());
   if (!dpy) {
      ::Error("TGLWidget::CreateWindow", "Display is not set!");
      throw std::runtime_error("Display is not set!");
   }
   XVisualInfo *visInfo = glXChooseVisual(dpy, DefaultScreen(dpy), &glxfmt[0]);

   if (!visInfo) {
      ::Error("TGLWidget::CreateWindow", "No good OpenGL visual found!");
      throw std::runtime_error("No good OpenGL visual found!");
   }

   Window_t winID = parent->GetId();

   XSetWindowAttributes attr;
   attr.colormap         = XCreateColormap(dpy, winID, visInfo->visual, AllocNone); // Can fail?
   attr.background_pixel = 0;
   attr.event_mask       = NoEventMask;
   attr.backing_store    = Always;
   attr.bit_gravity      = NorthWestGravity;

   ULong_t mask = CWBackPixel | CWColormap | CWEventMask | CWBackingStore | CWBitGravity;
   Window glWin = XCreateWindow(dpy, winID, 0, 0, width, height, 0,
                                visInfo->depth,
                                InputOutput, visInfo->visual, mask, &attr);

   innerData.first  = dpy;
   innerData.second = visInfo;

   return glWin;
}

//______________________________________________________________________________
void TGLWidget::SetFormat()
{
   // Set pixel format.
   // Empty version for X11.
}

//==============================================================================
#endif
//==============================================================================


//==============================================================================
// Event handling
//==============================================================================

//______________________________________________________________________________
void TGLWidget::SetEventHandler(TGEventHandler *eh)
{
   //Set event-handler. All events are passed to this object.
   fEventHandler = eh;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleCrossing(Event_t *ev)
{
   // Handle mouse crossing event.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleCrossing((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if ((ev->fType == kEnterNotify) &&
       (!gVirtualX->InheritsFrom("TGX11")) &&
       (gVirtualX->GetInputFocus() != GetId())) {
      gVirtualX->SetInputFocus(GetId());
   }
   if (fEventHandler)
      return fEventHandler->HandleCrossing(ev);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleButton(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleButton((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler)
      return fEventHandler->HandleButton(ev);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleDoubleClick(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleDoubleClick((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler)
      return fEventHandler->HandleDoubleClick(ev);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleConfigureNotify(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleConfigureNotify((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler && fEventHandler->HandleConfigureNotify(ev))
   {
      TGFrame::HandleConfigureNotify(ev);
      return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleFocusChange(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleFocusChange((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler)
      return fEventHandler->HandleFocusChange(ev);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleKey(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleKey((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler)
      return fEventHandler->HandleKey(ev);
   return kFALSE;
}

//______________________________________________________________________________
Bool_t TGLWidget::HandleMotion(Event_t *ev)
{
   //Delegate call to the owner.
   if (!gVirtualX->IsCmdThread()) {
      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->HandleMotion((Event_t *)0x%lx)", (ULong_t)this, (ULong_t)ev));
      return kTRUE;
   }
   R__LOCKGUARD2(gROOTMutex);

   if (fEventHandler)
      return fEventHandler->HandleMotion(ev);
   return kFALSE;
}

//______________________________________________________________________________
void TGLWidget::DoRedraw()
{
   //Delegate call to the owner.
//   if (!gVirtualX->IsCmdThread()) {
//      gROOT->ProcessLineFast(Form("((TGLWidget *)0x%lx)->DoRedraw()", this));
//      return;
//   }
//    R__LOCKGUARD2(gROOTMutex);

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