Logo ROOT   6.10/09
Reference Guide
TGClient.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 27/12/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 /**************************************************************************
12 
13  This source is based on Xclass95, a Win95-looking GUI toolkit.
14  Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15 
16  Xclass95 is free software; you can redistribute it and/or
17  modify it under the terms of the GNU Library General Public
18  License as published by the Free Software Foundation; either
19  version 2 of the License, or (at your option) any later version.
20 
21 **************************************************************************/
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGClient //
26 // //
27 // Window client. In client server windowing systems, like X11 this //
28 // class is used to make the initial connection to the window server. //
29 // //
30 //////////////////////////////////////////////////////////////////////////
31 
32 #include "RConfigure.h"
33 
34 #include "TGClient.h"
35 #include "TROOT.h"
36 #include "TApplication.h"
37 #include "TSystem.h"
38 #include "TEnv.h"
39 #include "THashList.h"
40 #include "TSysEvtHandler.h"
41 #include "TVirtualX.h"
42 #include "TGWindow.h"
43 #include "TGResourcePool.h"
44 #include "TGGC.h"
45 #include "TGFont.h"
46 #include "TGMimeTypes.h"
47 #include "TGFrame.h"
48 #include "TGIdleHandler.h"
49 #include "TError.h"
50 #include "TGlobal.h"
51 
52 // Global pointer to the TGClient object
53 static TGClient *gClientGlobal = 0;
54 
55 namespace {
56 static struct AddPseudoGlobals {
57 AddPseudoGlobals() {
58  // User "gCling" as synonym for "libCore static initialization has happened".
59  // This code here must not trigger it.
60  TGlobalMappedFunction::Add(new TGlobalMappedFunction("gClient", "TGClient*",
62 }
63 } gAddPseudoGlobals;
64 }
65 
66 // Initialize gClient in case libGui is loaded in batch mode
68 class TGClientInit {
69 public:
70  TGClientInit() {
71  TROOT *rootlocal = ROOT::Internal::gROOTLocal;
72  if (rootlocal && rootlocal->IsBatch()) {
73  // For now check if the heaeder files (or the module containing them)
74  // has been loaded in Cling.
75  // This is required because the dictionaries must be initialized
76  // __before__ the TGClient creation which will induce the creation
77  // of a TClass object which will need the dictionary for TGClient!
79  new TGClient();
80  }
82  }
83 };
84 static TGClientInit gClientInit;
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Returns global gClient (initialize graphics first, if not already done)
88 
90 {
91  if (!gClientGlobal && gApplication)
93  return gClientGlobal;
94 }
95 
96 //----- Graphics Input handler -------------------------------------------------
97 ////////////////////////////////////////////////////////////////////////////////
98 
99 class TGInputHandler : public TFileHandler {
100 private:
101  TGClient *fClient; // connection to display server
102 public:
103  TGInputHandler(TGClient *c, Int_t fd) : TFileHandler(fd, 1) { fClient = c; }
104  Bool_t Notify();
105  // Important: don't override ReadNotify()
106 };
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Notify input from the display server.
110 
111 Bool_t TGInputHandler::Notify()
112 {
113  return fClient->HandleInput();
114 }
115 
116 
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Create a connection with the display sever on host dpyName and setup
121 /// the complete GUI system, i.e., graphics contexts, fonts, etc. for all
122 /// widgets.
123 
124 TGClient::TGClient(const char *dpyName)
125 {
126  fRoot = 0;
127  fPicturePool = 0;
128  fMimeTypeList = 0;
129  fWlist = 0;
130  fPlist = 0;
131  fUWHandlers = 0;
132  fIdleHandlers = 0;
133 
134  if (gClientGlobal) {
135  Error("TGClient", "only one instance of TGClient allowed");
136  MakeZombie();
137  return;
138  }
139 
140  // Set DISPLAY based on utmp (only if DISPLAY is not yet set).
141  gSystem->SetDisplay();
142 
143  // Open the connection to the display
144  if ((fXfd = gVirtualX->OpenDisplay(dpyName)) < 0) {
145  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",
146  gVirtualX->DisplayName(dpyName));
147  MakeZombie();
148  return;
149  }
150 
151  if (fXfd >= 0 && !ROOT::Internal::gROOTLocal->IsBatch()) {
152  TGInputHandler *xi = new TGInputHandler(this, fXfd);
153  if (fXfd) gSystem->AddFileHandler(xi);
154  // X11 events are handled via gXDisplay->Notify() in
155  // TUnixSystem::DispatchOneEvent(). When no events available we wait for
156  // events on all TFileHandlers including this one via a select() call.
157  // However, X11 events are always handled via gXDisplay->Notify() and not
158  // via the ReadNotify() (therefore TGInputHandler should not override
159  // TFileHandler::ReadNotify()).
160  gXDisplay = xi;
161  }
162 
163  // Initialize internal window list. Use a THashList for fast
164  // finding of windows based on window id (see GetWindowById()).
165 
166  fWlist = new THashList(200);
167  fPlist = new TList;
168 
169  // Create root window
170 
171  fDefaultRoot = fRoot = new TGFrame(this, gVirtualX->GetDefaultRootWindow());
172 
173  // Setup some atoms (defined in TVirtualX)...
174 
175  gWM_DELETE_WINDOW = gVirtualX->InternAtom("WM_DELETE_WINDOW", kFALSE);
176  gMOTIF_WM_HINTS = gVirtualX->InternAtom("_MOTIF_WM_HINTS", kFALSE);
177  gROOT_MESSAGE = gVirtualX->InternAtom("_ROOT_MESSAGE", kFALSE);
178 
179  // Create the graphics event handler, an object for the root window,
180  // a picture pool, mimetype list, etc...
181 
182  fGlobalNeedRedraw = kFALSE;
183  fForceRedraw = kFALSE;
184  fWaitForWindow = kNone;
185  fWaitForEvent = kOtherEvent;
186 
187  fResourcePool = new TGResourcePool(this);
188 
189  fPicturePool = fResourcePool->GetPicturePool();
190  fGCPool = fResourcePool->GetGCPool();
191  fFontPool = fResourcePool->GetFontPool();
192 
193  fMimeTypeList = fResourcePool->GetMimeTypes();
194  fDefaultColormap = fResourcePool->GetDefaultColormap();
195 
196  // Set some color defaults...
197 
198  fWhite = fResourcePool->GetWhiteColor();
199  fBlack = fResourcePool->GetBlackColor();
200  fBackColor = fResourcePool->GetFrameBgndColor();
201  fForeColor = fResourcePool->GetFrameFgndColor();
202  fHilite = GetHilite(fBackColor);
203  fShadow = GetShadow(fBackColor);
204  fSelForeColor = fResourcePool->GetSelectedFgndColor();
205  fSelBackColor = fResourcePool->GetSelectedBgndColor();
206 
207  fStyle = 0;
208  TString style = gEnv->GetValue("Gui.Style", "modern");
209  if (style.Contains("flat", TString::kIgnoreCase))
210  fStyle = 2;
211  else if (style.Contains("modern", TString::kIgnoreCase))
212  fStyle = 1;
213 
214  gClientGlobal = this;
215 }
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// Returns current root (i.e. base) window. By changing the root
219 /// window one can change the window hierarchy, e.g. a top level
220 /// frame (TGMainFrame) can be embedded in another window.
221 
223 {
224  return fRoot;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /// Returns the root (i.e. desktop) window. Should only be used as parent
229 /// for frames that will never be embedded, like popups, message boxes,
230 /// etc. (like TGToolTips, TGMessageBox, etc.).
231 
233 {
234  return fDefaultRoot;
235 }
236 
237 ////////////////////////////////////////////////////////////////////////////////
238 /// Sets the current root (i.e. base) window. By changing the root
239 /// window one can change the window hierarchy, e.g. a top level
240 /// frame (TGMainFrame) can be embedded in another window.
241 
243 {
244  fRoot = root ? root : fDefaultRoot;
245 }
246 
247 ////////////////////////////////////////////////////////////////////////////////
248 /// Set the button style (modern or classic).
249 
250 void TGClient::SetStyle(const char *style)
251 {
252  fStyle = 0;
253  if (style && strstr(style, "modern"))
254  fStyle = 1;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Get display width.
259 
261 {
262  Int_t x, y;
263  UInt_t w, h;
264 
265  gVirtualX->GetGeometry(-1, x, y, w, h);
266 
267  return w;
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// Get display height.
272 
274 {
275  Int_t x, y;
276  UInt_t w, h;
277 
278  gVirtualX->GetGeometry(-1, x, y, w, h);
279 
280  return h;
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 /// Get picture from the picture pool. Picture must be freed using
285 /// TGClient::FreePicture(). If picture is not found 0 is returned.
286 
288 {
289  return fPicturePool->GetPicture(name);
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// Get picture with specified size from pool (picture will be scaled if
294 /// necessary). Picture must be freed using TGClient::FreePicture(). If
295 /// picture is not found 0 is returned.
296 
298  UInt_t new_width, UInt_t new_height)
299 {
300  return fPicturePool->GetPicture(name, new_width, new_height);
301 }
302 
303 ////////////////////////////////////////////////////////////////////////////////
304 /// Free picture resource.
305 
307 {
308  if (pic) fPicturePool->FreePicture(pic);
309 }
310 
311 ////////////////////////////////////////////////////////////////////////////////
312 /// Get graphics context from the gc pool. Context must be freed via
313 /// TGClient::FreeGC(). If rw is true a new read/write-able GC
314 /// is returned, otherwise a shared read-only context is returned.
315 /// For historical reasons it is also possible to create directly a
316 /// TGGC object, but it is advised to use this new interface only.
317 
319 {
320  return fGCPool->GetGC(values, rw);
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 /// Free a graphics context.
325 
326 void TGClient::FreeGC(const TGGC *gc)
327 {
328  fGCPool->FreeGC(gc);
329 }
330 
331 ////////////////////////////////////////////////////////////////////////////////
332 /// Free a graphics context.
333 
335 {
336  fGCPool->FreeGC(gc);
337 }
338 
339 ////////////////////////////////////////////////////////////////////////////////
340 /// Get a font from the font pool. Fonts must be freed via
341 /// TGClient::FreeFont(). Returns 0 in case of error or if font
342 /// does not exist. If fixedDefault is false the "fixed" font
343 /// will not be substituted as fallback when the asked for font
344 /// does not exist.
345 
346 TGFont *TGClient::GetFont(const char *font, Bool_t fixedDefault)
347 {
348  return fFontPool->GetFont(font, fixedDefault);
349 }
350 
351 ////////////////////////////////////////////////////////////////////////////////
352 /// Get again specified font. Will increase its usage count.
353 
355 {
356  return fFontPool->GetFont(font);
357 }
358 
359 ////////////////////////////////////////////////////////////////////////////////
360 /// Free a font.
361 
362 void TGClient::FreeFont(const TGFont *font)
363 {
364  fFontPool->FreeFont(font);
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Set redraw flags.
369 
371 {
372  if (gVirtualX->NeedRedraw((ULong_t)w,force)) return;
373  if (force) {
374  w->DoRedraw();
375  return;
376  }
377  w->fNeedRedraw = kTRUE;
378  fGlobalNeedRedraw = kTRUE;
379 }
380 
381 ////////////////////////////////////////////////////////////////////////////////
382 
384 {
385  w->fNeedRedraw = kFALSE;
386 }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Get a color by name. If color is found return kTRUE and pixel is
390 /// set to the color's pixel value, kFALSE otherwise.
391 
392 Bool_t TGClient::GetColorByName(const char *name, Pixel_t &pixel) const
393 {
394  ColorStruct_t color;
395  WindowAttributes_t attributes = WindowAttributes_t();
396  Bool_t status = kTRUE;
397 
398  gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
399  color.fPixel = 0;
400  if (!gVirtualX->ParseColor(attributes.fColormap, name, color)) {
401  Error("GetColorByName", "couldn't parse color %s", name);
402  status = kFALSE;
403  } else if (!gVirtualX->AllocColor(attributes.fColormap, color)) {
404  Warning("GetColorByName", "couldn't retrieve color %s.\n"
405  "Please close any other application, like netscape, "
406  "that might exhaust\nthe colormap and start ROOT again", name);
407  status = kFALSE;
408  }
409 
410  pixel = color.fPixel;
411 
412  return status;
413 }
414 
415 ////////////////////////////////////////////////////////////////////////////////
416 /// Get a font by name. If font is not found, fixed font is returned,
417 /// if fixed font also does not exist return 0 and print error.
418 /// The loaded font needs to be freed using TVirtualX::DeleteFont().
419 /// If fixedDefault is false the "fixed" font will not be substituted
420 /// as fallback when the asked for font does not exist.
421 
422 FontStruct_t TGClient::GetFontByName(const char *name, Bool_t fixedDefault) const
423 {
424  if (gROOT->IsBatch())
425  return (FontStruct_t) -1;
426 
427  FontStruct_t font = gVirtualX->LoadQueryFont(name);
428 
429  if (!font && fixedDefault) {
430  font = gVirtualX->LoadQueryFont("fixed");
431  if (font)
432  Warning("GetFontByName", "couldn't retrieve font %s, using \"fixed\"", name);
433  }
434  if (!font) {
435  if (fixedDefault)
436  Error("GetFontByName", "couldn't retrieve font %s nor backup font \"fixed\"", name);
437  else
438  Warning("GetFontByName", "couldn't retrieve font %s", name);
439  }
440 
441  return font;
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Return pixel value of hilite color based on base_color.
446 
448 {
449  ColorStruct_t color, white_p;
450  WindowAttributes_t attributes = WindowAttributes_t();
451 
452  gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
453 
454  color.fPixel = base_color;
455  gVirtualX->QueryColor(attributes.fColormap, color);
456 
457  GetColorByName("white", white_p.fPixel);
458  gVirtualX->QueryColor(attributes.fColormap, white_p);
459 
460  color.fRed = TMath::Max((UShort_t)(white_p.fRed/5), color.fRed);
461  color.fGreen = TMath::Max((UShort_t)(white_p.fGreen/5), color.fGreen);
462  color.fBlue = TMath::Max((UShort_t)(white_p.fBlue/5), color.fBlue);
463 
464  color.fRed = (UShort_t)TMath::Min((Int_t)white_p.fRed, (Int_t)(color.fRed*140)/100);
465  color.fGreen = (UShort_t)TMath::Min((Int_t)white_p.fGreen, (Int_t)(color.fGreen*140)/100);
466  color.fBlue = (UShort_t)TMath::Min((Int_t)white_p.fBlue, (Int_t)(color.fBlue*140)/100);
467 
468  if (!gVirtualX->AllocColor(attributes.fColormap, color))
469  Error("GetHilite", "couldn't allocate hilight color");
470 
471  return color.fPixel;
472 }
473 
474 ////////////////////////////////////////////////////////////////////////////////
475 /// Return pixel value of shadow color based on base_color.
476 /// Shadow is 60% of base_color intensity.
477 
479 {
480  ColorStruct_t color;
481  WindowAttributes_t attributes = WindowAttributes_t();
482 
483  gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
484 
485  color.fPixel = base_color;
486  gVirtualX->QueryColor(attributes.fColormap, color);
487 
488  color.fRed = (UShort_t)((color.fRed*60)/100);
489  color.fGreen = (UShort_t)((color.fGreen*60)/100);
490  color.fBlue = (UShort_t)((color.fBlue*60)/100);
491 
492  if (!gVirtualX->AllocColor(attributes.fColormap, color))
493  Error("GetShadow", "couldn't allocate shadow color");
494 
495  return color.fPixel;
496 }
497 
498 ////////////////////////////////////////////////////////////////////////////////
499 /// Free color.
500 
501 void TGClient::FreeColor(Pixel_t color) const
502 {
503  gVirtualX->FreeColor(fDefaultColormap, color);
504 }
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 /// Add a TGWindow to the clients list of windows.
508 
510 {
511  fWlist->Add(w);
512 
513  // Emits signal
514  RegisteredWindow(w->GetId());
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// Remove a TGWindow from the list of windows.
519 
521 {
522  fWlist->Remove(w);
523 }
524 
525 ////////////////////////////////////////////////////////////////////////////////
526 /// Add a popup menu to the list of popups. This list is used to pass
527 /// events to popup menus that are popped up over a transient window which
528 /// is waited for (see WaitFor()).
529 
531 {
532  fPlist->Add(w);
533 
534  // Emits signal
535  RegisteredWindow(w->GetId());
536 }
537 
538 ////////////////////////////////////////////////////////////////////////////////
539 /// Remove a popup menu from the list of popups.
540 
542 {
543  fPlist->Remove(w);
544 }
545 
546 ////////////////////////////////////////////////////////////////////////////////
547 /// Add handler for unknown (i.e. unregistered) windows.
548 
550 {
551  if (!fUWHandlers) {
552  fUWHandlers = new TList;
553  fUWHandlers->SetOwner();
554  }
555 
556  fUWHandlers->Add(h);
557 }
558 
559 ////////////////////////////////////////////////////////////////////////////////
560 /// Remove handler for unknown (i.e. unregistered) windows.
561 
563 {
564  fUWHandlers->Remove(h);
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////
568 /// Add handler for idle events.
569 
571 {
572  if (!fIdleHandlers) {
573  fIdleHandlers = new TList;
574  fIdleHandlers->SetOwner();
575  }
576 
577  fIdleHandlers->Add(h);
578 }
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 /// Remove handler for idle events.
582 
584 {
585  fIdleHandlers->Remove(h);
586 }
587 
588 ////////////////////////////////////////////////////////////////////////////////
589 /// Find a TGWindow via its handle. If window is not found return 0.
590 
592 {
593  TGWindow wt(wid);
594 
595  return (TGWindow *) fWlist->FindObject(&wt);
596 }
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /// Find a TGWindow via its name (unique name used in TGWindow::SavePrimitive).
600 /// If window is not found return 0.
601 
603 {
604  TIter next(fWlist);
605 
606  TObject *obj;
607  while ((obj = next())) {
608  TString n = obj->GetName();
609  if (n == name) {
610  return (TGWindow*)obj;
611  }
612  }
613  return 0;
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Closing down client: cleanup and close X connection.
618 
620 {
621  if (IsZombie())
622  return;
623 
624  if (fWlist)
625  fWlist->Delete("slow");
626  delete fWlist;
627  delete fPlist;
628  delete fUWHandlers;
629  delete fIdleHandlers;
630  delete fResourcePool;
631 
632  gVirtualX->CloseDisplay(); // this should do a cleanup of the remaining
633  // X allocated objects...
634 }
635 
636 ////////////////////////////////////////////////////////////////////////////////
637 /// Process one event. This method should only be called when there is
638 /// a GUI event ready to be processed. If event has been processed
639 /// kTRUE is returned. If processing of a specific event type for a specific
640 /// window was requested kFALSE is returned when specific event has been
641 /// processed, kTRUE otherwise. If no more pending events return kFALSE.
642 
644 {
645  Event_t event;
646 
647  if (!fRoot) return kFALSE;
648  if (gVirtualX->EventsPending()) {
649  gVirtualX->NextEvent(event);
650  if (fWaitForWindow == kNone) {
651  HandleEvent(&event);
652  if (fForceRedraw)
653  DoRedraw();
654  return kTRUE;
655  } else {
656  HandleMaskEvent(&event, fWaitForWindow);
657  if ((event.fType == fWaitForEvent) && (event.fWindow == fWaitForWindow))
658  fWaitForWindow = kNone;
659  if (fForceRedraw)
660  DoRedraw();
661  return kTRUE;
662  }
663  }
664 
665  // if nothing else to do redraw windows that need redrawing
666  if (DoRedraw()) return kTRUE;
667 
668  // process one idle event if there is nothing else to do
669  if (ProcessIdleEvent()) return kTRUE;
670 
671  return kFALSE;
672 }
673 
674 ////////////////////////////////////////////////////////////////////////////////
675 /// Process one idle event.
676 
678 {
679  if (fIdleHandlers) {
680  TGIdleHandler *ih = (TGIdleHandler *) fIdleHandlers->First();
681  if (ih) {
682  RemoveIdleHandler(ih);
683  ih->HandleEvent();
684  return kTRUE;
685  }
686  }
687  return kFALSE;
688 }
689 
690 ////////////////////////////////////////////////////////////////////////////////
691 /// Handles input from the display server. Returns kTRUE if one or more
692 /// events have been processed, kFALSE otherwise.
693 
695 {
696  Bool_t handledevent = kFALSE;
697 
698  while (ProcessOneEvent())
699  handledevent = kTRUE;
700  return handledevent;
701 }
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Wait for window to be destroyed.
705 
707 {
708  Window_t wsave = fWaitForWindow;
709  EGEventType esave = fWaitForEvent;
710 
711  fWaitForWindow = w->GetId();
712  fWaitForEvent = kDestroyNotify;
713 
714  //Let VirtualX know, that we are
715  //in a nested loop for a window w.
716  //Noop on X11/win32gdk.
717  if (gVirtualX)
718  gVirtualX->BeginModalSessionFor(w->GetId());
719 
720  while (fWaitForWindow != kNone) {
721  if (esave == kUnmapNotify)
722  wsave = kNone;
723  gSystem->ProcessEvents();//gSystem->InnerLoop();
724  gSystem->Sleep(5);
725  }
726 
727  fWaitForWindow = wsave;
728  fWaitForEvent = esave;
729 }
730 
731 ////////////////////////////////////////////////////////////////////////////////
732 /// Wait for window to be unmapped.
733 
735 {
736  Window_t wsave = fWaitForWindow;
737  EGEventType esave = fWaitForEvent;
738 
739  fWaitForWindow = w->GetId();
740  fWaitForEvent = kUnmapNotify;
741 
742  //Let VirtualX know, that we are
743  //in a nested loop for a window w.
744  //Noop on X11/win32gdk.
745  if (gVirtualX)
746  gVirtualX->BeginModalSessionFor(w->GetId());
747 
748  while (fWaitForWindow != kNone) {
749  gSystem->ProcessEvents();//gSystem->InnerLoop();
750  gSystem->Sleep(5);
751  }
752 
753  fWaitForWindow = wsave;
754  fWaitForEvent = esave;
755 }
756 
757 ////////////////////////////////////////////////////////////////////////////////
758 /// reset waiting
759 
761 {
762  if (fWaitForWindow == w->GetId()) fWaitForWindow = kNone;
763 }
764 
765 ////////////////////////////////////////////////////////////////////////////////
766 /// Like gSystem->ProcessEvents() but then only allow events for w to
767 /// be processed. For example to interrupt the processing and destroy
768 /// the window, call gROOT->SetInterrupt() before destroying the window.
769 
771 {
772  Window_t wsave = fWaitForWindow;
773  EGEventType esave = fWaitForEvent;
774 
775  fWaitForWindow = w->GetId();
776  fWaitForEvent = kDestroyNotify;
777 
778  Bool_t intr = gSystem->ProcessEvents();
779 
780  fWaitForWindow = wsave;
781  fWaitForEvent = esave;
782 
783  return intr;
784 }
785 
786 ////////////////////////////////////////////////////////////////////////////////
787 /// Redraw all windows that need redrawing. Returns kFALSE if no redraw
788 /// was needed, kTRUE otherwise.
789 /// Only redraw the application's windows when the event queue
790 /// does not contain expose event anymore.
791 
793 {
794  if (!fGlobalNeedRedraw) return kFALSE;
795 
796  TGWindow *w;
797  TObjLink *lnk = fWlist->FirstLink();
798  while (lnk) {
799  w = (TGWindow *) lnk->GetObject();
800  if (w->fNeedRedraw) {
801  w->DoRedraw();
802  w->fNeedRedraw = kFALSE;
803  }
804  lnk = lnk->Next();
805  }
806 
807  fGlobalNeedRedraw = kFALSE;
808  fForceRedraw = kFALSE;
809 
810  return kTRUE;
811 }
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 /// Handle a GUI event.
815 
817 {
818  TGWindow *w;
819 
820  // Emit signal for event recorder(s)
821  if (event->fType != kConfigureNotify) {
822  ProcessedEvent(event, 0);
823  }
824 
825  // Find window where event happened
826  if ((w = GetWindowById(event->fWindow)) == 0) {
827  if (fUWHandlers && fUWHandlers->GetSize() > 0) {
828  TGUnknownWindowHandler *unkwh;
829  TListIter it(fUWHandlers);
830  while ((unkwh = (TGUnknownWindowHandler*)it.Next())) {
831  if (unkwh->HandleEvent(event))
832  return kTRUE;
833  }
834  }
835  //Warning("HandleEvent", "unknown window %ld not handled\n",
836  // event->fWindow);
837  return kFALSE;
838  }
839 
840  // and let it handle the event
841  w->HandleEvent(event);
842 
843  return kTRUE;
844 }
845 
846 ////////////////////////////////////////////////////////////////////////////////
847 /// Handle masked events only if window wid is the window for which the
848 /// event was reported or if wid is a parent of the event window. The not
849 /// masked event are handled directly. The masked events are:
850 /// kButtonPress, kButtonRelease, kKeyPress, kKeyRelease, kEnterNotify,
851 /// kLeaveNotify, kMotionNotify.
852 
854 {
855  TGWindow *w, *ptr, *pop;
856 
857  if ((w = GetWindowById(event->fWindow)) == 0) return kFALSE;
858 
859  // Emit signal for event recorder(s)
860  if (event->fType != kConfigureNotify) {
861  ProcessedEvent(event, wid);
862  }
863 
864  // This breaks class member protection, but TGClient is a friend of
865  // TGWindow and _should_ know what to do and what *not* to do...
866 
867  for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
868  if ((ptr->fId == wid) ||
869  ((event->fType != kButtonPress) &&
870  (event->fType != kButtonRelease) &&
871  (event->fType != kGKeyPress) &&
872  (event->fType != kKeyRelease) &&
873  (event->fType != kEnterNotify) &&
874  (event->fType != kLeaveNotify) &&
875  (event->fType != kMotionNotify))) {
876  w->HandleEvent(event);
877  return kTRUE;
878  }
879  }
880 
881  // check if this is a popup menu
882  TIter next(fPlist);
883  while ((pop = (TGWindow *) next())) {
884  for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
885  if ((ptr->fId == pop->fId) &&
886  ((event->fType == kButtonPress) ||
887  (event->fType == kButtonRelease) ||
888  (event->fType == kGKeyPress) ||
889  (event->fType == kKeyRelease) ||
890  (event->fType == kEnterNotify) ||
891  (event->fType == kLeaveNotify) ||
892  (event->fType == kMotionNotify))) {
893  w->HandleEvent(event);
894  return kTRUE;
895  }
896  }
897  }
898 
899  if (event->fType == kButtonPress || event->fType == kGKeyPress)
900  gVirtualX->Bell(0);
901 
902  return kFALSE;
903 }
904 
905 ////////////////////////////////////////////////////////////////////////////////
906 /// Execute string "cmd" via the interpreter. Before executing replace
907 /// in the command string the token $MSG, $PARM1 and $PARM2 by msg,
908 /// parm1 and parm2, respectively. The function in cmd string must accept
909 /// these as longs.
910 
911 void TGClient::ProcessLine(TString cmd, Long_t msg, Long_t parm1, Long_t parm2)
912 {
913  if (cmd.IsNull()) return;
914 
915  char s[32];
916 
917  snprintf(s, sizeof(s), "%ld", msg);
918  cmd.ReplaceAll("$MSG", s);
919 
920  snprintf(s, sizeof(s), "%ld", parm1);
921  cmd.ReplaceAll("$PARM1", s);
922 
923  snprintf(s, sizeof(s), "%ld", parm2);
924  cmd.ReplaceAll("$PARM2", s);
925 
926  gROOT->ProcessLine(cmd.Data());
927 }
928 
929 ////////////////////////////////////////////////////////////////////////////////
930 /// Returns kTRUE if edit/guibuilding is forbidden.
931 
933 {
934  return (fDefaultRoot->GetEditDisabled() == 1);
935 }
936 
937 ////////////////////////////////////////////////////////////////////////////////
938 /// If on is kTRUE editting/guibuilding is forbidden.
939 
941 {
942  fDefaultRoot->SetEditDisabled(on);
943 }
944 
945 ////////////////////////////////////////////////////////////////////////////////
946 /// Emits a signal when an event has been processed.
947 /// Used in TRecorder.
948 
950 {
951  Long_t args[2];
952  args[0] = (Long_t) event;
953  args[1] = (Long_t) wid;
954 
955  Emit("ProcessedEvent(Event_t*, Window_t)", args);
956 }
957 
958 ////////////////////////////////////////////////////////////////////////////////
959 /// Emits a signal when a Window has been registered in TGClient.
960 /// Used in TRecorder.
961 
963 {
964  Emit("RegisteredWindow(Window_t)", w);
965 }
UShort_t fBlue
Definition: GuiTypes.h:313
void ProcessedEvent(Event_t *event, Window_t wid)
Emits a signal when an event has been processed.
Definition: TGClient.cxx:949
Bool_t IsEditDisabled() const
Returns kTRUE if edit/guibuilding is forbidden.
Definition: TGClient.cxx:932
Handle_t FontStruct_t
Definition: GuiTypes.h:38
const TGWindow * fParent
Definition: TGWindow.h:37
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:423
Bool_t HandleEvent(Event_t *event)
Handle a GUI event.
Definition: TGClient.cxx:816
ROOT top level object description.
Definition: TROOT.h:100
void SetRoot(TGWindow *root=0)
Sets the current root (i.e.
Definition: TGClient.cxx:242
virtual ~TGClient()
Closing down client: cleanup and close X connection.
Definition: TGClient.cxx:619
void RemoveIdleHandler(TGIdleHandler *h)
Remove handler for idle events.
Definition: TGClient.cxx:583
const TGWindow * GetRoot() const
Returns current root (i.e.
Definition: TGClient.cxx:222
void FreeColor(Pixel_t color) const
Free color.
Definition: TGClient.cxx:501
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:640
unsigned short UShort_t
Definition: RtypesCore.h:36
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void TriggerDictionaryInitialization_libGui()
TH1 * h
Definition: legend2.C:5
Bool_t fNeedRedraw
Definition: TGWindow.h:38
EGEventType
Definition: GuiTypes.h:58
Pixel_t GetShadow(Pixel_t base_color) const
Return pixel value of shadow color based on base_color.
Definition: TGClient.cxx:478
#define gROOT
Definition: TROOT.h:375
Handle_t GContext_t
Definition: GuiTypes.h:37
virtual Bool_t HandleEvent()
Handle the idle event.
R__EXTERN Atom_t gWM_DELETE_WINDOW
Definition: TVirtualX.h:39
Basic string class.
Definition: TString.h:129
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Bool_t GetColorByName(const char *name, Pixel_t &pixel) const
Get a color by name.
Definition: TGClient.cxx:392
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
TObject * Next()
Return next object in the list. Returns 0 when no more objects in list.
Definition: TList.cxx:937
static TGClientInit gClientInit
Definition: TGClient.cxx:84
Window_t fWindow
Definition: GuiTypes.h:175
void WaitForUnmap(TGWindow *w)
Wait for window to be unmapped.
Definition: TGClient.cxx:734
void CancelRedraw(TGWindow *w)
Definition: TGClient.cxx:383
Handle_t GetId() const
Definition: TGObject.h:48
void UnregisterWindow(TGWindow *w)
Remove a TGWindow from the list of windows.
Definition: TGClient.cxx:520
Iterator of linked list.
Definition: TList.h:183
static ARGB32 GetShadow(ARGB32 background)
Calculate shadow color.
Definition: TASImage.cxx:3214
Bool_t ProcessIdleEvent()
Process one idle event.
Definition: TGClient.cxx:677
UShort_t fRed
Definition: GuiTypes.h:311
UInt_t GetDisplayWidth() const
Get display width.
Definition: TGClient.cxx:260
void RegisterPopup(TGWindow *w)
Add a popup menu to the list of popups.
Definition: TGClient.cxx:530
TGWindow * GetWindowByName(const char *name) const
Find a TGWindow via its name (unique name used in TGWindow::SavePrimitive).
Definition: TGClient.cxx:602
Double_t x[n]
Definition: legend1.C:17
ULong_t Pixel_t
Definition: GuiTypes.h:39
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:444
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
void RegisterWindow(TGWindow *w)
Add a TGWindow to the clients list of windows.
Definition: TGClient.cxx:509
void FreePicture(const TGPicture *pic)
Free picture resource.
Definition: TGClient.cxx:306
void ProcessLine(TString cmd, Long_t msg, Long_t parm1, Long_t parm2)
Execute string "cmd" via the interpreter.
Definition: TGClient.cxx:911
R__EXTERN TFileHandler * gXDisplay
Definition: TSystem.h:540
Colormap_t fColormap
Definition: GuiTypes.h:127
void SetStyle(UInt_t newstyle)
Definition: TGClient.h:151
virtual Bool_t HandleEvent(Event_t *)=0
virtual void SetDisplay()
Set DISPLAY environment variable based on utmp entry. Only for UNIX.
Definition: TSystem.cxx:238
Bool_t DoRedraw()
Redraw all windows that need redrawing.
Definition: TGClient.cxx:792
void FreeGC(const TGGC *gc)
Free a graphics context.
Definition: TGClient.cxx:326
void RegisteredWindow(Window_t w)
Emits a signal when a Window has been registered in TGClient.
Definition: TGClient.cxx:962
void Error(const char *location, const char *msgfmt,...)
void WaitFor(TGWindow *w)
Wait for window to be destroyed.
Definition: TGClient.cxx:706
A doubly linked list.
Definition: TList.h:43
UShort_t fGreen
Definition: GuiTypes.h:312
Pixmap_t GetPicture() const
Definition: TGPicture.h:65
R__EXTERN TROOT * gROOTLocal
Definition: TROOT.h:372
void FreeFont(const TGFont *font)
Free a font.
Definition: TGClient.cxx:362
static void NeedGraphicsLibs()
Static method.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
Bool_t HandleMaskEvent(Event_t *event, Window_t wid)
Handle masked events only if window wid is the window for which the event was reported or if wid is a...
Definition: TGClient.cxx:853
EGEventType fType
Definition: GuiTypes.h:174
static TGClient * gClientGlobal
Definition: TGClient.cxx:53
void RemoveUnknownWindowHandler(TGUnknownWindowHandler *h)
Remove handler for unknown (i.e. unregistered) windows.
Definition: TGClient.cxx:562
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:482
void AddUnknownWindowHandler(TGUnknownWindowHandler *h)
Add handler for unknown (i.e. unregistered) windows.
Definition: TGClient.cxx:549
Bool_t ProcessOneEvent()
Process one event.
Definition: TGClient.cxx:643
unsigned int UInt_t
Definition: RtypesCore.h:42
const Handle_t kNone
Definition: GuiTypes.h:87
virtual void DoRedraw()
Definition: TGWindow.h:54
static TGClient * Instance()
Returns global gClient (initialize graphics first, if not already done)
Definition: TGClient.cxx:89
Bool_t HandleInput()
Handles input from the display server.
Definition: TGClient.cxx:694
void Warning(const char *location, const char *msgfmt,...)
ULong_t fPixel
Definition: GuiTypes.h:310
#define gVirtualX
Definition: TVirtualX.h:350
TGGC * GetGC(GCValues_t *values, Bool_t rw=kFALSE)
Get graphics context from the gc pool.
Definition: TGClient.cxx:318
const Bool_t kFALSE
Definition: RtypesCore.h:92
void InitializeGraphics()
Initialize the graphics environment.
long Long_t
Definition: RtypesCore.h:50
static void Add(TGlobalMappedFunction *gmf)
Definition: TGlobal.cxx:183
Pixel_t GetHilite(Pixel_t base_color) const
Return pixel value of hilite color based on base_color.
Definition: TGClient.cxx:447
void ResetWaitFor(TGWindow *w)
reset waiting
Definition: TGClient.cxx:760
#define ClassImp(name)
Definition: Rtypes.h:336
virtual Bool_t HandleEvent(Event_t *)
Definition: TGWindow.h:103
const TGPicture * GetPicture(const char *name)
Get picture from the picture pool.
Definition: TGClient.cxx:287
GContext_t GetGC() const
Definition: TGGC.h:50
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
Definition: TGFont.h:149
unsigned long ULong_t
Definition: RtypesCore.h:51
TCanvas * style()
Definition: style.C:1
Double_t y[n]
Definition: legend1.C:17
static ARGB32 GetHilite(ARGB32 background)
Calculate highlite color.
Definition: TASImage.cxx:3202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
UInt_t GetDisplayHeight() const
Get display height.
Definition: TGClient.cxx:273
Bool_t IsNull() const
Definition: TString.h:385
Handle_t fId
Definition: TGObject.h:36
void AddIdleHandler(TGIdleHandler *h)
Add handler for idle events.
Definition: TGClient.cxx:570
Mother of all ROOT objects.
Definition: TObject.h:37
FontStruct_t GetFontByName(const char *name, Bool_t fixedDefault=kTRUE) const
Get a font by name.
Definition: TGClient.cxx:422
R__EXTERN Atom_t gMOTIF_WM_HINTS
Definition: TVirtualX.h:40
Bool_t IsBatch() const
Definition: TROOT.h:282
Handle_t Window_t
Definition: GuiTypes.h:28
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
Bool_t ProcessEventsFor(TGWindow *w)
Like gSystem->ProcessEvents() but then only allow events for w to be processed.
Definition: TGClient.cxx:770
const TGWindow * GetDefaultRoot() const
Returns the root (i.e.
Definition: TGClient.cxx:232
#define snprintf
Definition: civetweb.c:822
void NeedRedraw(TGWindow *w, Bool_t force=kFALSE)
Set redraw flags.
Definition: TGClient.cxx:370
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:561
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
void *(* GlobalFunc_t)()
Definition: TGlobal.h:54
const Bool_t kTRUE
Definition: RtypesCore.h:91
void SetEditDisabled(Bool_t on=kTRUE)
If on is kTRUE editting/guibuilding is forbidden.
Definition: TGClient.cxx:940
Definition: TGGC.h:31
const Int_t n
Definition: legend1.C:16
void UnregisterPopup(TGWindow *w)
Remove a popup menu from the list of popups.
Definition: TGClient.cxx:541
TGFont * GetFont(const char *font, Bool_t fixedDefault=kTRUE)
Get a font from the font pool.
Definition: TGClient.cxx:346
R__EXTERN Atom_t gROOT_MESSAGE
Definition: TVirtualX.h:41
const char * Data() const
Definition: TString.h:347
TGWindow * GetWindowById(Window_t sw) const
Find a TGWindow via its handle. If window is not found return 0.
Definition: TGClient.cxx:591