TGClient.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGClient.cxx 35622 2010-09-23 08:29:15Z bellenot $
00002 // Author: Fons Rademakers   27/12/97
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 /**************************************************************************
00012 
00013     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGClient                                                             //
00026 //                                                                      //
00027 // Window client. In client server windowing systems, like X11 this     //
00028 // class is used to make the initial connection to the window server.   //
00029 //                                                                      //
00030 //////////////////////////////////////////////////////////////////////////
00031 
00032 #include "RConfigure.h"
00033 
00034 #include "TGClient.h"
00035 #include "TROOT.h"
00036 #include "TApplication.h"
00037 #include "TSystem.h"
00038 #include "TEnv.h"
00039 #include "THashList.h"
00040 #include "TSysEvtHandler.h"
00041 #include "TVirtualX.h"
00042 #include "TGWindow.h"
00043 #include "TGResourcePool.h"
00044 #include "TGGC.h"
00045 #include "TGFont.h"
00046 #include "TGMimeTypes.h"
00047 #include "TGFrame.h"
00048 #include "TGIdleHandler.h"
00049 
00050 
00051 // Global pointer to the TGClient object
00052 TGClient *gClient = 0;
00053 
00054 // Initialize gClient in case libGui is loaded in batch mode
00055 extern "C" void G__cpp_setup_tagtableG__Gui1();
00056 class TGClientInit {
00057 public:
00058    TGClientInit() { 
00059       if (gROOT && gROOT->IsBatch()) {
00060          // Insure that the CINT dictionary is initialized __before__ the TGClient creation which
00061          // will induce the creation of a TClass object which will need the dictionary for TGClient!
00062          G__cpp_setup_tagtableG__Gui1(); 
00063          new TGClient();
00064       }
00065       TApplication::NeedGraphicsLibs(); 
00066    }
00067 };
00068 static TGClientInit gClientInit;
00069 
00070 
00071 //----- Graphics Input handler -------------------------------------------------
00072 //______________________________________________________________________________
00073 class TGInputHandler : public TFileHandler {
00074 private:
00075    TGClient  *fClient;   // connection to display server
00076 public:
00077    TGInputHandler(TGClient *c, Int_t fd) : TFileHandler(fd, 1) { fClient = c; }
00078    Bool_t Notify();
00079    // Important: don't override ReadNotify()
00080 };
00081 
00082 //______________________________________________________________________________
00083 Bool_t TGInputHandler::Notify()
00084 {
00085    // Notify input from the display server.
00086 
00087    return fClient->HandleInput();
00088 }
00089 
00090 
00091 ClassImp(TGClient)
00092 
00093 //______________________________________________________________________________
00094 TGClient::TGClient(const char *dpyName)
00095 {
00096    // Create a connection with the display sever on host dpyName and setup
00097    // the complete GUI system, i.e., graphics contexts, fonts, etc. for all
00098    // widgets.
00099 
00100    fRoot         = 0;
00101    fPicturePool  = 0;
00102    fMimeTypeList = 0;
00103    fWlist        = 0;
00104    fPlist        = 0;
00105    fUWHandlers   = 0;
00106    fIdleHandlers = 0;
00107 
00108    if (gClient) {
00109       Error("TGClient", "only one instance of TGClient allowed");
00110       MakeZombie();
00111       return;
00112    }
00113 
00114    // Set DISPLAY based on utmp (only if DISPLAY is not yet set).
00115    gSystem->SetDisplay();
00116 
00117    // Open the connection to the display
00118    if ((fXfd = gVirtualX->OpenDisplay(dpyName)) < 0) {
00119       Error("TGClient", "can't open display \"%s\", switching to batch mode...\n In case you run from a remote ssh session, reconnect with ssh -Y",
00120             gVirtualX->DisplayName(dpyName));
00121       MakeZombie();
00122       return;
00123    }
00124 
00125    if (fXfd >= 0 && !gROOT->IsBatch()) {
00126       TGInputHandler *xi = new TGInputHandler(this, fXfd);
00127       if (fXfd) gSystem->AddFileHandler(xi);
00128       // X11 events are handled via gXDisplay->Notify() in
00129       // TUnixSystem::DispatchOneEvent(). When no events available we wait for
00130       // events on all TFileHandlers including this one via a select() call.
00131       // However, X11 events are always handled via gXDisplay->Notify() and not
00132       // via the ReadNotify() (therefore TGInputHandler should not override
00133       // TFileHandler::ReadNotify()).
00134       gXDisplay = xi;
00135    }
00136 
00137    // Initialize internal window list. Use a THashList for fast
00138    // finding of windows based on window id (see GetWindowById()).
00139 
00140    fWlist = new THashList(200);
00141    fPlist = new TList;
00142 
00143    // Create root window
00144 
00145    fDefaultRoot = fRoot = new TGFrame(this, gVirtualX->GetDefaultRootWindow());
00146 
00147    // Setup some atoms (defined in TVirtualX)...
00148 
00149    gWM_DELETE_WINDOW = gVirtualX->InternAtom("WM_DELETE_WINDOW", kFALSE);
00150    gMOTIF_WM_HINTS   = gVirtualX->InternAtom("_MOTIF_WM_HINTS", kFALSE);
00151    gROOT_MESSAGE     = gVirtualX->InternAtom("_ROOT_MESSAGE", kFALSE);
00152 
00153    // Create the graphics event handler, an object for the root window,
00154    // a picture pool, mimetype list, etc...
00155 
00156    fGlobalNeedRedraw = kFALSE;
00157    fForceRedraw      = kFALSE;
00158    fWaitForWindow    = kNone;
00159    fWaitForEvent     = kOtherEvent;
00160 
00161    fResourcePool    = new TGResourcePool(this);
00162 
00163    fPicturePool     = fResourcePool->GetPicturePool();
00164    fGCPool          = fResourcePool->GetGCPool();
00165    fFontPool        = fResourcePool->GetFontPool();
00166 
00167    fMimeTypeList    = fResourcePool->GetMimeTypes();
00168    fDefaultColormap = fResourcePool->GetDefaultColormap();
00169 
00170    // Set some color defaults...
00171 
00172    fWhite        = fResourcePool->GetWhiteColor();
00173    fBlack        = fResourcePool->GetBlackColor();
00174    fBackColor    = fResourcePool->GetFrameBgndColor();
00175    fForeColor    = fResourcePool->GetFrameFgndColor();
00176    fHilite       = GetHilite(fBackColor);
00177    fShadow       = GetShadow(fBackColor);
00178    fSelForeColor = fResourcePool->GetSelectedFgndColor();
00179    fSelBackColor = fResourcePool->GetSelectedBgndColor();
00180 
00181    gClient = this;
00182 }
00183 
00184 //______________________________________________________________________________
00185 const TGWindow *TGClient::GetRoot() const
00186 {
00187    // Returns current root (i.e. base) window. By changing the root
00188    // window one can change the window hierarchy, e.g. a top level
00189    // frame (TGMainFrame) can be embedded in another window.
00190 
00191    return fRoot;
00192 }
00193 
00194 //______________________________________________________________________________
00195 const TGWindow *TGClient::GetDefaultRoot() const
00196 {
00197    // Returns the root (i.e. desktop) window. Should only be used as parent
00198    // for frames that will never be embedded, like popups, message boxes,
00199    // etc. (like TGToolTips, TGMessageBox, etc.).
00200 
00201    return fDefaultRoot;
00202 }
00203 
00204 //______________________________________________________________________________
00205 void TGClient::SetRoot(TGWindow *root)
00206 {
00207    // Sets the current root (i.e. base) window. By changing the root
00208    // window one can change the window hierarchy, e.g. a top level
00209    // frame (TGMainFrame) can be embedded in another window.
00210 
00211    fRoot = root ? root : fDefaultRoot;
00212 }
00213 
00214 //______________________________________________________________________________
00215 UInt_t TGClient::GetDisplayWidth() const
00216 {
00217    // Get display width.
00218 
00219    Int_t  x, y;
00220    UInt_t w, h;
00221 
00222    gVirtualX->GetGeometry(-1, x, y, w, h);
00223 
00224    return w;
00225 }
00226 
00227 //______________________________________________________________________________
00228 UInt_t TGClient::GetDisplayHeight() const
00229 {
00230    // Get display height.
00231 
00232    Int_t  x, y;
00233    UInt_t w, h;
00234 
00235    gVirtualX->GetGeometry(-1, x, y, w, h);
00236 
00237    return h;
00238 }
00239 
00240 //______________________________________________________________________________
00241 const TGPicture *TGClient::GetPicture(const char *name)
00242 {
00243    // Get picture from the picture pool. Picture must be freed using
00244    // TGClient::FreePicture(). If picture is not found 0 is returned.
00245 
00246    return fPicturePool->GetPicture(name);
00247 }
00248 
00249 //______________________________________________________________________________
00250 const TGPicture *TGClient::GetPicture(const char *name,
00251                                       UInt_t new_width, UInt_t new_height)
00252 {
00253    // Get picture with specified size from pool (picture will be scaled if
00254    // necessary). Picture must be freed using TGClient::FreePicture(). If
00255    // picture is not found 0 is returned.
00256 
00257    return fPicturePool->GetPicture(name, new_width, new_height);
00258 }
00259 
00260 //______________________________________________________________________________
00261 void TGClient::FreePicture(const TGPicture *pic)
00262 {
00263    // Free picture resource.
00264 
00265    if (pic) fPicturePool->FreePicture(pic);
00266 }
00267 
00268 //______________________________________________________________________________
00269 TGGC *TGClient::GetGC(GCValues_t *values, Bool_t rw)
00270 {
00271    // Get graphics context from the gc pool. Context must be freed via
00272    // TGClient::FreeGC(). If rw is true a new read/write-able GC
00273    // is returned, otherwise a shared read-only context is returned.
00274    // For historical reasons it is also possible to create directly a
00275    // TGGC object, but it is advised to use this new interface only.
00276 
00277    return fGCPool->GetGC(values, rw);
00278 }
00279 
00280 //______________________________________________________________________________
00281 void TGClient::FreeGC(const TGGC *gc)
00282 {
00283    // Free a graphics context.
00284 
00285    fGCPool->FreeGC(gc);
00286 }
00287 
00288 //______________________________________________________________________________
00289 void TGClient::FreeGC(GContext_t gc)
00290 {
00291    // Free a graphics context.
00292 
00293    fGCPool->FreeGC(gc);
00294 }
00295 
00296 //______________________________________________________________________________
00297 TGFont *TGClient::GetFont(const char *font, Bool_t fixedDefault)
00298 {
00299    // Get a font from the font pool. Fonts must be freed via
00300    // TGClient::FreeFont(). Returns 0 in case of error or if font
00301    // does not exist. If fixedDefault is false the "fixed" font
00302    // will not be substituted as fallback when the asked for font
00303    // does not exist.
00304 
00305    return fFontPool->GetFont(font, fixedDefault);
00306 }
00307 
00308 //______________________________________________________________________________
00309 TGFont *TGClient::GetFont(const TGFont *font)
00310 {
00311    // Get again specified font. Will increase its usage count.
00312 
00313    return fFontPool->GetFont(font);
00314 }
00315 
00316 //______________________________________________________________________________
00317 void TGClient::FreeFont(const TGFont *font)
00318 {
00319    // Free a font.
00320 
00321    fFontPool->FreeFont(font);
00322 }
00323 
00324 //______________________________________________________________________________
00325 void TGClient::NeedRedraw(TGWindow *w, Bool_t force)
00326 {
00327    // Set redraw flags.
00328    if (gVirtualX->NeedRedraw((ULong_t)w,force)) return;
00329    if (force) {
00330       w->DoRedraw();
00331       return;
00332    }
00333    w->fNeedRedraw = kTRUE;
00334    fGlobalNeedRedraw = kTRUE;
00335 }
00336 
00337 //______________________________________________________________________________
00338 Bool_t TGClient::GetColorByName(const char *name, Pixel_t &pixel) const
00339 {
00340    // Get a color by name. If color is found return kTRUE and pixel is
00341    // set to the color's pixel value, kFALSE otherwise.
00342 
00343    ColorStruct_t      color;
00344    WindowAttributes_t attributes = WindowAttributes_t();
00345    Bool_t             status = kTRUE;
00346 
00347    gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
00348    color.fPixel = 0;
00349    if (!gVirtualX->ParseColor(attributes.fColormap, name, color)) {
00350       Error("GetColorByName", "couldn't parse color %s", name);
00351       status = kFALSE;
00352    } else if (!gVirtualX->AllocColor(attributes.fColormap, color)) {
00353       Warning("GetColorByName", "couldn't retrieve color %s.\n"
00354               "Please close any other application, like netscape, "
00355               "that might exhaust\nthe colormap and start ROOT again", name);
00356       status = kFALSE;
00357    }
00358 
00359    pixel = color.fPixel;
00360 
00361    return status;
00362 }
00363 
00364 //______________________________________________________________________________
00365 FontStruct_t TGClient::GetFontByName(const char *name, Bool_t fixedDefault) const
00366 {
00367    // Get a font by name. If font is not found, fixed font is returned,
00368    // if fixed font also does not exist return 0 and print error.
00369    // The loaded font needs to be freed using TVirtualX::DeleteFont().
00370    // If fixedDefault is false the "fixed" font will not be substituted
00371    // as fallback when the asked for font does not exist.
00372 
00373    if (gROOT->IsBatch())
00374       return (FontStruct_t) -1;
00375 
00376    FontStruct_t font = gVirtualX->LoadQueryFont(name);
00377 
00378    if (!font && fixedDefault) {
00379       font = gVirtualX->LoadQueryFont("fixed");
00380       if (font)
00381          Warning("GetFontByName", "couldn't retrieve font %s, using \"fixed\"", name);
00382    }
00383    if (!font) {
00384       if (fixedDefault)
00385          Error("GetFontByName", "couldn't retrieve font %s nor backup font \"fixed\"", name);
00386       else
00387          Warning("GetFontByName", "couldn't retrieve font %s", name);
00388    }
00389 
00390    return font;
00391 }
00392 
00393 //______________________________________________________________________________
00394 Pixel_t TGClient::GetHilite(Pixel_t base_color) const
00395 {
00396    // Return pixel value of hilite color based on base_color.
00397 
00398    ColorStruct_t      color, white_p;
00399    WindowAttributes_t attributes = WindowAttributes_t();
00400 
00401    gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
00402 
00403    color.fPixel = base_color;
00404    gVirtualX->QueryColor(attributes.fColormap, color);
00405 
00406    GetColorByName("white", white_p.fPixel);
00407    gVirtualX->QueryColor(attributes.fColormap, white_p);
00408 
00409    color.fRed   = TMath::Max((UShort_t)(white_p.fRed/5),   color.fRed);
00410    color.fGreen = TMath::Max((UShort_t)(white_p.fGreen/5), color.fGreen);
00411    color.fBlue  = TMath::Max((UShort_t)(white_p.fBlue/5),  color.fBlue);
00412 
00413    color.fRed   = (UShort_t)TMath::Min((Int_t)white_p.fRed,   (Int_t)(color.fRed*140)/100);
00414    color.fGreen = (UShort_t)TMath::Min((Int_t)white_p.fGreen, (Int_t)(color.fGreen*140)/100);
00415    color.fBlue  = (UShort_t)TMath::Min((Int_t)white_p.fBlue,  (Int_t)(color.fBlue*140)/100);
00416 
00417    if (!gVirtualX->AllocColor(attributes.fColormap, color))
00418       Error("GetHilite", "couldn't allocate hilight color");
00419 
00420    return color.fPixel;
00421 }
00422 
00423 //______________________________________________________________________________
00424 Pixel_t TGClient::GetShadow(Pixel_t base_color) const
00425 {
00426    // Return pixel value of shadow color based on base_color.
00427    // Shadow is 60% of base_color intensity.
00428 
00429    ColorStruct_t      color;
00430    WindowAttributes_t attributes = WindowAttributes_t();
00431 
00432    gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
00433 
00434    color.fPixel = base_color;
00435    gVirtualX->QueryColor(attributes.fColormap, color);
00436 
00437    color.fRed   = (UShort_t)((color.fRed*60)/100);
00438    color.fGreen = (UShort_t)((color.fGreen*60)/100);
00439    color.fBlue  = (UShort_t)((color.fBlue*60)/100);
00440 
00441    if (!gVirtualX->AllocColor(attributes.fColormap, color))
00442       Error("GetShadow", "couldn't allocate shadow color");
00443 
00444    return color.fPixel;
00445 }
00446 
00447 //______________________________________________________________________________
00448 void TGClient::FreeColor(Pixel_t color) const
00449 {
00450    // Free color.
00451 
00452    gVirtualX->FreeColor(fDefaultColormap, color);
00453 }
00454 
00455 //______________________________________________________________________________
00456 void TGClient::RegisterWindow(TGWindow *w)
00457 {
00458    // Add a TGWindow to the clients list of windows.
00459 
00460    fWlist->Add(w);
00461 
00462    // Emits signal
00463    RegisteredWindow(w->GetId());
00464 }
00465 
00466 //______________________________________________________________________________
00467 void TGClient::UnregisterWindow(TGWindow *w)
00468 {
00469    // Remove a TGWindow from the list of windows.
00470 
00471    fWlist->Remove(w);
00472 }
00473 
00474 //______________________________________________________________________________
00475 void TGClient::RegisterPopup(TGWindow *w)
00476 {
00477    // Add a popup menu to the list of popups. This list is used to pass
00478    // events to popup menus that are popped up over a transient window which
00479    // is waited for (see WaitFor()).
00480 
00481    fPlist->Add(w);
00482 
00483    // Emits signal
00484    RegisteredWindow(w->GetId());
00485 }
00486 
00487 //______________________________________________________________________________
00488 void TGClient::UnregisterPopup(TGWindow *w)
00489 {
00490    // Remove a popup menu from the list of popups.
00491 
00492    fPlist->Remove(w);
00493 }
00494 
00495 //______________________________________________________________________________
00496 void TGClient::AddUnknownWindowHandler(TGUnknownWindowHandler *h)
00497 {
00498    // Add handler for unknown (i.e. unregistered) windows.
00499 
00500    if (!fUWHandlers) {
00501       fUWHandlers = new TList;
00502       fUWHandlers->SetOwner();
00503    }
00504 
00505    fUWHandlers->Add(h);
00506 }
00507 
00508 //______________________________________________________________________________
00509 void TGClient::RemoveUnknownWindowHandler(TGUnknownWindowHandler *h)
00510 {
00511    // Remove handler for unknown (i.e. unregistered) windows.
00512 
00513    fUWHandlers->Remove(h);
00514 }
00515 
00516 //______________________________________________________________________________
00517 void TGClient::AddIdleHandler(TGIdleHandler *h)
00518 {
00519    // Add handler for idle events.
00520 
00521    if (!fIdleHandlers) {
00522       fIdleHandlers = new TList;
00523       fIdleHandlers->SetOwner();
00524    }
00525 
00526    fIdleHandlers->Add(h);
00527 }
00528 
00529 //______________________________________________________________________________
00530 void TGClient::RemoveIdleHandler(TGIdleHandler *h)
00531 {
00532    // Remove handler for idle events.
00533 
00534    fIdleHandlers->Remove(h);
00535 }
00536 
00537 //______________________________________________________________________________
00538 TGWindow *TGClient::GetWindowById(Window_t wid) const
00539 {
00540    // Find a TGWindow via its handle. If window is not found return 0.
00541 
00542    TGWindow  wt(wid);
00543 
00544    return (TGWindow *) fWlist->FindObject(&wt);
00545 }
00546 
00547 //______________________________________________________________________________
00548 TGWindow *TGClient::GetWindowByName(const char *name) const
00549 {
00550    // Find a TGWindow via its name (unique name used in TGWindow::SavePrimitive).
00551    // If window is not found return 0.
00552 
00553    TIter next(fWlist);
00554 
00555    TObject *obj;
00556    while ((obj = next())) {
00557       TString n = obj->GetName();
00558       if (n == name) {
00559          return (TGWindow*)obj;
00560       }
00561    }
00562    return 0;
00563 }
00564 
00565 //______________________________________________________________________________
00566 TGClient::~TGClient()
00567 {
00568    // Closing down client: cleanup and close X connection.
00569 
00570    if (IsZombie())
00571       return;
00572 
00573    if (fWlist)
00574       fWlist->Delete("slow");
00575    delete fWlist;
00576    delete fPlist;
00577    delete fUWHandlers;
00578    delete fIdleHandlers;
00579    delete fResourcePool;
00580 
00581    gVirtualX->CloseDisplay(); // this should do a cleanup of the remaining
00582                               // X allocated objects...
00583 }
00584 
00585 //______________________________________________________________________________
00586 Bool_t TGClient::ProcessOneEvent()
00587 {
00588    // Process one event. This method should only be called when there is
00589    // a GUI event ready to be processed. If event has been processed
00590    // kTRUE is returned. If processing of a specific event type for a specific
00591    // window was requested kFALSE is returned when specific event has been
00592    // processed, kTRUE otherwise. If no more pending events return kFALSE.
00593 
00594    Event_t event;
00595 
00596    if (!fRoot) return kFALSE;
00597    if (gVirtualX->EventsPending()) {
00598       gVirtualX->NextEvent(event);
00599       if (fWaitForWindow == kNone) {
00600          HandleEvent(&event);
00601          if (fForceRedraw)
00602             DoRedraw();
00603          return kTRUE;
00604       } else {
00605          HandleMaskEvent(&event, fWaitForWindow);
00606          if ((event.fType == fWaitForEvent) && (event.fWindow == fWaitForWindow))
00607             fWaitForWindow = kNone;
00608          if (fForceRedraw)
00609             DoRedraw();
00610          return kTRUE;
00611       }
00612    }
00613 
00614    // if nothing else to do redraw windows that need redrawing
00615    if (DoRedraw()) return kTRUE;
00616 
00617    // process one idle event if there is nothing else to do
00618    if (ProcessIdleEvent()) return kTRUE;
00619 
00620    return kFALSE;
00621 }
00622 
00623 //______________________________________________________________________________
00624 Bool_t TGClient::ProcessIdleEvent()
00625 {
00626    // Process one idle event.
00627 
00628    if (fIdleHandlers) {
00629       TGIdleHandler *ih = (TGIdleHandler *) fIdleHandlers->First();
00630       if (ih) {
00631          RemoveIdleHandler(ih);
00632          ih->HandleEvent();
00633          return kTRUE;
00634       }
00635    }
00636    return kFALSE;
00637 }
00638 
00639 //______________________________________________________________________________
00640 Bool_t TGClient::HandleInput()
00641 {
00642    // Handles input from the display server. Returns kTRUE if one or more
00643    // events have been processed, kFALSE otherwise.
00644 
00645    Bool_t handledevent = kFALSE;
00646 
00647    while (ProcessOneEvent())
00648       handledevent = kTRUE;
00649    return handledevent;
00650 }
00651 
00652 //______________________________________________________________________________
00653 void TGClient::WaitFor(TGWindow *w)
00654 {
00655    // Wait for window to be destroyed.
00656 
00657    Window_t wsave    = fWaitForWindow;
00658    EGEventType esave = fWaitForEvent;
00659 
00660    fWaitForWindow = w->GetId();
00661    fWaitForEvent  = kDestroyNotify;
00662 
00663    while (fWaitForWindow != kNone) {
00664       if (esave == kUnmapNotify)
00665          wsave = kNone;
00666       gSystem->ProcessEvents();//gSystem->InnerLoop();
00667       gSystem->Sleep(5);
00668    }
00669 
00670    fWaitForWindow = wsave;
00671    fWaitForEvent  = esave;
00672 }
00673 
00674 //______________________________________________________________________________
00675 void TGClient::WaitForUnmap(TGWindow *w)
00676 {
00677    // Wait for window to be unmapped.
00678 
00679    Window_t wsave    = fWaitForWindow;
00680    EGEventType esave = fWaitForEvent;
00681 
00682    fWaitForWindow = w->GetId();
00683    fWaitForEvent  = kUnmapNotify;
00684 
00685    while (fWaitForWindow != kNone) {
00686       gSystem->ProcessEvents();//gSystem->InnerLoop();
00687       gSystem->Sleep(5);
00688    }
00689 
00690    fWaitForWindow = wsave;
00691    fWaitForEvent  = esave;
00692 }
00693 
00694 //______________________________________________________________________________
00695 void TGClient::ResetWaitFor(TGWindow *w)
00696 {
00697    // reset waiting
00698 
00699    if (fWaitForWindow == w->GetId()) fWaitForWindow = kNone;
00700 }
00701 
00702 //______________________________________________________________________________
00703 Bool_t TGClient::ProcessEventsFor(TGWindow *w)
00704 {
00705    // Like gSystem->ProcessEvents() but then only allow events for w to
00706    // be processed. For example to interrupt the processing and destroy
00707    // the window, call gROOT->SetInterrupt() before destroying the window.
00708 
00709    Window_t wsave    = fWaitForWindow;
00710    EGEventType esave = fWaitForEvent;
00711 
00712    fWaitForWindow = w->GetId();
00713    fWaitForEvent  = kDestroyNotify;
00714 
00715    Bool_t intr = gSystem->ProcessEvents();
00716 
00717    fWaitForWindow = wsave;
00718    fWaitForEvent  = esave;
00719 
00720    return intr;
00721 }
00722 
00723 //______________________________________________________________________________
00724 Bool_t TGClient::DoRedraw()
00725 {
00726    // Redraw all windows that need redrawing. Returns kFALSE if no redraw
00727    // was needed, kTRUE otherwise.
00728    // Only redraw the application's windows when the event queue
00729    // does not contain expose event anymore.
00730 
00731    if (!fGlobalNeedRedraw) return kFALSE;
00732 
00733    TGWindow *w;
00734    TObjLink *lnk = fWlist->FirstLink();
00735    while (lnk) {
00736       w = (TGWindow *) lnk->GetObject();
00737       if (w->fNeedRedraw) {
00738          w->DoRedraw();
00739          w->fNeedRedraw = kFALSE;
00740       }
00741       lnk = lnk->Next();
00742    }
00743 
00744    fGlobalNeedRedraw = kFALSE;
00745    fForceRedraw      = kFALSE;
00746 
00747    return kTRUE;
00748 }
00749 
00750 //______________________________________________________________________________
00751 Bool_t TGClient::HandleEvent(Event_t *event)
00752 {
00753    // Handle a GUI event.
00754 
00755    TGWindow *w;
00756 
00757    // Emit signal for event recorder(s)
00758    if (event->fType != kConfigureNotify) {
00759       ProcessedEvent(event, 0);
00760    }
00761 
00762    // Find window where event happened
00763    if ((w = GetWindowById(event->fWindow)) == 0) {
00764       if (fUWHandlers && fUWHandlers->GetSize() > 0) {
00765          TGUnknownWindowHandler *unkwh;
00766          TListIter it(fUWHandlers);
00767          while ((unkwh = (TGUnknownWindowHandler*)it.Next())) {
00768             if (unkwh->HandleEvent(event))
00769                return kTRUE;
00770          }
00771       }
00772       //Warning("HandleEvent", "unknown window %ld not handled\n",
00773       //        event->fWindow);
00774       return kFALSE;
00775    }
00776 
00777    // and let it handle the event
00778    w->HandleEvent(event);
00779 
00780    return kTRUE;
00781 }
00782 
00783 //______________________________________________________________________________
00784 Bool_t TGClient::HandleMaskEvent(Event_t *event, Window_t wid)
00785 {
00786    // Handle masked events only if window wid is the window for which the
00787    // event was reported or if wid is a parent of the event window. The not
00788    // masked event are handled directly. The masked events are:
00789    // kButtonPress, kButtonRelease, kKeyPress, kKeyRelease, kEnterNotify,
00790    // kLeaveNotify, kMotionNotify.
00791 
00792    TGWindow *w, *ptr, *pop;
00793 
00794    if ((w = GetWindowById(event->fWindow)) == 0) return kFALSE;
00795 
00796    // Emit signal for event recorder(s)
00797    if (event->fType != kConfigureNotify) {
00798       ProcessedEvent(event, wid);
00799    }
00800 
00801    // This breaks class member protection, but TGClient is a friend of
00802    // TGWindow and _should_ know what to do and what *not* to do...
00803 
00804    for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
00805       if ((ptr->fId == wid) ||
00806           ((event->fType != kButtonPress) &&
00807            (event->fType != kButtonRelease) &&
00808            (event->fType != kGKeyPress) &&
00809            (event->fType != kKeyRelease) &&
00810            (event->fType != kEnterNotify) &&
00811            (event->fType != kLeaveNotify) &&
00812            (event->fType != kMotionNotify))) {
00813          w->HandleEvent(event);
00814          return kTRUE;
00815       }
00816    }
00817 
00818    // check if this is a popup menu
00819    TIter next(fPlist);
00820    while ((pop = (TGWindow *) next())) {
00821       for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
00822          if ((ptr->fId == pop->fId) &&
00823              ((event->fType == kButtonPress) ||
00824               (event->fType == kButtonRelease) ||
00825               (event->fType == kGKeyPress) ||
00826               (event->fType == kKeyRelease) ||
00827               (event->fType == kEnterNotify) ||
00828               (event->fType == kLeaveNotify) ||
00829               (event->fType == kMotionNotify))) {
00830             w->HandleEvent(event);
00831             return kTRUE;
00832          }
00833       }
00834    }
00835 
00836    if (event->fType == kButtonPress || event->fType == kGKeyPress)
00837       gVirtualX->Bell(0);
00838 
00839    return kFALSE;
00840 }
00841 
00842 //______________________________________________________________________________
00843 void TGClient::ProcessLine(TString cmd, Long_t msg, Long_t parm1, Long_t parm2)
00844 {
00845    // Execute string "cmd" via the interpreter. Before executing replace
00846    // in the command string the token $MSG, $PARM1 and $PARM2 by msg,
00847    // parm1 and parm2, respectively. The function in cmd string must accept
00848    // these as longs.
00849 
00850    if (cmd.IsNull()) return;
00851 
00852    char s[32];
00853 
00854    snprintf(s, sizeof(s), "%ld", msg);
00855    cmd.ReplaceAll("$MSG", s);
00856 
00857    snprintf(s, sizeof(s), "%ld", parm1);
00858    cmd.ReplaceAll("$PARM1", s);
00859 
00860    snprintf(s, sizeof(s), "%ld", parm2);
00861    cmd.ReplaceAll("$PARM2", s);
00862 
00863    gROOT->ProcessLine(cmd.Data());
00864 }
00865 
00866 //______________________________________________________________________________
00867 Bool_t TGClient::IsEditDisabled() const
00868 {
00869    // Returns kTRUE if edit/guibuilding is forbidden.
00870 
00871    return (fDefaultRoot->GetEditDisabled() == 1);
00872 }
00873 
00874 //______________________________________________________________________________
00875 void TGClient::SetEditDisabled(Bool_t on)
00876 {
00877    // If on is kTRUE editting/guibuilding is forbidden.
00878 
00879    fDefaultRoot->SetEditDisabled(on);
00880 }
00881 
00882 //______________________________________________________________________________
00883 void TGClient::ProcessedEvent(Event_t *event, Window_t wid)
00884 {
00885    // Emits a signal when an event has been processed.
00886    // Used in TRecorder.
00887 
00888    Long_t args[2];
00889    args[0] = (Long_t) event;
00890    args[1] = (Long_t) wid;
00891 
00892    Emit("ProcessedEvent(Event_t*, Window_t)", args);
00893 }
00894 
00895 //______________________________________________________________________________
00896 void TGClient::RegisteredWindow(Window_t w)
00897 {
00898    // Emits a signal when a Window has been registered in TGClient.
00899    // Used in TRecorder.
00900 
00901    Emit("RegisteredWindow(Window_t)", w);
00902 }

Generated on Tue Jul 5 14:21:57 2011 for ROOT_528-00b_version by  doxygen 1.5.1