    // @(#)root/qt:$Name:  $:$Id: TQtClientFilter.cxx,v 1.6 2005/04/15 07:19:50 brun Exp $
    // Author: Valeri Fine   21/01/2002

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

    #include "TQtClientFilter.h"
    #include "TQtRConfig.h"

    #ifdef R__QTGUITHREAD
    #   include "TQtNextEventMessage.h"
    #endif
    #include "TQtClientWidget.h"
    #include "TGQt.h"
    #include "TQtEventQueue.h"
    #include "TQUserEvent.h"

    #include "TSystem.h"
    #include "TStopwatch.h"
    #include "qevent.h"
    #include <qdatetime.h>
    #include <qcursor.h>
    #include <qtextcodec.h>

    #include "KeySymbols.h"

    ClassImp(TQtClientFilter)

    //
    //  TQtClientFilter  is Qt "eventFilter" to map Qt event to ROOT event
    //

    //______________________________________________________________________________________
    static inline UInt_t  MapModifierState(Qt::ButtonState qState)
    {
       UInt_t state = 0;
       if ( qState & Qt::ShiftButton   ) state |= kKeyShiftMask;
       if ( qState & Qt::ControlButton ) state |= kKeyControlMask;
       if ( qState & Qt::AltButton     ) state |= kKeyMod1Mask;
       if ( qState & Qt::RightButton   ) state |= kButton3Mask;
       if ( qState & Qt::MidButton     ) state |= kButton2Mask;
       if ( qState & Qt::LeftButton    ) state |= kButton1Mask;
       if ( qState & Qt::MetaButton    ) state |= kKeyLockMask;
       return state;
    }

    //______________________________________________________________________________________
    static inline void MapEvent(QMouseEvent &qev, Event_t &ev)
    {
       ev.fX      = qev.x();
       ev.fY      = qev.y();
       ev.fXRoot  = qev.globalX();
       ev.fYRoot  = qev.globalY();
       Qt::ButtonState state = Qt::NoButton;
       switch ( state = (qev.type()== QEvent::MouseMove ? qev.state() :  qev.button() ) ) {
          case Qt::LeftButton:
             // Set if the left button is pressed, or if this event refers to the left button.
             //(The left button may be the right button on left-handed mice.)
             ev.fCode  = kButton1;
             // ev.fState = kButton1Mask;
             break;
          case Qt::MidButton:
             // the middle button.
             ev.fCode  = kButton2;
             // ev.fState = kButton2Mask;
             break;
          case Qt::RightButton:
             //  the right button
             ev.fCode  = kButton3;
             // ev.fState = kButton3Mask;
             break;
          default:
             if (qev.type() != QEvent::MouseMove) {
              fprintf(stderr,"Error ***. Unexpected event. MapEvent(QMouseEvent &qev, Event_t &ev) state = %d\n",state);
              return;
             }
             break;
       };
       ev.fState |= MapModifierState(qev.state());
       if (ev.fCode)
          ev.fUser[0] = TGQt::rootwid(TGQt::wid(ev.fWindow)->childAt(ev.fX,ev.fY)) ;

       qev.ignore(); // propage the mouse event further
    }

    //---- Key symbol mapping
    struct KeyQSymbolMap_t {
       Qt::Key fQKeySym;
       EKeySym fKeySym;
    };

    //---- Mapping table of all non-trivial mappings (the ASCII keys map
    //---- one to one so are not included)

    static KeyQSymbolMap_t gKeyQMap[] = {
       {Qt::Key_Escape,    kKey_Escape},
       {Qt::Key_Tab,       kKey_Tab},
       {Qt::Key_Backtab,   kKey_Backtab},
       {Qt::Key_BackSpace, kKey_Backspace},
       {Qt::Key_Return,    kKey_Return},
       {Qt::Key_Insert,    kKey_Insert},
       {Qt::Key_Delete,    kKey_Delete},
       {Qt::Key_Pause,     kKey_Pause},
       {Qt::Key_Print,     kKey_Print},
       {Qt::Key_SysReq,    kKey_SysReq},
       {Qt::Key_Home,      kKey_Home},       // cursor movement
       {Qt::Key_End,       kKey_End},
       {Qt::Key_Left,      kKey_Left},
       {Qt::Key_Up,        kKey_Up},
       {Qt::Key_Right,     kKey_Right},
       {Qt::Key_Down,      kKey_Down},
       {Qt::Key_Prior,     kKey_Prior},
       {Qt::Key_Next,      kKey_Next},
       {Qt::Key_Shift,     kKey_Shift},
       {Qt::Key_Control,   kKey_Control},
       {Qt::Key_Meta,      kKey_Meta},
       {Qt::Key_Alt,       kKey_Alt},
       {Qt::Key_CapsLock,  kKey_CapsLock},
       {Qt::Key_NumLock ,  kKey_NumLock},
       {Qt::Key_ScrollLock, kKey_ScrollLock},
       {Qt::Key_Space,     kKey_Space},  // numeric keypad
       {Qt::Key_Tab,       kKey_Tab},
       {Qt::Key_Enter,     kKey_Enter},
       {Qt::Key_Equal,     kKey_Equal},
       {Qt::Key_Asterisk,  kKey_Asterisk},
       {Qt::Key_Plus,      kKey_Plus},
       {Qt::Key_Comma,     kKey_Comma},
       {Qt::Key_Minus,     kKey_Minus},
       {Qt::Key_Period,    kKey_Period},
       {Qt::Key_Slash,     kKey_Slash},
       {Qt::Key(0), (EKeySym) 0}
    };
    //______________________________________________________________________________________
    static inline UInt_t MapKeySym(const QKeyEvent &qev)
    {
       UInt_t text = 0;;
       Qt::Key key = Qt::Key(qev.key());
       for (int i = 0; gKeyQMap[i].fKeySym; i++) {	// any other keys
          if (key ==  gKeyQMap[i].fQKeySym) {
             return   UInt_t(gKeyQMap[i].fKeySym);
          }
       }
    #if 0
       QCString r = gQt->GetTextDecoder()->fromUnicode(qev.text());
       qstrncpy((char *)&text, (const char *)r,1);
       return text;
    #else
       text = UInt_t(qev.ascii());
       // Regenerate the ascii code (Qt bug I guess)
       if ( (qev.state() & Qt::KeyButtonMask) ) {
          if (  ( Qt::Key_A <= key && key <= Qt::Key_Z)  )
                text =  (( qev.state() & Qt::ShiftButton )?  'A' : 'a') + (key - Qt::Key_A) ;
          else if (  ( Qt::Key_0 <= key && key <= Qt::Key_9)  )
                text =    '0'  + (key - Qt::Key_0);
       }

        // we have to accomodate the new ROOT GUI logic.
        // the information about the "ctrl" key should provided TWICE nowadays 12.04.2005 vf.
    //   }
       return text;
    #endif
    }
    //______________________________________________________________________________________
    static inline void MapEvent(const QKeyEvent  &qev, Event_t &ev)
    {
       ev.fCode  = MapKeySym(qev);
       ev.fState = MapModifierState(qev.state());
       ev.fCount = qev.count();
       ev.fUser[0] = TGQt::rootwid(TGQt::wid(ev.fWindow)->childAt(ev.fX,ev.fY)) ;
       // qev.accept();
    }
    //______________________________________________________________________________________
    static inline void MapEvent(const QMoveEvent &qev, Event_t &ev)
    {
       ev.fX = qev.pos().x();
       ev.fY = qev.pos().y();
    }
    //______________________________________________________________________________________
    static inline void MapEvent(const QResizeEvent &qev, Event_t &ev)
    {
       ev.fWidth  = qev.size().width();	   // width and
       ev.fHeight = qev.size().height();	// height of exposed area
    }
    //______________________________________________________________________________________
    static inline void MapEvent(const QPaintEvent &qev, Event_t &ev)
    {
       ev.fX = qev.rect().x();
       ev.fY = qev.rect().y();
       ev.fWidth  = qev.rect().width();	  // width and
       ev.fHeight = qev.rect().height();  // height of exposed area
       ev.fCount  = 0;
       //         ev.fCount = xev.expose.count;	// number of expose events still to come
    }
    //______________________________________________________________________________________
    static inline void MapEvent(const TQUserEvent &qev, Event_t &ev)
    {
       qev.getData(ev);
    }
    //______________________________________________________________________________________
    static inline TQtClientWidget *GrabEvent(Event_t &event/*,QPtrList<TQtClientWidget> &grabList*/)
    {
       // Substitute the orginal window with the grabbed one if any
    #if 1
       TQtClientWidget *grabbedWidget = (TQtClientWidget *)TGQt::wid(event.fWindow);
       while (grabbedWidget && !(grabbedWidget->IsGrabbed(event))) {
          QWidget *w = grabbedWidget->parentWidget();
          grabbedWidget = (TQtClientWidget *)w;
       }
       return grabbedWidget;
    #else
       TQtClientWidget *grabbedWidget = grabList.first();
       while (grabbedWidget && !(grabbedWidget->IsGrabbed(event)))
          grabbedWidget = grabList.next();
    #endif
    }
    //______________________________________________________________________________________
    static inline bool GrabPointer(Event_t &event,TQtClientWidget * grabber)
    {
       // fprintf(stderr,"GrabPointer grabber=%p; event.Window=%d\n",grabber, event.fWindow);
       if (grabber) {
          if (grabber->IsGrabOwner()) return true;
          else if (grabber->IsPointerGrabbed(event)) {
             grabber->GrabEvent(event);
             return true;
          }
       }
       return false;
    }
    //______________________________________________________________________________
     TQtClientFilter::~TQtClientFilter()
    {
       qApp->lock();
    #ifdef R__QTGUITHREAD
       delete fNotifyClient;fNotifyClient=0;
    #endif
       if (fRootEventQueue) {
          delete fRootEventQueue;
          fRootEventQueue = 0;
       }
       qApp->unlock();
    }
    //______________________________________________________________________________
    static void SendCloseMessage(Event_t &closeEvent)
    {
       // Send close message to window provided via closeEvent.
       // This method should be called just use close window via WM

       if (closeEvent.fType != kDestroyNotify) return;
       Event_t event = closeEvent;

       event.fType   = kClientMessage;
       event.fFormat = 32;
       event.fHandle = gWM_DELETE_WINDOW;

       // event.fWindow  = GetId();
       event.fUser[0] = (Long_t) gWM_DELETE_WINDOW;
       event.fUser[1] = 0;
       event.fUser[2] = 0;
       event.fUser[3] = 0;
       event.fUser[4] = 0;

       gVirtualX->SendEvent(event.fWindow, &event);
    }
    //______________________________________________________________________________
    void DebugMe() {
       // fprintf(stderr, "Debug me please \n");
    }

    //______________________________________________________________________________
     bool TQtClientFilter::eventFilter( QObject *qWidget, QEvent *e ){
       // Dispatch The Qt event from event queue to Event_t structure
       // Not all of the event fields are valid for each event type,
       // except fType and fWindow.

       // Set to default event. This method however, should never be called.
       // check whether we are getting the desktop event
       ULong_t selectEventMask = 0;
       Bool_t  grabEvent       = kFALSE;
       static TStopwatch *filterTime = 0;
       static int neventProcessed = 0;
       neventProcessed ++;
       Event_t &event = *new Event_t;
       memset( &event,0,sizeof(Event_t));
       event.fType      = kOtherEvent;

       // Cast it carefully
       TQtClientWidget *frame = dynamic_cast<TQtClientWidget *>(qWidget);
       if (!frame)    {
             if (filterTime) filterTime->Stop();
             return kFALSE; // it is a desktop, it is NOT ROOT gui object
       }
       QPaintDevice *paintDev = (QPaintDevice *)frame;

       // Fill the default event values

       event.fWindow    = TGQt::rootwid(paintDev);

       event.fSendEvent = !e->spontaneous();
       event.fTime      = QTime::currentTime().msec ();
       event.fX         = frame->x();
       event.fY         = frame->y();
       event.fWidth     = frame->width();	// width and
       event.fHeight    = frame->height();	// height excluding the frame

       QMouseEvent *mouseEvent = 0;
       QKeyEvent   *keyEvent   = 0; //     Q Event::KeyPress or QEvent::KeyRelease.
       QFocusEvent *focusEvent = 0; //     Q Event::KeyPress or QEvent::KeyRelease.
       switch ( e->type() ) {
          case QEvent::MouseButtonPress:     // mouse button pressed
             event.fType   = kButtonPress;
             mouseEvent = (QMouseEvent *)e;
             MapEvent(*mouseEvent,event);
             selectEventMask |=  kButtonPressMask;
             // Passive grab
    #if 0
             if ( fPointerGrabber ) {
    //            ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             } else
    #endif
                if ( fButtonGrabList.findRef(frame) >=0 && frame->IsGrabbed(event) )
             {
                ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             } else {
                // delete &event;
                // return kTRUE;  // We do not need the standard Qt processing
                // return kFALSE;  // We do not need the standard Qt processing
             };
             break;

          case QEvent::MouseButtonRelease:   // mouse button released
             event.fType   = kButtonRelease;
             mouseEvent = (QMouseEvent *)e;
             MapEvent(*mouseEvent,event);
             selectEventMask |=  kButtonReleaseMask;
             if ( fPointerGrabber ) {
    //            ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             } else if ( fButtonGrabList.findRef(frame) >=0 && frame->IsGrabbed(event) )
             {
                ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             } else {
                //delete &event;
                //return kTRUE;  // We do not need the standard Qt processing
             };
             break;

          case QEvent::MouseButtonDblClick:
    #if ROOT_VERSION_CODE >= ROOT_VERSION(4,00,1)
             event.fType   = kButtonDoubleClick;
              // the rest code is taken from kButtonPress
             mouseEvent = (QMouseEvent *)e;
             MapEvent(*mouseEvent,event);
             selectEventMask |=  kButtonPressMask;
             if ( fPointerGrabber ) {
                //            ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             } else if ( fButtonGrabList.findRef(frame) >=0 && frame->IsGrabbed(event) )
             {
                ((QMouseEvent *)e)->accept();
                grabEvent = kTRUE;
             };
    #endif
             break;

          case QEvent::MouseMove:            // mouse move
             event.fType   = kMotionNotify;
             mouseEvent = (QMouseEvent *)e;
             MapEvent(*mouseEvent,event);
             selectEventMask |=  kPointerMotionMask;
             if (event.fCode == kButton1 || event.fCode == kButton2 || event.fCode == kButton3)
             {
                selectEventMask |=  kButtonMotionMask;
             }
             //// check grabbing

             if (fIsGrabbing && fPointerGrabber &&  QApplication::widgetAt(mouseEvent->globalPos()))
             {
                fIsGrabbing = false;
                fPointerGrabber->releaseMouse();
             }
             // Active grab
             if ( GrabPointer(event, fPointerGrabber)) {
                grabEvent = kTRUE;
                ((QMouseEvent *)e)->accept();
             } else if ( event.fCode && fButtonGrabList.findRef(frame) >=0 && frame->IsGrabbed(event) ) {
                grabEvent = kTRUE;
                ((QMouseEvent *)e)->accept();
             } else if (frame->GetCanvasWidget())  {
                ((QMouseEvent *)e)->accept();
             } else {
                delete &event;  // discard this event
                if (filterTime) filterTime->Stop();
                return kFALSE;  // We do need this event to be propagated to its parent by Qt
             }
             break;
          case QEvent::KeyPress:             // key pressed
             event.fType   = kGKeyPress;
             keyEvent = (QKeyEvent *)e;
             MapEvent(*keyEvent,event);
             selectEventMask |=  kKeyPressMask;
             {
                TQtClientWidget *grabber = 0;
               if (fKeyGrabber) grabber = fKeyGrabber->IsKeyGrabbed(event);
               if (!grabber)    grabber = frame->      IsKeyGrabbed(event);
               if (grabber) {
                  grabber->GrabEvent(event,false);
                  grabEvent = kTRUE;
                  ((QKeyEvent *)e)->accept();
               } else {
                  ((QKeyEvent *)e)->ignore();
               }
             //  fprintf(stderr, " accepted: case QEvent::KeyPress: <%c><%d>: frame = %x; grabber = %x grabbed = %d\n",event.fCode,event.fCode,TGQt::wid(frame), TGQt::wid(grabber),grabEvent);
             //  fprintf(stderr, "  QEvent::KeyPress: <%s>: key = %d, key_f=%d\n",(const char *)keyEvent->text(),keyEvent->key(),Qt::Key_F);
             //  fprintf(stderr, "  QEvent::KeyPress: Current focus %p\n",(QPaintDevice *) qApp->focusWidget () );
             //  fprintf(stderr, "---------------\n\n");
             }
             break;
          case QEvent::KeyRelease:           // key released
             event.fType   = kKeyRelease;
             keyEvent = (QKeyEvent *)e;
             MapEvent(*keyEvent,event);
             selectEventMask |=  kKeyReleaseMask;
             {
               TQtClientWidget *grabber = frame->IsKeyGrabbed(event);
               if (grabber) {
                  grabber->GrabEvent(event,false);
                  grabEvent = kTRUE;
                  ((QKeyEvent *)e)->accept();
               } else {
                  ((QKeyEvent *)e)->ignore();
               }
             }
             break;
          case QEvent::FocusIn:              // keyboard focus received
             focusEvent   = (QFocusEvent *)e;
             event.fCode  = kNotifyNormal;
             event.fState = 0;
             event.fType  = kFocusIn;
             selectEventMask |=  kFocusChangeMask;
             // fprintf(stderr, "       case IN QEvent::FocusEvent:frame = %x; \n",TGQt::wid(frame));
           break;
          case QEvent::FocusOut:             // keyboard focus lost
             focusEvent   = (QFocusEvent *)e;
             event.fCode  = kNotifyNormal;
             event.fState = 0;
             event.fType  = kFocusOut;
             selectEventMask |=  kFocusChangeMask;
             // fprintf(stderr, "       case OUT QEvent::FocusEvent:frame = %x; \n",TGQt::wid(frame));
             break;
          case QEvent::Enter:                // mouse enters widget
             event.fType   = kEnterNotify;
             selectEventMask |=  kEnterWindowMask;
             break;
          case QEvent::Leave:                // mouse leaves widget
             event.fType   = kLeaveNotify;
             if (fPointerGrabber && !fIsGrabbing && fPointerGrabber->IsGrabOwner() && frame->isTopLevel() )
             {
                // Let's grab it to hook all messages
                // fprintf(stderr," QEvent::Leave frame=%p top=%d parent=%p\n", frame, frame->isTopLevel(),frame->parentWidget());
                fPointerGrabber->grabMouse();
                fIsGrabbing = true;
             }
             selectEventMask |=  kLeaveWindowMask;
             break;
          case QEvent::Close:
             event.fType   = kDestroyNotify;
             ((QCloseEvent *)e)->accept();
             // ((QCloseEvent *)e)->ignore();
             fprintf(stderr, " QEvent::Close spontaneous %d:\n",e->spontaneous());
             if (fIsGrabbing && (fPointerGrabber == frame))
             {
                fIsGrabbing = false;
                gVirtualX->GrabPointer(0, 0, 0, 0,kFALSE);
             }
             SendCloseMessage(event);
             selectEventMask |=  kStructureNotifyMask;
             break;
          case QEvent::Destroy:              //  during object destruction
             event.fType   = kDestroyNotify;
             if (fIsGrabbing && (fPointerGrabber == frame))
             {
                fIsGrabbing = false;
                gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
             }
             selectEventMask |=  kStructureNotifyMask;
             fprintf(stderr, " Event::Destroy: \n");
             // SendCloseMessage(event); nothing to do here
             break;
          case QEvent::Show:                 // Widget was shown on screen,
          case QEvent::ShowWindowRequest:    //  (obsolete)  widget's window should be mapped
             event.fType   = kMapNotify;
             selectEventMask |=  kStructureNotifyMask;
             break;
          case QEvent::Paint:                //   widget's window should be mapped
             event.fType   = kExpose;
             MapEvent(*(QPaintEvent *)e,event);
             selectEventMask |=  kExposureMask;
             break;
          case QEvent::Hide:                //   widget's window should be unmapped
             event.fType   = kUnmapNotify;
             selectEventMask |=  kStructureNotifyMask;
             break;
          case QEvent::Resize:              // window move/resize event
             event.fType   = kConfigureNotify;
             MapEvent(*(QResizeEvent *)e,event);
             selectEventMask |=  kStructureNotifyMask;
             break;
          case QEvent::Move:
             event.fType   = kConfigureNotify;
             MapEvent(*(QMoveEvent *)e,event);
             selectEventMask |=  kStructureNotifyMask;
             break;
           case QEvent::Clipboard:          // window move/resize event
             event.fType  =  kSelectionNotify;
    #ifdef R__QTX11
              // this is the platform depended part
             event.fType   = kSelectionClear; // , kSelectionRequest, kSelectionNotify;
    #endif
             grabEvent = kTRUE;
             selectEventMask |=  kStructureNotifyMask;
             break;
         default:
             if ( e->type() >= TQUserEvent::Id()) {
                // event.fType = kClientMessage; ..event type will be set by MapEvent anyway
                MapEvent(*(TQUserEvent *)e,event);
                grabEvent = kTRUE;
                if (event.fType != kClientMessage && event.fType != kDestroyNotify)
                    fprintf(stderr, "** Error ** TQUserEvent:  %d %d\n", event.fType, kClientMessage);
                else if (event.fType == kDestroyNotify) {
                   //  remove all events related to the dead window
    #ifdef QTDEBUG
                   int nRemoved = fRootEventQueue->RemoveItems(&event);
                   fprintf(stderr,"kDestroyNotify %d %d events have been removed from the queue\n",event.fWindow,nRemoved );
    #endif
                }
                // else fprintf(stderr, "TQUserEvent: %p  %d %d\n", event.fWindow, event.fType, kClientMessage);
             } else {
                delete &event;
                if (filterTime) filterTime->Stop();
                return kFALSE;  // We need the standard Qt processing
             }

            // GUI event types. Later merge with EEventType in Button.h and rename to
            // EEventTypes. Also rename in that case kGKeyPress to kKeyPress.
            //enum EGEventType {
            //   kClientMessage, kSelectionClear, kSelectionRequest, kSelectionNotify,
            //   kColormapNotify
            //};
           break;
       };
       qApp->lock();
       bool justInit =  false;
       if (!fRootEventQueue) {
          fRootEventQueue = new TQtEventQueue();
          // send message to another thread
          justInit = true;
       }

       if ( grabEvent || ((TQtClientWidget*)(TGQt::wid(event.fWindow)))->IsEventSelected(selectEventMask) )
       {
    //---------------------------------------------------------------------------
    //    QT message has been mapped to ROOT one and ready to be shipped out
    //---------------------------------------------------------------------------
          fRootEventQueue->enqueue(&event);
    //---------------------------------------------------------------------------
       } else {
          delete &event;
          if (filterTime) filterTime->Stop();
          return kFALSE;  // We need the standard Qt processing
       }

    #ifdef R__QTGUITHREAD
       if (!fNotifyClient) fNotifyClient = new TQtNextEventMessage();
       if (justInit) {
          justInit = false;
          fNotifyClient->ExecCommandThread();
       }
       else {
          //fprintf(stderr,"TQtClientFilter::eventFilter %d %s\n", fRootEventQueue->count(),
          //   (const char *)qWidget->name());
       }
    #else
       // gSystem->DispatchOneEvent(kTRUE);
    #endif
       qApp->unlock();
       // We should hold ALL events because we want to process them themsleves.
       // However non-accepted mouse event should be propagated further
       if (mouseEvent && !mouseEvent->isAccepted () ) return kFALSE;
       if (keyEvent   && !keyEvent->isAccepted ()   ) return kFALSE;
       if (focusEvent                               ) return kFALSE;
       switch (e->type() ) {
          case QEvent::Show:                 // Widget was shown on screen,
          case QEvent::ShowWindowRequest:    //  (obsolete)  widget's window should be mapped
          case QEvent::Hide:                //   widget's window should be unmapped
             if (filterTime) filterTime->Stop();
             return kFALSE;
          default: break;
    //      case QEvent::Paint:                //   widget's window should be mapped
       };
     // }
      return frame->GetCanvasWidget()==0;
     //  return kTRUE; // eat event. We want the special processing via TGClient
     // fClient?fClient->ProcessOneEvent(event):kFALSE;
    }

    //______________________________________________________________________________
     void TQtClientFilter::AppendPointerGrab(TQtClientWidget *widget)
    {
       if (fPointerGrabber) RemovePointerGrab(fPointerGrabber);
       fPointerGrabber = widget;
       connect(widget,SIGNAL(destroyed(QObject *)),this,SLOT(RemovePointerGrab(QObject *)));
    }
    //______________________________________________________________________________
     void TQtClientFilter::RemovePointerGrab(QObject *widget)
    {
       if (!widget && fPointerGrabber ) fPointerGrabber->UnSetPointerMask();
       else if (widget) {
          fPointerGrabber = 0;
          disconnect(widget,SIGNAL(destroyed(QObject *)),this,SLOT(RemovePointerGrab(QObject *)));
       }
    }