32 #include "RConfigure.h"
53 static TGClient *gClientGlobal =
nullptr;
56 static struct AddPseudoGlobals {
60 TGlobalMappedFunction::MakeFunctor(
"gClient",
"TGClient*", TGClient::Instance, [] {
62 return (
void *) &gClientGlobal;
69 void TriggerDictionaryInitialization_libGui();
73 TROOT *rootlocal = ROOT::Internal::gROOTLocal;
74 if (rootlocal && rootlocal->IsBatch()) {
80 TriggerDictionaryInitialization_libGui();
83 TApplication::NeedGraphicsLibs();
86 static TGClientInit gClientInit;
91 TGClient *TGClient::Instance()
93 if (!gClientGlobal && gApplication)
94 gApplication->InitializeGraphics();
101 class TGInputHandler :
public TFileHandler {
105 TGInputHandler(TGClient *c, Int_t fd) : TFileHandler(fd, 1) { fClient = c; }
113 Bool_t TGInputHandler::Notify()
115 return fClient->HandleInput();
126 TGClient::TGClient(
const char *dpyName)
137 Error(
"TGClient",
"only one instance of TGClient allowed");
143 gSystem->SetDisplay();
146 if ((fXfd = gVirtualX->OpenDisplay(dpyName)) < 0) {
147 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",
148 gVirtualX->DisplayName(dpyName));
153 if (fXfd >= 0 && !ROOT::Internal::gROOTLocal->IsBatch()) {
154 TGInputHandler *xi =
new TGInputHandler(
this, fXfd);
155 if (fXfd) gSystem->AddFileHandler(xi);
168 fWlist =
new THashList(200);
173 fDefaultRoot = fRoot =
new TGFrame(
this, gVirtualX->GetDefaultRootWindow());
177 gWM_DELETE_WINDOW = gVirtualX->InternAtom(
"WM_DELETE_WINDOW", kFALSE);
178 gMOTIF_WM_HINTS = gVirtualX->InternAtom(
"_MOTIF_WM_HINTS", kFALSE);
179 gROOT_MESSAGE = gVirtualX->InternAtom(
"_ROOT_MESSAGE", kFALSE);
184 fGlobalNeedRedraw = kFALSE;
185 fForceRedraw = kFALSE;
186 fWaitForWindow = kNone;
187 fWaitForEvent = kOtherEvent;
189 fResourcePool =
new TGResourcePool(
this);
191 fPicturePool = fResourcePool->GetPicturePool();
192 fGCPool = fResourcePool->GetGCPool();
193 fFontPool = fResourcePool->GetFontPool();
195 fMimeTypeList = fResourcePool->GetMimeTypes();
196 fDefaultColormap = fResourcePool->GetDefaultColormap();
200 fWhite = fResourcePool->GetWhiteColor();
201 fBlack = fResourcePool->GetBlackColor();
202 fBackColor = fResourcePool->GetFrameBgndColor();
203 fForeColor = fResourcePool->GetFrameFgndColor();
204 fHilite = GetHilite(fBackColor);
205 fShadow = GetShadow(fBackColor);
206 fSelForeColor = fResourcePool->GetSelectedFgndColor();
207 fSelBackColor = fResourcePool->GetSelectedBgndColor();
210 TString style = gEnv->GetValue(
"Gui.Style",
"modern");
211 if (style.Contains(
"flat", TString::kIgnoreCase))
213 else if (style.Contains(
"modern", TString::kIgnoreCase))
216 gClientGlobal =
this;
224 const TGWindow *TGClient::GetRoot()
const
234 const TGWindow *TGClient::GetDefaultRoot()
const
244 void TGClient::SetRoot(TGWindow *root)
246 fRoot = root ? root : fDefaultRoot;
252 void TGClient::SetStyle(
const char *style)
255 if (style && strstr(style,
"modern"))
262 UInt_t TGClient::GetDisplayWidth()
const
267 gVirtualX->GetGeometry(-1, x, y, w, h);
275 UInt_t TGClient::GetDisplayHeight()
const
280 gVirtualX->GetGeometry(-1, x, y, w, h);
289 const TGPicture *TGClient::GetPicture(
const char *name)
291 return fPicturePool->GetPicture(name);
299 const TGPicture *TGClient::GetPicture(
const char *name,
300 UInt_t new_width, UInt_t new_height)
302 return fPicturePool->GetPicture(name, new_width, new_height);
308 void TGClient::FreePicture(
const TGPicture *pic)
310 if (pic) fPicturePool->FreePicture(pic);
320 TGGC *TGClient::GetGC(GCValues_t *values, Bool_t rw)
322 return fGCPool->GetGC(values, rw);
328 void TGClient::FreeGC(
const TGGC *gc)
336 void TGClient::FreeGC(GContext_t gc)
348 TGFont *TGClient::GetFont(
const char *font, Bool_t fixedDefault)
350 return fFontPool->GetFont(font, fixedDefault);
356 TGFont *TGClient::GetFont(
const TGFont *font)
358 return fFontPool->GetFont(font);
364 void TGClient::FreeFont(
const TGFont *font)
366 fFontPool->FreeFont(font);
372 void TGClient::NeedRedraw(TGWindow *w, Bool_t force)
374 if (gVirtualX->NeedRedraw((ULong_t)w,force))
return;
379 w->fNeedRedraw = kTRUE;
380 fGlobalNeedRedraw = kTRUE;
385 void TGClient::CancelRedraw(TGWindow *w)
387 w->fNeedRedraw = kFALSE;
394 Bool_t TGClient::GetColorByName(
const char *name, Pixel_t &pixel)
const
397 WindowAttributes_t attributes = WindowAttributes_t();
398 Bool_t status = kTRUE;
400 gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
402 if (!gVirtualX->ParseColor(attributes.fColormap, name, color)) {
403 Error(
"GetColorByName",
"couldn't parse color %s", name);
405 }
else if (!gVirtualX->AllocColor(attributes.fColormap, color)) {
406 Warning(
"GetColorByName",
"couldn't retrieve color %s.\n"
407 "Please close any other application, like netscape, "
408 "that might exhaust\nthe colormap and start ROOT again", name);
412 pixel = color.fPixel;
424 FontStruct_t TGClient::GetFontByName(
const char *name, Bool_t fixedDefault)
const
426 if (gROOT->IsBatch())
427 return (FontStruct_t) -1;
429 FontStruct_t font = gVirtualX->LoadQueryFont(name);
431 if (!font && fixedDefault) {
432 font = gVirtualX->LoadQueryFont(
"fixed");
434 Warning(
"GetFontByName",
"couldn't retrieve font %s, using \"fixed\"", name);
438 Error(
"GetFontByName",
"couldn't retrieve font %s nor backup font \"fixed\"", name);
440 Warning(
"GetFontByName",
"couldn't retrieve font %s", name);
449 Pixel_t TGClient::GetHilite(Pixel_t base_color)
const
451 ColorStruct_t color, white_p;
452 WindowAttributes_t attributes = WindowAttributes_t();
454 gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
456 color.fPixel = base_color;
457 gVirtualX->QueryColor(attributes.fColormap, color);
459 GetColorByName(
"white", white_p.fPixel);
460 gVirtualX->QueryColor(attributes.fColormap, white_p);
462 color.fRed = TMath::Max((UShort_t)(white_p.fRed/5), color.fRed);
463 color.fGreen = TMath::Max((UShort_t)(white_p.fGreen/5), color.fGreen);
464 color.fBlue = TMath::Max((UShort_t)(white_p.fBlue/5), color.fBlue);
466 color.fRed = (UShort_t)TMath::Min((Int_t)white_p.fRed, (Int_t)(color.fRed*140)/100);
467 color.fGreen = (UShort_t)TMath::Min((Int_t)white_p.fGreen, (Int_t)(color.fGreen*140)/100);
468 color.fBlue = (UShort_t)TMath::Min((Int_t)white_p.fBlue, (Int_t)(color.fBlue*140)/100);
470 if (!gVirtualX->AllocColor(attributes.fColormap, color))
471 Error(
"GetHilite",
"couldn't allocate hilight color");
480 Pixel_t TGClient::GetShadow(Pixel_t base_color)
const
483 WindowAttributes_t attributes = WindowAttributes_t();
485 gVirtualX->GetWindowAttributes(fRoot->GetId(), attributes);
487 color.fPixel = base_color;
488 gVirtualX->QueryColor(attributes.fColormap, color);
490 color.fRed = (UShort_t)((color.fRed*60)/100);
491 color.fGreen = (UShort_t)((color.fGreen*60)/100);
492 color.fBlue = (UShort_t)((color.fBlue*60)/100);
494 if (!gVirtualX->AllocColor(attributes.fColormap, color))
495 Error(
"GetShadow",
"couldn't allocate shadow color");
503 void TGClient::FreeColor(Pixel_t color)
const
505 gVirtualX->FreeColor(fDefaultColormap, color);
511 void TGClient::RegisterWindow(TGWindow *w)
516 RegisteredWindow(w->GetId());
522 void TGClient::UnregisterWindow(TGWindow *w)
532 void TGClient::RegisterPopup(TGWindow *w)
537 RegisteredWindow(w->GetId());
543 void TGClient::UnregisterPopup(TGWindow *w)
551 void TGClient::AddUnknownWindowHandler(TGUnknownWindowHandler *h)
554 fUWHandlers =
new TList;
555 fUWHandlers->SetOwner();
564 void TGClient::RemoveUnknownWindowHandler(TGUnknownWindowHandler *h)
566 fUWHandlers->Remove(h);
572 void TGClient::AddIdleHandler(TGIdleHandler *h)
574 if (!fIdleHandlers) {
575 fIdleHandlers =
new TList;
576 fIdleHandlers->SetOwner();
579 fIdleHandlers->Add(h);
585 void TGClient::RemoveIdleHandler(TGIdleHandler *h)
587 fIdleHandlers->Remove(h);
593 TGWindow *TGClient::GetWindowById(Window_t wid)
const
597 return (TGWindow *) fWlist->FindObject(&wt);
604 TGWindow *TGClient::GetWindowByName(
const char *name)
const
609 while ((obj = next())) {
610 TString n = obj->GetName();
612 return (TGWindow*)obj;
621 TGClient::~TGClient()
627 fWlist->Delete(
"slow");
631 delete fIdleHandlers;
632 delete fResourcePool;
634 gVirtualX->CloseDisplay();
645 Bool_t TGClient::ProcessOneEvent()
649 if (!fRoot)
return kFALSE;
650 if (gVirtualX->EventsPending()) {
651 gVirtualX->NextEvent(event);
652 if (fWaitForWindow == kNone) {
658 HandleMaskEvent(&event, fWaitForWindow);
659 if ((event.fType == fWaitForEvent) && (event.fWindow == fWaitForWindow))
660 fWaitForWindow = kNone;
668 if (DoRedraw())
return kTRUE;
671 if (ProcessIdleEvent())
return kTRUE;
679 Bool_t TGClient::ProcessIdleEvent()
682 TGIdleHandler *ih = (TGIdleHandler *) fIdleHandlers->First();
684 RemoveIdleHandler(ih);
696 Bool_t TGClient::HandleInput()
698 Bool_t handledevent = kFALSE;
700 while (ProcessOneEvent())
701 handledevent = kTRUE;
708 void TGClient::WaitFor(TGWindow *w)
710 Window_t wsave = fWaitForWindow;
711 EGEventType esave = fWaitForEvent;
713 fWaitForWindow = w->GetId();
714 fWaitForEvent = kDestroyNotify;
720 gVirtualX->BeginModalSessionFor(w->GetId());
722 while (fWaitForWindow != kNone) {
723 if (esave == kUnmapNotify)
725 gSystem->ProcessEvents();
729 fWaitForWindow = wsave;
730 fWaitForEvent = esave;
736 void TGClient::WaitForUnmap(TGWindow *w)
738 Window_t wsave = fWaitForWindow;
739 EGEventType esave = fWaitForEvent;
741 fWaitForWindow = w->GetId();
742 fWaitForEvent = kUnmapNotify;
748 gVirtualX->BeginModalSessionFor(w->GetId());
750 while (fWaitForWindow != kNone) {
751 gSystem->ProcessEvents();
755 fWaitForWindow = wsave;
756 fWaitForEvent = esave;
762 void TGClient::ResetWaitFor(TGWindow *w)
764 if (fWaitForWindow == w->GetId()) fWaitForWindow = kNone;
772 Bool_t TGClient::ProcessEventsFor(TGWindow *w)
774 Window_t wsave = fWaitForWindow;
775 EGEventType esave = fWaitForEvent;
777 fWaitForWindow = w->GetId();
778 fWaitForEvent = kDestroyNotify;
780 Bool_t intr = gSystem->ProcessEvents();
782 fWaitForWindow = wsave;
783 fWaitForEvent = esave;
794 Bool_t TGClient::DoRedraw()
796 if (!fGlobalNeedRedraw)
return kFALSE;
799 TObjLink *lnk = fWlist->FirstLink();
801 w = (TGWindow *) lnk->GetObject();
802 if (w->fNeedRedraw) {
804 w->fNeedRedraw = kFALSE;
809 fGlobalNeedRedraw = kFALSE;
810 fForceRedraw = kFALSE;
818 Bool_t TGClient::HandleEvent(Event_t *event)
823 if (event->fType != kConfigureNotify) {
824 ProcessedEvent(event, 0);
828 if ((w = GetWindowById(event->fWindow)) == 0) {
829 if (fUWHandlers && fUWHandlers->GetSize() > 0) {
830 TGUnknownWindowHandler *unkwh;
831 TListIter it(fUWHandlers);
832 while ((unkwh = (TGUnknownWindowHandler*)it.Next())) {
833 if (unkwh->HandleEvent(event))
843 w->HandleEvent(event);
855 Bool_t TGClient::HandleMaskEvent(Event_t *event, Window_t wid)
857 TGWindow *w, *ptr, *pop;
859 if ((w = GetWindowById(event->fWindow)) == 0)
return kFALSE;
862 if (event->fType != kConfigureNotify) {
863 ProcessedEvent(event, wid);
869 for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
870 if ((ptr->fId == wid) ||
871 ((
event->fType != kButtonPress) &&
872 (event->fType != kButtonRelease) &&
873 (
event->fType != kGKeyPress) &&
874 (event->fType != kKeyRelease) &&
875 (
event->fType != kEnterNotify) &&
876 (event->fType != kLeaveNotify) &&
877 (
event->fType != kMotionNotify))) {
878 w->HandleEvent(event);
885 while ((pop = (TGWindow *) next())) {
886 for (ptr = w; ptr->fParent != 0; ptr = (TGWindow *) ptr->fParent) {
887 if ((ptr->fId == pop->fId) &&
888 ((
event->fType == kButtonPress) ||
889 (event->fType == kButtonRelease) ||
890 (
event->fType == kGKeyPress) ||
891 (event->fType == kKeyRelease) ||
892 (
event->fType == kEnterNotify) ||
893 (event->fType == kLeaveNotify) ||
894 (
event->fType == kMotionNotify))) {
895 w->HandleEvent(event);
901 if (event->fType == kButtonPress || event->fType == kGKeyPress)
913 void TGClient::ProcessLine(TString cmd, Long_t msg, Long_t parm1, Long_t parm2)
915 if (cmd.IsNull())
return;
919 snprintf(s,
sizeof(s),
"%ld", msg);
920 cmd.ReplaceAll(
"$MSG", s);
922 snprintf(s,
sizeof(s),
"%ld", parm1);
923 cmd.ReplaceAll(
"$PARM1", s);
925 snprintf(s,
sizeof(s),
"%ld", parm2);
926 cmd.ReplaceAll(
"$PARM2", s);
928 gROOT->ProcessLine(cmd.Data());
934 Bool_t TGClient::IsEditDisabled()
const
936 return (fDefaultRoot->GetEditDisabled() == 1);
942 void TGClient::SetEditDisabled(Bool_t on)
944 fDefaultRoot->SetEditDisabled(on);
951 void TGClient::ProcessedEvent(Event_t *event, Window_t wid)
954 args[0] = (Long_t) event;
955 args[1] = (Long_t) wid;
957 Emit(
"ProcessedEvent(Event_t*, Window_t)", args);
964 void TGClient::RegisteredWindow(Window_t w)
966 Emit(
"RegisteredWindow(Window_t)", w);