tdf#144624 Prevent infinite recursion when loading SVG icon

When Generic/X11 VCL backend plugin loads SVG icon,
it creates virtual device for rasterizing an SVG icon,
which in turn tries to load an SVG icon,
and thus infinite recursion happens.

Change-Id: I7559b6255e6718e64ef4a6e7c79d597375e5823a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122344
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/tools/wintypes.hxx b/include/tools/wintypes.hxx
index fcccd9a..1bc5178 100644
--- a/include/tools/wintypes.hxx
+++ b/include/tools/wintypes.hxx
@@ -229,6 +229,8 @@
WinBits const WB_HIDESELECTION =        SAL_CONST_INT64(0x002000000000);
// DO NOT USE: 0x008000000000, that's WB_SYSTEMCHILDWINDOW

// tdf#144624: special bit used to skip assigning icon to virtual window
WinBits const WB_NOICON =               SAL_CONST_INT64(0x200000000000);

enum class WindowAlign { Left, Top, Right, Bottom };

diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index 519aad8..e7b3c3b 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -824,7 +824,7 @@

     @see GetFocusWindow
    */
    static OutputDevice*        GetDefaultDevice();
    static OutputDevice*        GetDefaultDevice(bool bUseIcon = true);

    /** Get the first top-level window of the application.

diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx
index 6525ab1..ac8840b4 100644
--- a/vcl/inc/salframe.hxx
+++ b/vcl/inc/salframe.hxx
@@ -80,6 +80,8 @@
    INTRO               = 0x00000100,
    // partial fullscreen: fullscreen on one monitor of a multimonitor display
    PARTIAL_FULLSCREEN  = 0x00800000,
    // tdf#144624: don't set icon
    NOICON              = 0x01000000,
    // system child window inside another SalFrame
    SYSTEMCHILD         = 0x08000000,
    // plugged system child window
@@ -91,7 +93,7 @@
};

namespace o3tl {
    template<> struct typed_flags<SalFrameStyleFlags> : is_typed_flags<SalFrameStyleFlags, 0x788001ff> {};
    template<> struct typed_flags<SalFrameStyleFlags> : is_typed_flags<SalFrameStyleFlags, 0x798001ff> {};
};

// Extended frame style (sal equivalent to extended WinBits)
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index d428b5b..cadc35c 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -428,8 +428,8 @@

void        ImplDeInitSVData();
VCL_PLUGIN_PUBLIC basegfx::SystemDependentDataManager& ImplGetSystemDependentDataManager();
VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow();
vcl::Window* ImplGetDefaultContextWindow();
VCL_PLUGIN_PUBLIC vcl::Window* ImplGetDefaultWindow(bool bUseIcon = true);
vcl::Window* ImplGetDefaultContextWindow(bool bUseIcon = true);
const std::locale& ImplGetResLocale();
VCL_PLUGIN_PUBLIC OUString VclResId(TranslateId sContextAndId);
DockingManager*     ImplGetDockingManager();
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 66c030d..515c97f 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1066,9 +1066,9 @@
    return ImplGetSVData()->mpWinData->mpFocusWin;
}

OutputDevice* Application::GetDefaultDevice()
OutputDevice* Application::GetDefaultDevice(bool bUseIcon)
{
    return ImplGetDefaultWindow()->GetOutDev();
    return ImplGetDefaultWindow(bUseIcon)->GetOutDev();
}

vcl::Window* Application::GetFirstTopLevelWindow()
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 61a766b..c8b0c15 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -206,17 +206,17 @@
}

/// Returns either the application window, or the default GL context window
vcl::Window* ImplGetDefaultWindow()
vcl::Window* ImplGetDefaultWindow(bool bUseIcon)
{
    ImplSVData* pSVData = ImplGetSVData();
    if (pSVData->maFrameData.mpAppWin)
        return pSVData->maFrameData.mpAppWin;
    else
        return ImplGetDefaultContextWindow();
        return ImplGetDefaultContextWindow(bUseIcon);
}

/// returns the default window created to hold the persistent VCL GL context.
vcl::Window *ImplGetDefaultContextWindow()
vcl::Window *ImplGetDefaultContextWindow(bool bUseIcon)
{
    ImplSVData* pSVData = ImplGetSVData();

@@ -231,7 +231,7 @@
            {
                SAL_INFO( "vcl", "ImplGetDefaultWindow(): No AppWindow" );

                pSVData->mpDefaultWin = VclPtr<WorkWindow>::Create( nullptr, WB_DEFAULTWIN );
                pSVData->mpDefaultWin = VclPtr<WorkWindow>::Create( nullptr, bUseIcon ? WB_DEFAULTWIN : WB_DEFAULTWIN | WB_NOICON );
                pSVData->mpDefaultWin->SetText( "VCL ImplGetDefaultWindow" );
            }
            catch (const css::uno::Exception&)
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
index 77f364a..c539f3d 100644
--- a/vcl/source/gdi/virdev.cxx
+++ b/vcl/source/gdi/virdev.cxx
@@ -205,7 +205,7 @@
                            << ", " << static_cast<int>(eAlphaFormat)
                            << ", " << static_cast<int>(eOutDevType) << " )" );

    ImplInitVirDev(pCompDev ? pCompDev : Application::GetDefaultDevice(), 0, 0);
    ImplInitVirDev(pCompDev ? pCompDev : Application::GetDefaultDevice(false), 0, 0);
}

VirtualDevice::VirtualDevice(const SystemGraphicsData& rData, const Size &rSize,
diff --git a/vcl/source/window/brdwin.cxx b/vcl/source/window/brdwin.cxx
index 95d508c..7cd7bb4 100644
--- a/vcl/source/window/brdwin.cxx
+++ b/vcl/source/window/brdwin.cxx
@@ -1499,7 +1499,7 @@
{
    // remove all unwanted WindowBits
    WinBits nOrgStyle = nStyle;
    WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW  | WB_POPUP);
    WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW  | WB_POPUP | WB_NOICON);
    if ( nTypeStyle & BorderWindowStyle::App )
        nTestStyle |= WB_APP;
    nStyle &= nTestStyle;
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 3f4f764..e6ed7b3 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1032,6 +1032,9 @@
                break;
        }

        if( nStyle & WB_NOICON )
            nFrameStyle |= SalFrameStyleFlags::NOICON;

        SalFrame* pParentFrame = nullptr;
        if ( pParent )
            pParentFrame = pParent->mpWindowImpl->mpFrame;
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index d08bd9d..03b7f1b 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -561,7 +561,7 @@
        if( IsOverrideRedirect() )
            Attributes.override_redirect = True;
        // default icon
        if( !(nStyle_ & SalFrameStyleFlags::INTRO) )
        if( !(nStyle_ & SalFrameStyleFlags::INTRO) && !(nStyle_ & SalFrameStyleFlags::NOICON))
        {
            bool bOk=false;
            try