diff --git a/graf2d/asimage/inc/TASImage.h b/graf2d/asimage/inc/TASImage.h index 2efd50bc74253..3fad702ba1f0f 100644 --- a/graf2d/asimage/inc/TASImage.h +++ b/graf2d/asimage/inc/TASImage.h @@ -186,14 +186,16 @@ class TASImage : public TImage { // Utilities UInt_t GetWidth() const override; UInt_t GetHeight() const override; - UInt_t GetScaledWidth() const; - UInt_t GetScaledHeight() const; + UInt_t GetScaledWidth() const override; + UInt_t GetScaledHeight() const override; Bool_t IsValid() const override { return fImage ? kTRUE : kFALSE; } Bool_t IsGray() const override { return fIsGray; } ASImage *GetImage() const { return fImage; } void SetImage(ASImage *image) { DestroyImage(); fImage = image; } TImage *GetScaledImage() const override { return fScaledImage; } + Pixmap_t GetX11Pixmap(Window_t root_window) override; Pixmap_t GetPixmap() override; + Bool_t GetMaskBits(UInt_t &width, UInt_t &height, std::vector &bits) override; Pixmap_t GetMask() override; TArrayL *GetPixels(Int_t x = 0, Int_t y = 0, UInt_t w = 0, UInt_t h = 0) override; TArrayD *GetArray(UInt_t w = 0, UInt_t h = 0, TImagePalette *pal = gWebImagePalette) override; diff --git a/graf2d/asimage/src/TASImage.cxx b/graf2d/asimage/src/TASImage.cxx index 10e7ab85f1962..fd12225042217 100644 --- a/graf2d/asimage/src/TASImage.cxx +++ b/graf2d/asimage/src/TASImage.cxx @@ -2159,75 +2159,81 @@ void TASImage::StartPaletteEditor() TAttImage::StartPaletteEditor(); } + //////////////////////////////////////////////////////////////////////////////// -/// Returns image pixmap. +/// Returns image X11 pixmap. +/// Workrs only on the platforms with support of X11 /// The pixmap must deleted by user. -Pixmap_t TASImage::GetPixmap() +Pixmap_t TASImage::GetX11Pixmap(Window_t root_window) { if (!InitVisual()) { - Warning("GetPixmap", "Visual not initiated"); + Warning("GetX11Pixmap", "Visual not initiated"); return 0; } - Pixmap_t ret; - ASImage *img = fScaledImage ? fScaledImage->fImage : fImage; - static int x11 = -1; - if (x11 < 0) x11 = gVirtualX->InheritsFrom("TGX11"); + return (Pixmap_t)asimage2pixmap(fgVisual, root_window, img, nullptr, kTRUE); +} - if (x11) { // use builtin version - ret = (Pixmap_t)asimage2pixmap(fgVisual, gVirtualX->GetDefaultRootWindow(), - img, nullptr, kTRUE); - } else { - if (!fImage->alt.argb32) { - BeginPaint(); - } - ret = gVirtualX->CreatePixmapFromData((unsigned char*)fImage->alt.argb32, - fImage->width, fImage->height); +//////////////////////////////////////////////////////////////////////////////// +/// DEPRECATED. Method left for backward compatibility and will be removed in ROOT7! +/// Returns image pixmap. +/// The pixmap must deleted by user. + +Pixmap_t TASImage::GetPixmap() +{ + static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); + + if (x11) + return GetX11Pixmap(gVirtualX->GetDefaultRootWindow()); + + auto argb = GetArgbArray(); + if (!argb) { + Error("GetPixmap", "ARGB array is not exists"); + return 0; } - return ret; + return gVirtualX->CreatePixmapFromData((unsigned char*) argb, GetScaledWidth(), GetScaledHeight()); } //////////////////////////////////////////////////////////////////////////////// -/// Returns image mask pixmap (alpha channel). -/// The pixmap must deleted by user. +/// Returns image mask bits - only alpha channel of the image. +/// Also provides width and height which is aligned to 8 bits +/// Returns kTRUE if operation was successful -Pixmap_t TASImage::GetMask() +Bool_t TASImage::GetMaskBits(UInt_t &width, UInt_t &height, std::vector &bits) { - Pixmap_t pxmap = 0; - if (!InitVisual()) { - Warning("GetMask", "Visual not initiated"); - return pxmap; + Warning("GetMaskBits", "Visual not initiated"); + return kFALSE; } ASImage *img = fScaledImage ? fScaledImage->fImage : fImage; if (!img) { - Warning("GetMask", "No image"); - return pxmap; + Warning("GetMaskBits", "No image"); + return kFALSE; } - UInt_t hh = img->height; - UInt_t ow = img->width%8; - UInt_t ww = img->width - ow + (ow ? 8 : 0); + height = img->height; + UInt_t ow = img->width % 8; + width = img->width - ow + (ow ? 8 : 0); ASImageDecoder *imdec = start_image_decoding(fgVisual, img, SCL_DO_ALPHA, - 0, 0, ww, 0, nullptr); + 0, 0, width, 0, nullptr); if (!imdec) - return pxmap; + return kFALSE; - std::vector bits(ww * hh / 8); //an array of bits + bits.resize(height * width / 8); //an array of bits UInt_t bit = 0, i = 0; - for (UInt_t y = 0; y < hh; y++) { + for (UInt_t y = 0; y < height; y++) { imdec->decode_image_scanline(imdec); CARD32 *a = imdec->buffer.alpha; - for (UInt_t x = 0; x < ww; x++) { + for (UInt_t x = 0; x < width; x++) { if (a[x]) { SETBIT(bits[i], bit); } else { @@ -2241,8 +2247,25 @@ Pixmap_t TASImage::GetMask() } stop_image_decoding(&imdec); - pxmap = gVirtualX->CreateBitmap(gVirtualX->GetDefaultRootWindow(), bits.data(), ww, hh); - return pxmap; + + return kTRUE; +} + +//////////////////////////////////////////////////////////////////////////////// +/// DEPRECATED! Method left for backward compatibility and will be removed in ROOT7! +/// Returns image mask pixmap (alpha channel). +/// The pixmap must deleted by user. + +Pixmap_t TASImage::GetMask() +{ + Pixmap_t pixmap = 0; + + UInt_t ww = 0, hh = 0; + std::vector bits; + if (GetMaskBits(ww, hh, bits)) + pixmap = gVirtualX->CreateBitmap(gVirtualX->GetDefaultRootWindow(), bits.data(), ww, hh); + + return pixmap; } //////////////////////////////////////////////////////////////////////////////// diff --git a/graf2d/graf/inc/TImage.h b/graf2d/graf/inc/TImage.h index 17842ddff28a6..59b2af21a8553 100644 --- a/graf2d/graf/inc/TImage.h +++ b/graf2d/graf/inc/TImage.h @@ -18,6 +18,7 @@ #include "TAttImage.h" #include "GuiTypes.h" #include "TVectorDfwd.h" +#include class TVirtualPad; class TArrayD; @@ -132,7 +133,7 @@ friend TImage operator/(const TImage &i1, const TImage &s2); virtual void FromX11Window(Window_t /* win */ , Int_t /* x */, Int_t /* y */, Int_t /* width */, Int_t /* height */) {} // Create an image from gVirtualX window. (See TASImage::FromWindow) - virtual void FromWindow(Drawable_t /*wid*/, Int_t /*x*/ = 0, Int_t /*y*/ = 0, UInt_t /*w*/ = 0, UInt_t /*h*/ = 0) {} + virtual void R__DEPRECATED(7,00, "Use TGWindow::CreateImageFromWindow instead") FromWindow(Drawable_t /*wid*/, Int_t /*x*/ = 0, Int_t /*y*/ = 0, UInt_t /*w*/ = 0, UInt_t /*h*/ = 0) {} // Create an image from GL buffer. (See TASImage::FromGLBuffer) virtual void R__DEPRECATED(7,00, "Use FromBitmap instead") FromGLBuffer(UChar_t * /*buf*/, UInt_t /*w*/, UInt_t /*h*/) {} @@ -244,13 +245,17 @@ friend TImage operator/(const TImage &i1, const TImage &s2); virtual UInt_t GetWidth() const { return 0; } virtual UInt_t GetHeight() const { return 0; } + virtual UInt_t GetScaledWidth() const { return 0; } + virtual UInt_t GetScaledHeight() const { return 0; } virtual Bool_t IsValid() const { return kTRUE; } virtual TImage *GetScaledImage() const { return nullptr; } virtual TArrayL *GetPixels(Int_t /*x*/= 0, Int_t /*y*/= 0, UInt_t /*w*/ = 0, UInt_t /*h*/ = 0) { return nullptr; } virtual TArrayD *GetArray(UInt_t /*w*/ = 0, UInt_t /*h*/ = 0, TImagePalette * = gWebImagePalette) { return nullptr; } - virtual Pixmap_t GetPixmap() { return 0; } - virtual Pixmap_t GetMask() { return 0; } + virtual Pixmap_t GetX11Pixmap(Window_t /* root_window */) { return 0; } + virtual Pixmap_t R__DEPRECATED(7,00, "Use TGWindow::GetImagePixmap instead") GetPixmap() { return 0; } + virtual Bool_t GetMaskBits(UInt_t & /* width */, UInt_t & /* height */, std::vector & /* bits */) { return kFALSE; } + virtual Pixmap_t R__DEPRECATED(7,00, "Use TGWindow::GetImageMask instead") GetMask() { return 0; } virtual UInt_t *GetArgbArray() { return nullptr; } virtual UInt_t *GetRgbaArray() { return nullptr; } virtual Double_t *GetVecArray() { return nullptr; } diff --git a/gui/gui/inc/TGWindow.h b/gui/gui/inc/TGWindow.h index cc1105bd29329..ce65b8a825300 100644 --- a/gui/gui/inc/TGWindow.h +++ b/gui/gui/inc/TGWindow.h @@ -15,10 +15,11 @@ #include "TGObject.h" #include "TGClient.h" +#include class TGClient; class TGIdleHandler; - +class TImage; class TGWindow : public TGObject { @@ -125,6 +126,10 @@ friend class TGClient; static Int_t GetCounter(); + static std::unique_ptr CreateImageFromWindow(Drawable_t wid); + static Pixmap_t GetImagePixmap(TImage *img); + static Pixmap_t GetImageMask(TImage *img); + ClassDefOverride(TGWindow, 0); // GUI Window base class }; diff --git a/gui/gui/src/TGButton.cxx b/gui/gui/src/TGButton.cxx index 075225e19c907..ede2fe0b66382 100644 --- a/gui/gui/src/TGButton.cxx +++ b/gui/gui/src/TGButton.cxx @@ -1111,12 +1111,12 @@ void TGPictureButton::CreateDisabledPicture() TString back = gEnv->GetValue("Gui.BackgroundColor", "#c0c0c0"); img2->FillRectangle(back.Data(), 0, 0, fPic->GetWidth(), fPic->GetHeight()); img->SetImage(fPic->GetPicture(), fPic->GetMask()); - Pixmap_t mask = img->GetMask(); + Pixmap_t mask = GetImageMask(img); img2->Merge(img, "overlay"); TString name = "disbl_"; name += fPic->GetName(); - fPicD = fClient->GetPicturePool()->GetPicture(name.Data(), img2->GetPixmap(), + fPicD = fClient->GetPicturePool()->GetPicture(name.Data(), GetImagePixmap(img2), mask); fOwnDisabledPic = kTRUE; delete img; diff --git a/gui/gui/src/TGFSContainer.cxx b/gui/gui/src/TGFSContainer.cxx index 26f9c883215fe..3d2e23578fd3c 100644 --- a/gui/gui/src/TGFSContainer.cxx +++ b/gui/gui/src/TGFSContainer.cxx @@ -704,7 +704,7 @@ void TGFileContainer::GetFilePictures(const TGPicture **pic, lnk_name = ((const TGPicture *)*pic)->GetName(); lnk_name.Prepend("lnk_"); *pic = fClient->GetPicturePool()->GetPicture(lnk_name.Data(), - img1->GetPixmap(), img1->GetMask()); + GetImagePixmap(img1), GetImageMask(img1)); fCleanups->Add(((TObject *)*pic)); if (img2) delete img2; delete img1; @@ -718,7 +718,7 @@ void TGFileContainer::GetFilePictures(const TGPicture **pic, lnk_name = ((const TGPicture *)*lpic)->GetName(); lnk_name.Prepend("lnk_"); *lpic = fClient->GetPicturePool()->GetPicture(lnk_name.Data(), - img1->GetPixmap(), img1->GetMask()); + GetImagePixmap(img1), GetImageMask(img1)); fCleanups->Add(((TObject *)*lpic)); if (img2) delete img2; delete img1; diff --git a/gui/gui/src/TGFileBrowser.cxx b/gui/gui/src/TGFileBrowser.cxx index f7179b0ee4995..b2aa57e018d42 100644 --- a/gui/gui/src/TGFileBrowser.cxx +++ b/gui/gui/src/TGFileBrowser.cxx @@ -1160,19 +1160,17 @@ static Bool_t IsTextFile(const char *candidate) static const TGPicture *MakeLinkPic(const TGPicture *pic) { - const TGPicture *merged; - TImage *img1, *img2; if (pic) { - img1 = TImage::Create(); - if (img1 == 0) return pic; + auto img1 = TImage::Create(); + if (!img1) return pic; img1->SetImage(((const TGPicture *)pic)->GetPicture(), ((const TGPicture *)pic)->GetMask()); - img2 = TImage::Open("slink_t.xpm"); + auto img2 = TImage::Open("slink_t.xpm"); if (img2) img1->Merge(img2); TString lnk_name = ((const TGPicture *)pic)->GetName(); lnk_name.Prepend("lnk_"); - merged = gClient->GetPicturePool()->GetPicture(lnk_name.Data(), - img1->GetPixmap(), img1->GetMask()); + auto merged = gClient->GetPicturePool()->GetPicture(lnk_name.Data(), + TGWindow::GetImagePixmap(img1), TGWindow::GetImageMask(img1)); if (img2) delete img2; delete img1; return merged; @@ -1565,9 +1563,9 @@ char *TGFileBrowser::FormatFileInfo(const char *fname, Long64_t size, Long_t mod void TGFileBrowser::GetObjPicture(const TGPicture **pic, TObject *obj) { - const char *clname = 0; - TClass *objClass = 0; - static TImage *im = 0; + const char *clname = nullptr; + TClass *objClass = nullptr; + static TImage *im = nullptr; if (!im) { im = TImage::Create(); } @@ -1616,8 +1614,7 @@ void TGFileBrowser::GetObjPicture(const TGPicture **pic, TObject *obj) if (!(*pic) && xpm) { if (im && im->SetImageBuffer((char**)&name, TImage::kXpm)) { im->Scale(im->GetWidth()/4, im->GetHeight()/4); - *pic = gClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(), - im->GetMask()); + *pic = gClient->GetPicturePool()->GetPicture(iconname, TGWindow::GetImagePixmap(im), TGWindow::GetImageMask(im)); } gClient->GetMimeTypeList()->AddType("[thumbnail]", iconname, iconname, iconname, "->Browse()"); return; diff --git a/gui/gui/src/TGFrame.cxx b/gui/gui/src/TGFrame.cxx index cac75c9ed200d..625101cbb7d44 100644 --- a/gui/gui/src/TGFrame.cxx +++ b/gui/gui/src/TGFrame.cxx @@ -1556,8 +1556,6 @@ Bool_t TGMainFrame::SaveFrameAsCodeOrImage() Bool_t TGMainFrame::SaveFrameAsCodeOrImage(const TString &fileName) { - static TString dir("."); - const TString fname = gSystem->UnixPathName(fileName); if (fname.EndsWith(".C")) { TGMainFrame *main = (TGMainFrame*)GetMainFrame(); @@ -1580,12 +1578,11 @@ Bool_t TGMainFrame::SaveFrameAsCodeOrImage(const TString &fileName) if (gtype != TImage::kUnknown) { Int_t saver = gErrorIgnoreLevel; gErrorIgnoreLevel = kFatal; - TImage *img = TImage::Create(); RaiseWindow(); - img->FromWindow(GetId()); - img->WriteImage(fname, gtype); + auto img = TGWindow::CreateImageFromWindow(GetId()); + if (img) + img->WriteImage(fname, gtype); gErrorIgnoreLevel = saver; - delete img; } else { Error("SaveFrameAsCodeOrImage", "File cannot be saved with this extension"); return kFALSE; @@ -1836,7 +1833,7 @@ void TGMainFrame::SetIconPixmap(char **xpm_array) TImage *img = TImage::Create(); if (!img) return; img->SetImageBuffer(xpm_array, TImage::kXpm); - Pixmap_t pic = img->GetPixmap(); + Pixmap_t pic = GetImagePixmap(img); if (pic) { gVirtualX->SetIconPixmap(fId, pic); } else { diff --git a/gui/gui/src/TGIcon.cxx b/gui/gui/src/TGIcon.cxx index 6f77c403afea4..9547eda7f6654 100644 --- a/gui/gui/src/TGIcon.cxx +++ b/gui/gui/src/TGIcon.cxx @@ -57,7 +57,7 @@ TGIcon::TGIcon(const TGWindow *p, const char *image) : TGFrame(p, 1, 1) fImage = TImage::Open(path); if (fImage) { fPic = fClient->GetPicturePool()->GetPicture(gSystem->BaseName(path), - fImage->GetPixmap(), fImage->GetMask()); + GetImagePixmap(fImage), GetImageMask(fImage)); TGFrame::Resize(fImage->GetWidth(), fImage->GetHeight()); } SetWindowName(); @@ -155,7 +155,7 @@ void TGIcon::Resize(UInt_t w, UInt_t h) fImage->Scale(w - 2*border, h - 2*border); fPic = fClient->GetPicturePool()->GetPicture(fImage->GetName(), - fImage->GetPixmap(), fImage->GetMask()); + GetImagePixmap(fImage), GetImageMask(fImage)); DoRedraw(); } diff --git a/gui/gui/src/TGObject.cxx b/gui/gui/src/TGObject.cxx index b0dfc4cb28057..a62534698b0ea 100644 --- a/gui/gui/src/TGObject.cxx +++ b/gui/gui/src/TGObject.cxx @@ -32,7 +32,7 @@ is based on the XClass'95 code (see Copyleft in source). #include "TGObject.h" -#include "TVirtualX.h" +#include "TGWindow.h" #include "TImage.h" #include "TROOT.h" @@ -55,14 +55,9 @@ void TGObject::SaveAs(const char* filename /*= ""*/, Option_t* option /*= ""*/) { TImage::EImageFileTypes type = TImage::GetImageFileTypeFromFilename(filename); if (type != TImage::kUnknown) { - WindowAttributes_t wattr; - gVirtualX->GetWindowAttributes(GetId(), wattr); - TImage* img = TImage::Create(); - if (img) { - img->FromWindow(GetId(), 0, 0, wattr.fWidth, wattr.fHeight); + auto img = TGWindow::CreateImageFromWindow(GetId()); + if (img) img->WriteImage(filename, type); - delete img; - } return; } diff --git a/gui/gui/src/TGPicture.cxx b/gui/gui/src/TGPicture.cxx index 2776dbb6387ce..2dced4a815938 100644 --- a/gui/gui/src/TGPicture.cxx +++ b/gui/gui/src/TGPicture.cxx @@ -116,7 +116,7 @@ const TGPicture *TGPicturePool::GetPicture(const char *name) return nullptr; } - pic = new TGPicture(pname, img->GetPixmap(), img->GetMask()); + pic = new TGPicture(pname, TGWindow::GetImagePixmap(img), TGWindow::GetImageMask(img)); delete img; fPicList->Add(pic); return pic; @@ -192,7 +192,7 @@ const TGPicture *TGPicturePool::GetPicture(const char *name, img->Scale(new_width, new_height); - pic = new TGPicture(hname, img->GetPixmap(), img->GetMask()); + pic = new TGPicture(hname, TGWindow::GetImagePixmap(img), TGWindow::GetImageMask(img)); delete [] picnam; delete img; fPicList->Add(pic); @@ -271,7 +271,7 @@ const TGPicture *TGPicturePool::GetPicture(const char *name, char **xpm) return 0; } - pic = new TGPicture(hname, img->GetPixmap(), img->GetMask()); + pic = new TGPicture(hname, TGWindow::GetImagePixmap(img), TGWindow::GetImageMask(img)); delete img; return pic; } diff --git a/gui/gui/src/TGScrollBar.cxx b/gui/gui/src/TGScrollBar.cxx index 9c2cc2bcd80d4..707e145e7ea3a 100644 --- a/gui/gui/src/TGScrollBar.cxx +++ b/gui/gui/src/TGScrollBar.cxx @@ -167,12 +167,12 @@ void TGScrollBarElement::SetEnabled(Bool_t on) TString back = gEnv->GetValue("Gui.BackgroundColor", "#c0c0c0"); img2->FillRectangle(back.Data(), 0, 0, fPic->GetWidth(), fPic->GetHeight()); img->SetImage(fPicN->GetPicture(), fPicN->GetMask()); - Pixmap_t mask = img->GetMask(); + Pixmap_t mask = GetImageMask(img); img2->Merge(img, "overlay"); TString name = "disbl_"; name += fPic->GetName(); - fPicD = fClient->GetPicturePool()->GetPicture(name.Data(), img2->GetPixmap(), + fPicD = fClient->GetPicturePool()->GetPicture(name.Data(), GetImagePixmap(img2), mask); delete img; delete img2; diff --git a/gui/gui/src/TGShapedFrame.cxx b/gui/gui/src/TGShapedFrame.cxx index 6929f6d5b4acd..3a425258353dd 100644 --- a/gui/gui/src/TGShapedFrame.cxx +++ b/gui/gui/src/TGShapedFrame.cxx @@ -29,7 +29,7 @@ A Shaped window TGShapedFrame::TGShapedFrame(const char *pname, const TGWindow *p, UInt_t w, UInt_t h, UInt_t options) : - TGCompositeFrame(p, w, h, options), fBgnd(0), fImage(0) + TGCompositeFrame(p, w, h, options), fBgnd(nullptr), fImage(nullptr) { TString picName; // set a few attributes @@ -50,8 +50,7 @@ TGShapedFrame::TGShapedFrame(const char *pname, const TGWindow *p, UInt_t w, Error("TGShapedFrame", "%s not found", picName.Data()); return; } - fBgnd = fClient->GetPicturePool()->GetPicture(picName.Data(), - fImage->GetPixmap(), fImage->GetMask()); + fBgnd = fClient->GetPicturePool()->GetPicture(picName.Data(), GetImagePixmap(fImage), GetImageMask(fImage)); // shape the window with the picture mask gVirtualX->ShapeCombineMask(fId, 0, 0, fBgnd->GetMask()); // and finally set the background picture diff --git a/gui/gui/src/TGSlider.cxx b/gui/gui/src/TGSlider.cxx index 2458afb6df353..5ed270c90188e 100644 --- a/gui/gui/src/TGSlider.cxx +++ b/gui/gui/src/TGSlider.cxx @@ -140,13 +140,12 @@ void TGSlider::CreateDisabledPicture() img2->FillRectangle(back.Data(), 0, 0, fSliderPic->GetWidth(), fSliderPic->GetHeight()); img->SetImage(fSliderPic->GetPicture(), fSliderPic->GetMask()); - Pixmap_t mask = img->GetMask(); + Pixmap_t mask = GetImageMask(img); img2->Merge(img, "overlay"); TString name = "disbl_"; name += fSliderPic->GetName(); - fDisabledPic = fClient->GetPicturePool()->GetPicture(name.Data(), - img2->GetPixmap(), mask); + fDisabledPic = fClient->GetPicturePool()->GetPicture(name.Data(), GetImagePixmap(img2), mask); delete img; delete img2; } diff --git a/gui/gui/src/TGSpeedo.cxx b/gui/gui/src/TGSpeedo.cxx index 95c7ededd2bdd..b0373e4169d05 100644 --- a/gui/gui/src/TGSpeedo.cxx +++ b/gui/gui/src/TGSpeedo.cxx @@ -136,7 +136,7 @@ void TGSpeedo::Build() if (fImage && fImage->IsValid()) { fBase = fClient->GetPicturePool()->GetPicture(gSystem->BaseName(fPicName.Data()), - fImage->GetPixmap(), fImage->GetMask()); + GetImagePixmap(fImage), GetImageMask(fImage)); // center of the image Float_t xc = (Float_t)(fBase ? (fBase->GetWidth() + 1) / 2 : 96.0); Float_t yc = (Float_t)(fBase ? (fBase->GetHeight() + 1) / 2 : 96.0); diff --git a/gui/gui/src/TGWindow.cxx b/gui/gui/src/TGWindow.cxx index 6ef5a7223b7d8..4306e9031c835 100644 --- a/gui/gui/src/TGWindow.cxx +++ b/gui/gui/src/TGWindow.cxx @@ -32,9 +32,11 @@ ROOT GUI Window base class. #include "TGWindow.h" #include #include "TVirtualX.h" +#include "TVirtualPad.h" #include "TApplication.h" #include "TError.h" #include "TSystem.h" +#include "TImage.h" Int_t TGWindow::fgCounter = 0; @@ -354,3 +356,92 @@ const char *TGWindow::GetName()const return fName.Data(); } + + +//////////////////////////////////////////////////////////////////////////////// +/// Create TImage object with content of displayed window + +std::unique_ptr TGWindow::CreateImageFromWindow(Drawable_t wid) +{ + std::unique_ptr img(TImage::Create()); + if (!img) { + ::Error("TGWindow::CreateImageFromWindow", "Fail to create TImage object"); + return nullptr; + } + gVirtualX->Update(1); + if (!gThreadXAR) { + gSystem->Sleep(10); + gSystem->ProcessEvents(); + gSystem->Sleep(10); + gSystem->ProcessEvents(); + } + + Int_t x = 0, y = 0; + UInt_t w = 0, h = 0; + + gVirtualX->GetWindowSize(wid, x, y, w, h); + + (void) x; // position of window is not used + (void) y; + + static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); + + if (x11) { + img->FromX11Window(wid, 0, 0, w, h); + } else { + unsigned char *bits = gVirtualX->GetColorBits(wid, 0, 0, w, h); + if (!bits) { + ::Error("TGWindow::CreateImageFromWindow", "Fail to extract color bits for specified window"); + return nullptr; + } + img->FromBitmap(bits, w, h); + delete [] bits; + } + + return img; +} + +//////////////////////////////////////////////////////////////////////////////// +/// Returns image pixmap. +/// The pixmap must deleted by user. +/// Replacement for deprecated TImage::GetPixmap method + +Pixmap_t TGWindow::GetImagePixmap(TImage *img) +{ + if (!img) { + ::Error("TGWindow::GetImagePixmap", "Image not provided"); + return 0; + } + static Bool_t x11 = gVirtualX->InheritsFrom("TGX11"); + + if (x11) + return img->GetX11Pixmap(gVirtualX->GetDefaultRootWindow()); + + auto argb = img->GetArgbArray(); + if (!argb) { + ::Error("TGWindow::GetImagePixmap", "ARGB array is not exists"); + return 0; + } + + return gVirtualX->CreatePixmapFromData((unsigned char*) argb, img->GetScaledWidth(), img->GetScaledHeight()); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Returns image mask pixmap (alpha channel). +/// The pixmap must deleted by user. +/// Replacement for deprecated TImage::GetMask() method + +Pixmap_t TGWindow::GetImageMask(TImage *img) +{ + Pixmap_t pixmap = 0; + + UInt_t width = 0, height = 0; + std::vector bits; + + if (!img) + ::Error("TGWindow::GetImageMask", "Image not provided"); + else if (img->GetMaskBits(width, height, bits)) + pixmap = gVirtualX->CreateBitmap(gVirtualX->GetDefaultRootWindow(), bits.data(), width, height); + + return pixmap; +} diff --git a/gui/gui/src/TRootBrowserLite.cxx b/gui/gui/src/TRootBrowserLite.cxx index c46f19fb88d2e..41d8190a9c31d 100644 --- a/gui/gui/src/TRootBrowserLite.cxx +++ b/gui/gui/src/TRootBrowserLite.cxx @@ -503,11 +503,11 @@ void TRootIconBox::GetObjPictures(const TGPicture **pic, const TGPicture **spic, if (!(*pic) && xpm) { if (im && im->SetImageBuffer((char**)&name, TImage::kXpm)) { - *pic = fClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(), - im->GetMask()); + *pic = fClient->GetPicturePool()->GetPicture(iconname, GetImagePixmap(im), + GetImageMask(im)); im->Scale(im->GetWidth()/2, im->GetHeight()/2); - *spic = fClient->GetPicturePool()->GetPicture(iconname, im->GetPixmap(), - im->GetMask()); + *spic = fClient->GetPicturePool()->GetPicture(iconname, GetImagePixmap(im), + GetImageMask(im)); } fClient->GetMimeTypeList()->AddType("[thumbnail]", iconname, iconname, iconname, "->Browse()"); @@ -1746,9 +1746,9 @@ void TRootBrowserLite::ExecuteDefaultAction(TObject *obj) img->Merge(img, "tint"); // contrasting img->DrawBox(0, 0, w, h, "#ffff00", 1); // yellow frame - pic = fClient->GetPicturePool()->GetPicture(path.Data(), img->GetPixmap(), 0); + pic = fClient->GetPicturePool()->GetPicture(path.Data(), GetImagePixmap(img), 0); img->Scale(w/3, h/3); - spic = fClient->GetPicturePool()->GetPicture(path.Data(), img->GetPixmap(), 0); + spic = fClient->GetPicturePool()->GetPicture(path.Data(), GetImagePixmap(img), 0); thumb = new TIconBoxThumb(path.Data(), spic, pic); fIconBox->fThumbnails->Add(thumb); diff --git a/gui/guibuilder/src/TGuiBldDragManager.cxx b/gui/guibuilder/src/TGuiBldDragManager.cxx index 37d096771ae54..86272f37864ce 100644 --- a/gui/guibuilder/src/TGuiBldDragManager.cxx +++ b/gui/guibuilder/src/TGuiBldDragManager.cxx @@ -918,7 +918,7 @@ TGuiBldDragManager::TGuiBldDragManager() : TVirtualDragManager() , TString tmpfile = gSystem->TempDirectory(); fPasteFileName = TString::Format("RootGuiBldClipboard%d.C", gSystem->GetPid()); gSystem->PrependPathName(tmpfile.Data(), fPasteFileName); - + fTmpBuildFile = TString::Format("RootGuiBldTmpFile%d.C", gSystem->GetPid()); gSystem->PrependPathName(tmpfile.Data(), fTmpBuildFile); @@ -3294,12 +3294,9 @@ Bool_t TGuiBldDragManager::Save(const char *file) root->SetEditable(kFALSE); - static TImage *img = 0; + static std::unique_ptr img; - if (!img) { - img = TImage::Create(); - } - img->FromWindow(main->GetId()); + img = TGWindow::CreateImageFromWindow(main->GetId()); if (!file || !file[0]) { static TString dir("."); @@ -3329,7 +3326,7 @@ Bool_t TGuiBldDragManager::Save(const char *file) main->SaveSource(fname.Data(), file ? "keep_names quiet" : "keep_names"); if (fBuilder) - fBuilder->AddMacro(fname.Data(), img); + fBuilder->AddMacro(fname.Data(), img.get()); } else { Int_t retval; @@ -3363,12 +3360,9 @@ Bool_t TGuiBldDragManager::SaveFrame(const char *file) TGFrame *frame = fPimpl->fGrab; SetEditable(kFALSE); - static TImage *img = 0; + static std::unique_ptr img; - if (!img) { - img = TImage::Create(); - } - img->FromWindow(frame->GetId()); + img = TGWindow::CreateImageFromWindow(frame->GetId()); static TString dir("."); static Bool_t overwr = kFALSE; @@ -3412,7 +3406,7 @@ Bool_t TGuiBldDragManager::SaveFrame(const char *file) HandleCopy(kFALSE); fStop = kTRUE; - fBuilder->AddMacro(fname.Data(), img); + fBuilder->AddMacro(fname.Data(), img.get()); } else { Int_t retval; TString msg = TString::Format("file (%s) must have extension .C", fname.Data()); diff --git a/gui/guibuilder/src/TRootGuiBuilder.cxx b/gui/guibuilder/src/TRootGuiBuilder.cxx index d3e42ff307b5c..af371cf6c0505 100644 --- a/gui/guibuilder/src/TRootGuiBuilder.cxx +++ b/gui/guibuilder/src/TRootGuiBuilder.cxx @@ -1599,12 +1599,9 @@ Bool_t TRootGuiBuilder::SaveProject(Event_t *event) TGMdiFrame *savfr = fMain->GetCurrent(); if (!savfr) return kFALSE; - static TImage *img = 0; + static std::unique_ptr img; - if (!img) { - img = TImage::Create(); - } - img->FromWindow(savfr->GetParent()->GetId()); + img = TGWindow::CreateImageFromWindow(savfr->GetParent()->GetId()); TGWindow *root = (TGWindow*)fClient->GetRoot(); TGFileInfo fi; @@ -1656,7 +1653,7 @@ Bool_t TRootGuiBuilder::SaveProject(Event_t *event) savfr->SetName(name.Data()); - AddMacro(fname.Data(), img); + AddMacro(fname.Data(), img.get()); delete main; } else { Int_t retval; @@ -1693,7 +1690,7 @@ void TRootGuiBuilder::AddMacro(const char *macro, TImage *img) static int i = 0; const TGPicture *pic = fClient->GetPicturePool()->GetPicture( TString::Format("%s;%d", macro, i++), - img->GetPixmap(),img->GetMask()); + GetImagePixmap(img), GetImageMask(img)); const char *name = gSystem->BaseName(macro); TGButton *btn = FindActionButton(name, "User's Macros"); diff --git a/gui/guihtml/src/TGHtmlDraw.cxx b/gui/guihtml/src/TGHtmlDraw.cxx index 7d512655f3fc1..e275c017d75e9 100644 --- a/gui/guihtml/src/TGHtmlDraw.cxx +++ b/gui/guihtml/src/TGHtmlDraw.cxx @@ -891,12 +891,13 @@ void TGHtml::DrawTableBgnd(int l, int t, int w, int h, w -= sw; } #else - if (!image->GetPixmap()) return; + auto img_pixmap = TGWindow::GetImagePixmap(image); + if (!img_pixmap) return; GContext_t gc = GetAnyGC(); GCValues_t gcv; // unsigned int mask = kGCTile | kGCFillStyle | // kGCTileStipXOrigin | kGCTileStipYOrigin; - gcv.fTile = image->GetPixmap(); + gcv.fTile = img_pixmap; gcv.fFillStyle = kFillTiled; gcv.fTsXOrigin = -fVisible.fX - fDirtyLeft; gcv.fTsYOrigin = -fVisible.fY - fDirtyTop; diff --git a/gui/guihtml/src/TGHtmlSizer.cxx b/gui/guihtml/src/TGHtmlSizer.cxx index 1bff78afe18ad..46dff10b952fb 100644 --- a/gui/guihtml/src/TGHtmlSizer.cxx +++ b/gui/guihtml/src/TGHtmlSizer.cxx @@ -353,10 +353,10 @@ void TGHtml::AddStyle(TGHtmlElement *p) // unsigned int mask; // mask = kGCTile | kGCFillStyle | kGCGraphicsExposures; - gcv.fTile = img->GetPixmap(); + gcv.fTile = TGWindow::GetImagePixmap(img); gcv.fFillStyle = kFillTiled; gcv.fGraphicsExposures = kTRUE; - fCanvas->SetBackgroundPixmap(img->GetPixmap()); + fCanvas->SetBackgroundPixmap(TGWindow::GetImagePixmap(img)); gVirtualX->ChangeGC(fWhiteGC.GetGC(), &gcv); diff --git a/test/stressGUI.cxx b/test/stressGUI.cxx index 98d47d5d66ce8..52f9b4b407b72 100644 --- a/test/stressGUI.cxx +++ b/test/stressGUI.cxx @@ -174,10 +174,10 @@ void ProcessFrame(TGFrame *f, const char *title) else outfile.Form("sgui_%02d.png", gTestNum); - TImage *img = TImage::Create(); f->RaiseWindow(); - img->FromWindow(f->GetId()); - img->WriteImage(outfile); + auto img = TGWindow::CreateImageFromWindow(f->GetId()); + if (img) + img->WriteImage(outfile); if (!gOptionRef) { if (!strstr(title, "Pack Frames")) { @@ -191,7 +191,6 @@ void ProcessFrame(TGFrame *f, const char *title) } VerifySize(outfile, title); - delete img; gErrorIgnoreLevel = 0; gTestNum++; } diff --git a/tutorials/visualisation/gui/drag_and_drop.C b/tutorials/visualisation/gui/drag_and_drop.C index 0dddcad048f8a..63bdaded3acdb 100644 --- a/tutorials/visualisation/gui/drag_and_drop.C +++ b/tutorials/visualisation/gui/drag_and_drop.C @@ -195,7 +195,7 @@ DNDMainFrame::DNDMainFrame(const TGWindow *p, int w, int h) : TGMainFrame(p, w, if (img) { // create a 16x16 icon from the original picture img->Scale(16, 16); - pic = gClient->GetPicturePool()->GetPicture("rose512", img->GetPixmap(), img->GetMask()); + pic = gClient->GetPicturePool()->GetPicture("rose512", TGWindow::GetImagePixmap(img), TGWindow::GetImageMask(img)); delete img; } else pic = gClient->GetPicture("psp_t.xpm"); @@ -284,7 +284,7 @@ void DNDMainFrame::DataDropped(TGListTreeItem *, TDNDData *data) TImage *img2 = TImage::Open("slink_t.xpm"); if (img1 && img2) { img1->Merge(img2); - pic = gClient->GetPicturePool()->GetPicture("doc_lnk", img1->GetPixmap(), img1->GetMask()); + pic = gClient->GetPicturePool()->GetPicture("doc_lnk", TGWindow::GetImagePixmap(img1), TGWindow::GetImageMask(img1)); delete img2; delete img1; } else diff --git a/tutorials/visualisation/gui/exec_macro.C b/tutorials/visualisation/gui/exec_macro.C index b2b322f362f61..da6ad424c73db 100644 --- a/tutorials/visualisation/gui/exec_macro.C +++ b/tutorials/visualisation/gui/exec_macro.C @@ -48,9 +48,8 @@ Int_t exec_macro(const char *macro, Bool_t comp = kFALSE, Bool_t save = kTRUE) UInt_t nMainFrames = 0; TClass *clGMainFrame = TClass::GetClass("TGMainFrame"); - TGWindow *win = nullptr; TIter iWin(gClient->GetListOfWindows()); - while ((win = (TGWindow *)iWin())) { + while (auto win = (TGWindow *)iWin()) { const TObject *winGetParent = win->GetParent(); Bool_t winIsMapped = kFALSE; if (winGetParent == gClient->GetDefaultRoot()) @@ -60,11 +59,11 @@ Int_t exec_macro(const char *macro, Bool_t comp = kFALSE, Bool_t save = kTRUE) if (save) { TString outfile = gSystem->BaseName(macro); outfile.ReplaceAll(".C", TString::Format("_%d.png", ++nMainFrames)); - TImage *img = TImage::Create(); win->RaiseWindow(); - img->FromWindow(win->GetId()); - img->WriteImage(outfile.Data()); - delete img; + + auto img = TGWindow::CreateImageFromWindow(win->GetId()); + if (img) + img->WriteImage(outfile.Data()); } } }