/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "tools/debug.hxx"

#include "sal/alloca.h"

#include "vcl/floatwin.hxx"
#include "vcl/svapp.hxx"
#include "vcl/keycodes.hxx"
#include "vcl/printerinfomanager.hxx"
#include "vcl/settings.hxx"

#include <tools/prex.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include "FWS.hxx"
#include <X11/extensions/shape.h>
#ifndef SOLARIS
#include <X11/extensions/dpms.h>
#endif
#include <tools/postx.h>

#include "unx/salunx.h"
#include "unx/saldata.hxx"
#include "unx/saldisp.hxx"
#include "unx/salgdi.h"
#include "unx/salframe.h"
#include "unx/soicon.hxx"
#include "unx/dtint.hxx"
#include "unx/sm.hxx"
#include "unx/wmadaptor.hxx"
#include "unx/salprn.h"
#include "unx/salbmp.h"
#include "unx/i18n_ic.hxx"
#include "unx/i18n_keysym.hxx"
#include "unx/i18n_status.hxx"

#include "salinst.hxx"
#include "sallayout.hxx"

#include <com/sun/star/uno/Exception.hpp>

#include <algorithm>

#ifndef Button6
# define Button6 6
#endif
#ifndef Button7
# define Button7 7
#endif

using namespace vcl_sal;
using namespace vcl;

// -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define CLIENT_EVENTS			StructureNotifyMask \
								| SubstructureNotifyMask \
								| KeyPressMask \
								| KeyReleaseMask \
								| ButtonPressMask \
								| ButtonReleaseMask \
								| PointerMotionMask \
								| EnterWindowMask \
								| LeaveWindowMask \
								| FocusChangeMask \
								| ExposureMask \
								| VisibilityChangeMask \
								| PropertyChangeMask \
								| ColormapChangeMask

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

static XLIB_Window	hPresentationWindow = None, hPresFocusWindow = None;
static ::std::list< XLIB_Window > aPresentationReparentList;
static int			nVisibleFloats		= 0;

X11SalFrame* X11SalFrame::s_pSaveYourselfFrame = NULL;

// -=-= C++ statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
static void doReparentPresentationDialogues( SalDisplay* pDisplay )
{
    pDisplay->GetXLib()->PushXErrorLevel( true );
    while( aPresentationReparentList.begin() != aPresentationReparentList.end() )
    {
        int x, y;
        XLIB_Window aRoot, aChild;
        unsigned int w, h, bw, d;
        XGetGeometry( pDisplay->GetDisplay(),
                      aPresentationReparentList.front(),
                      &aRoot,
                      &x, &y, &w, &h, &bw, &d );
        XTranslateCoordinates( pDisplay->GetDisplay(),
                               hPresentationWindow,
                               aRoot,
                               x, y,
                               &x, &y,
                               &aChild );
        XReparentWindow( pDisplay->GetDisplay(),
                         aPresentationReparentList.front(),
                         aRoot,
                         x, y );
        aPresentationReparentList.pop_front();
    }
    if( hPresFocusWindow )
        XSetInputFocus( pDisplay->GetDisplay(), hPresFocusWindow, PointerRoot, CurrentTime );
    XSync( pDisplay->GetDisplay(), False );
    pDisplay->GetXLib()->PopXErrorLevel();
}

// -=-= SalFrame / X11SalFrame =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

bool X11SalFrame::IsOverrideRedirect() const
{
    return
        ((nStyle_ & SAL_FRAME_STYLE_INTRO) && !pDisplay_->getWMAdaptor()->supportsSplash())
        ||
        (!( nStyle_ & ~SAL_FRAME_STYLE_DEFAULT ) && !pDisplay_->getWMAdaptor()->supportsFullScreen())
        ;
}

bool X11SalFrame::IsFloatGrabWindow() const
{
    static const char* pDisableGrab = getenv( "SAL_DISABLE_FLOATGRAB" );

    return
        ( ( !pDisableGrab || !*pDisableGrab ) &&
          (
           (nStyle_ & SAL_FRAME_STYLE_FLOAT)	&&
           ! (nStyle_ & SAL_FRAME_STYLE_TOOLTIP)	&&
           ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
           )
          );
}

void X11SalFrame::setXEmbedInfo()
{
    if( m_bXEmbed )
    {
        long aInfo[2];
        aInfo[0] = 1; // XEMBED protocol version
        aInfo[1] = (bMapped_ ? 1 : 0); // XEMBED_MAPPED
        XChangeProperty( pDisplay_->GetDisplay(),
                         mhWindow,
                         pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ),
                         pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ),
                         32,
                         PropModeReplace,
                         reinterpret_cast<unsigned char*>(aInfo),
                         sizeof(aInfo)/sizeof(aInfo[0]) );
    }
}

void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode )
{
    XEvent aEvent;
    
    rtl_zeroMemory( &aEvent, sizeof(aEvent) );
    aEvent.xclient.window = mhForeignParent;
    aEvent.xclient.type = ClientMessage;
    aEvent.xclient.message_type = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED );
    aEvent.xclient.format = 32;
    aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime;
    aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS
    aEvent.xclient.data.l[2] = 0;
    aEvent.xclient.data.l[3] = 0;
    aEvent.xclient.data.l[4] = 0;
    
    GetDisplay()->GetXLib()->PushXErrorLevel( true );
    XSendEvent( pDisplay_->GetDisplay(),
                mhForeignParent,
                False, NoEventMask, &aEvent );
    XSync( pDisplay_->GetDisplay(), False );
    GetDisplay()->GetXLib()->PopXErrorLevel();
}


// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::Init( sal_uLong nSalFrameStyle, int nScreen, SystemParentData* pParentData, bool bUseGeometry )
{
    if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
        nScreen = GetDisplay()->GetDefaultScreenNumber();
    if( mpParent )
        nScreen = mpParent->m_nScreen;
    
    m_nScreen   = nScreen;
	nStyle_ 	= nSalFrameStyle;
	XWMHints Hints;
    Hints.flags = InputHint;
    Hints.input = (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? False : True;

    int x = 0, y = 0;
    unsigned int w = 500, h = 500;
    XSetWindowAttributes Attributes;

    int nAttrMask =   CWBorderPixel
                    | CWBackPixmap
                    | CWColormap
                    | CWOverrideRedirect
                    | CWEventMask
                    ;
    Attributes.border_pixel             = 0;
    Attributes.background_pixmap		= None;
    Attributes.colormap					= GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
    Attributes.override_redirect		= False;
    Attributes.event_mask				= CLIENT_EVENTS;
    
    const SalVisual& rVis = GetDisplay()->GetVisual( m_nScreen );
    XLIB_Window aFrameParent = pParentData ? pParentData->aWindow : GetDisplay()->GetRootWindow( m_nScreen );
    XLIB_Window aClientLeader = None;
    
    if( bUseGeometry )
    {
        x = maGeometry.nX;
        y = maGeometry.nY;
        w = maGeometry.nWidth;
        h = maGeometry.nHeight;
    }
    
    if( (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT) &&
        ! (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
        )
	{
        if( nShowState_ == SHOWSTATE_UNKNOWN )
        {
            w = 10;
            h = 10;
        }
        Attributes.override_redirect = True;
	}
    else if( (nSalFrameStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) )
    {
        DBG_ASSERT( mpParent, "SAL_FRAME_STYLE_SYSTEMCHILD window without parent" );
        if( mpParent )
        {
            aFrameParent = mpParent->mhWindow;
            // FIXME: since with SAL_FRAME_STYLE_SYSTEMCHILD
            // multiple X11SalFrame objects can have the same shell window
            // dispatching events in saldisp.cxx is unclear (the first frame)
            // wins. HTH this correctly is unclear yet
            // for the time being, treat set the shell window to own window
            // like for a normal frame
            // mhShellWindow = mpParent->GetShellWindow();
        }
    }
	else if( pParentData )
	{
        // plugin parent may be killed unexpectedly by
        // plugging process; ignore XErrors in that case
        GetDisplay()->setHaveSystemChildFrame();

		nStyle_ |= SAL_FRAME_STYLE_PLUG;
        Attributes.override_redirect = True;
        if( pParentData->nSize >= sizeof(SystemParentData) )
            m_bXEmbed = pParentData->bXEmbedSupport;

		int x_ret, y_ret;
		unsigned int bw, d;
		XLIB_Window aRoot, aParent;

		XGetGeometry( GetXDisplay(), pParentData->aWindow,
					  &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d );
		mhForeignParent = pParentData->aWindow;

		mhShellWindow = aParent = mhForeignParent;
		XLIB_Window* pChildren;
		unsigned int nChildren;
        bool bBreak = false;
		do
		{
			XQueryTree( GetDisplay()->GetDisplay(), mhShellWindow,
						&aRoot, &aParent, &pChildren, &nChildren );
			XFree( pChildren );
			if( aParent != aRoot )
				mhShellWindow = aParent;
            int nCount = 0;
            Atom* pProps = XListProperties( GetDisplay()->GetDisplay(),
                                            mhShellWindow,
                                            &nCount );
            for( int i = 0; i < nCount && ! bBreak; ++i )
                bBreak = (pProps[i] == XA_WM_HINTS);
            if( pProps )
                XFree( pProps );
		} while( aParent != aRoot && ! bBreak );

		// check if this is really one of our own frames
		// do not change the input mask in that case
        const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
        std::list< SalFrame* >::const_iterator it = rFrames.begin();
        while( it != rFrames.end() && mhForeignParent != static_cast<const X11SalFrame*>(*it)->GetWindow() )
            ++it;

		if( it == rFrames.end() )
		{
			XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent, StructureNotifyMask | FocusChangeMask );
			XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow, StructureNotifyMask | FocusChangeMask );
		}
    }
    else
    {
        if( ! bUseGeometry )
        {
            Size aScreenSize( GetDisplay()->getDataForScreen( m_nScreen ).m_aSize );
            w = aScreenSize.Width();
            h = aScreenSize.Height();
            if( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE &&
                nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
            {
                // fill in holy default values brought to us by product management
                if( aScreenSize.Width() >= 800 )
                    w = 785;
                if( aScreenSize.Width() >= 1024 )
                    w = 920;
    
                if( aScreenSize.Height() >= 600 )
                    h = 550;
                if( aScreenSize.Height() >= 768 )
                    h = 630;
                if( aScreenSize.Height() >= 1024 )
                    h = 875;
            }
            if( ! mpParent )
            {
                // find the last document window (if any)
                const X11SalFrame* pFrame = NULL;
                const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
                std::list< SalFrame* >::const_iterator it = rFrames.begin();
                while( it != rFrames.end() )
                {
                    pFrame = static_cast< const X11SalFrame* >(*it);
                    if( ! ( pFrame->mpParent
                            || pFrame->mbFullScreen
                            || ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
                            || ! pFrame->GetUnmirroredGeometry().nWidth
                            || ! pFrame->GetUnmirroredGeometry().nHeight
                            )
                        )
                        break;
                    ++it;
                }
                
                if( it != rFrames.end() )
                {
                    // set a document position and size
                    // the first frame gets positioned by the window manager
                    const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
                    x = rGeom.nX;
                    y = rGeom.nY;
                    if( x+(int)w+40 <= (int)aScreenSize.Width() &&
                        y+(int)h+40 <= (int)aScreenSize.Height()
                        )
                    {
                        y += 40;
                        x += 40;
                    }
                    else
                    {
                        x = 10; // leave some space for decoration
                        y = 20;
                    }
                }
                else if( GetDisplay()->IsXinerama() )
                {
                    // place frame on same screen as mouse pointer
                    XLIB_Window aRoot, aChild;
                    int root_x = 0, root_y = 0, lx, ly;
                    unsigned int mask;
                    XQueryPointer( GetXDisplay(),
                                   GetDisplay()->GetRootWindow( m_nScreen ),
                                   &aRoot, &aChild,
                                   &root_x, &root_y, &lx, &ly, &mask );
                    const std::vector< Rectangle >& rScreens = GetDisplay()->GetXineramaScreens();
                    for( unsigned int i = 0; i < rScreens.size(); i++ )
                        if( rScreens[i].IsInside( Point( root_x, root_y ) ) )
                        {
                            x = rScreens[i].Left();
                            y = rScreens[i].Top();
                            break;
                        }
                }
            }
        }
        Attributes.win_gravity = pDisplay_->getWMAdaptor()->getInitWinGravity();
        nAttrMask |= CWWinGravity;
        if( mpParent )
        {
            Attributes.save_under = True;
            nAttrMask |= CWSaveUnder;
        }
        if( IsOverrideRedirect() )
            Attributes.override_redirect = True;
        // default icon
        if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 )
        {
            bool bOk=false;
            try
            {
                bOk=SelectAppIconPixmap( pDisplay_, m_nScreen,
                                         mnIconID != 1 ? mnIconID : 
                                         (mpParent ? mpParent->mnIconID : 1), 32,
                                         Hints.icon_pixmap, Hints.icon_mask );
            }
            catch( com::sun::star::uno::Exception& )
            {
                // can happen - no ucb during early startup
            }
            if( bOk )
            {
                Hints.flags		|= IconPixmapHint;
                if( Hints.icon_mask )
                    Hints.flags	|= IconMaskHint;
            }
        }

		// find the top level frame of the transience hierarchy
        X11SalFrame* pFrame = this;
        while( pFrame->mpParent )
            pFrame = pFrame->mpParent;
		if( (pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG ) )
		{
			// if the top level window is a plugin window,
			// then we should place us in the same window group as
			// the parent application (or none if there is no window group
			// hint in the parent).
			if( pFrame->GetShellWindow() )
			{
				XWMHints* pWMHints = XGetWMHints( pDisplay_->GetDisplay(),
					pFrame->GetShellWindow() );
				if( pWMHints )
				{
					if( (pWMHints->flags & WindowGroupHint) )
					{
						Hints.flags |= WindowGroupHint;
						Hints.window_group = pWMHints->window_group;
					}
					XFree( pWMHints );
				}
			}
		}
		else
		{
			Hints.flags			|= WindowGroupHint;
			Hints.window_group	= pFrame->GetShellWindow();
			// note: for a normal document window this will produce None
			// as the window is not yet created and the shell window is
			// initialized to None. This must be corrected after window creation.
			aClientLeader = GetDisplay()->GetDrawable( m_nScreen );
		}
    }

	nShowState_ 				= SHOWSTATE_UNKNOWN;
	bViewable_					= sal_True;
	bMapped_					= sal_False;
	nVisibility_				= VisibilityFullyObscured;
    mhWindow = XCreateWindow( GetXDisplay(),
                              aFrameParent,
                              x, y,
                              w, h,
                              0,
                              rVis.GetDepth(),
                              InputOutput,
                              rVis.GetVisual(),
                              nAttrMask,
                              &Attributes );
    // FIXME: see above: fake shell window for now to own window
    if( /*! IsSysChildWindow() &&*/ pParentData == NULL )
    {
        mhShellWindow = mhWindow;
    }    
	
	// correct window group if necessary
	if( (Hints.flags & WindowGroupHint) == WindowGroupHint )
	{
		if( Hints.window_group == None )
			Hints.window_group = GetShellWindow();
	}

    maGeometry.nX		= x;
    maGeometry.nY		= y;
    maGeometry.nWidth	= w;
    maGeometry.nHeight	= h;
    updateScreenNumber();

    XSync( GetXDisplay(), False );
    setXEmbedInfo();

    XLIB_Time nUserTime = (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_TOOLWINDOW) ) == 0 ?
        pDisplay_->GetLastUserEventTime() : 0;
    pDisplay_->getWMAdaptor()->setUserTime( this, nUserTime );

	if( ! pParentData && ! IsChildWindow() && ! Attributes.override_redirect )
	{
        XSetWMHints( GetXDisplay(), mhWindow, &Hints );
		// WM Protocols && internals
		Atom a[4];
		int  n = 0;
		a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW );
        if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) )
            a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING );
        if( ! s_pSaveYourselfFrame && ! mpParent)
        {
            // at all times have only one frame with SaveYourself
            a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF );
            s_pSaveYourselfFrame = this;
        }
        if( (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
            a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_TAKE_FOCUS );
		XSetWMProtocols( GetXDisplay(), GetShellWindow(), a, n );

        XClassHint* pClass = XAllocClassHint();
        pClass->res_name  = const_cast<char*>(X11SalData::getFrameResName());
        pClass->res_class = const_cast<char*>(X11SalData::getFrameClassName());
        XSetClassHint( GetXDisplay(), GetShellWindow(), pClass );
        XFree( pClass );

        XSizeHints* pHints = XAllocSizeHints();
        pHints->flags       = PWinGravity | PPosition;
        pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity();
        pHints->x           = 0;
        pHints->y           = 0;
        if( mbFullScreen )
        {
            pHints->flags |= PMaxSize | PMinSize;
            pHints->max_width = w+100;
            pHints->max_height = h+100;
            pHints->min_width  = w;
            pHints->min_height = h;
        }
        XSetWMNormalHints( GetXDisplay(),
                           GetShellWindow(),
                           pHints );
        XFree (pHints);
        
        // set PID and WM_CLIENT_MACHINE
        pDisplay_->getWMAdaptor()->setClientMachine( this );
        pDisplay_->getWMAdaptor()->setPID( this );

        // set client leader
		if( aClientLeader )
		{
			XChangeProperty( GetXDisplay(),
            	             mhWindow,
							 pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_CLIENT_LEADER),
							 XA_WINDOW,
							 32,
							 PropModeReplace,
							 (unsigned char*)&aClientLeader,
							 1
							 );
		}
#define DECOFLAGS (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE)
        int nDecoFlags = WMAdaptor::decoration_All;
        if( (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ||
            (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
            )
            nDecoFlags = 0;
        else if( (nStyle_ & DECOFLAGS ) != DECOFLAGS || (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
        {
            if( nStyle_ & DECOFLAGS )
                // if any decoration, then show a border
                nDecoFlags = WMAdaptor::decoration_Border;
            else
                nDecoFlags = 0;

            if( ! mpParent && (nStyle_ & DECOFLAGS) )
                // don't add a min button if window should be decorationless
                nDecoFlags |= WMAdaptor::decoration_MinimizeBtn;
            if( nStyle_ & SAL_FRAME_STYLE_CLOSEABLE )
                nDecoFlags |= WMAdaptor::decoration_CloseBtn;
            if( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
            {
                nDecoFlags |= WMAdaptor::decoration_Resize;
                if( ! (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
                    nDecoFlags |= WMAdaptor::decoration_MaximizeBtn;
            }
            if( nStyle_ & SAL_FRAME_STYLE_MOVEABLE )
                nDecoFlags |= WMAdaptor::decoration_Title;
        }

        WMAdaptor::WMWindowType eType = WMAdaptor::windowType_Normal;
        if( nStyle_ & SAL_FRAME_STYLE_INTRO )
            eType = WMAdaptor::windowType_Splash;
        if( (nStyle_ & SAL_FRAME_STYLE_DIALOG) && hPresentationWindow == None )
            eType = WMAdaptor::windowType_ModelessDialogue;
        if( nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW )
            eType = WMAdaptor::windowType_Utility;
        if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION )
            eType = WMAdaptor::windowType_Toolbar;
        if(    (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN)
            && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() )
            eType = WMAdaptor::windowType_Dock;

        GetDisplay()->getWMAdaptor()->
            setFrameTypeAndDecoration( this,
                                       eType,
                                       nDecoFlags,
                                       hPresentationWindow ? NULL : mpParent );

	    if( (nStyle_ & (SAL_FRAME_STYLE_DEFAULT |
                        SAL_FRAME_STYLE_OWNERDRAWDECORATION|
                        SAL_FRAME_STYLE_FLOAT |
                        SAL_FRAME_STYLE_INTRO |
                        SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) )
             == SAL_FRAME_STYLE_DEFAULT )
            pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true );
	}
        
    m_nWorkArea = GetDisplay()->getWMAdaptor()->getCurrentWorkArea();
    
	// Pointer
	SetPointer( POINTER_ARROW );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
X11SalFrame::X11SalFrame( SalFrame *pParent, sal_uLong nSalFrameStyle, SystemParentData* pSystemParent )
{
	X11SalData* pSalData = GetX11SalData();

    // initialize frame geometry
    memset( &maGeometry, 0, sizeof(maGeometry) );

    mpParent					= static_cast< X11SalFrame* >( pParent );

    mbTransientForRoot			= false;

	pDisplay_					= pSalData->GetDisplay();
	// insert frame in framelist
    pDisplay_->registerFrame( this );

    mhWindow					= None;
    mhShellWindow				= None;
    mhStackingWindow			= None;
    mhForeignParent				= None;
    mhBackgroundPixmap          = None;
    m_bSetFocusOnMap            = false;

	pGraphics_					= NULL;
	pFreeGraphics_				= NULL;

	hCursor_					= None;
	nCaptured_					= 0;

 	nReleaseTime_				= 0;
	nKeyCode_					= 0;
	nKeyState_					= 0;
	nCompose_					= -1;
    mbKeyMenu					= false;
    mbSendExtKeyModChange		= false;
    mnExtKeyMod					= 0;

	nShowState_ 				= SHOWSTATE_UNKNOWN;
	nWidth_ 					= 0;
	nHeight_					= 0;
	nStyle_ 					= 0;
    mnExtStyle                  = 0;
	bAlwaysOnTop_				= sal_False;

    // set bViewable_ to sal_True: hack GetClientSize to report something
    // different to 0/0 before first map
	bViewable_					= sal_True;
	bMapped_					= sal_False;
	bDefaultPosition_			= sal_True;
	nVisibility_				= VisibilityFullyObscured;
    m_nWorkArea                 = 0;
    mbInShow					= sal_False;
    m_bXEmbed                   = false;

	nScreenSaversTimeout_		= 0;

	mpInputContext 				= NULL;
	mbInputFocus				= False;

    maAlwaysOnTopRaiseTimer.SetTimeoutHdl( LINK( this, X11SalFrame, HandleAlwaysOnTopRaise ) );
    maAlwaysOnTopRaiseTimer.SetTimeout( 100 );

    meWindowType				= WMAdaptor::windowType_Normal;
    mnDecorationFlags			= WMAdaptor::decoration_All;
    mbMaximizedVert				= false;
    mbMaximizedHorz				= false;
    mbShaded					= false;
    mbFullScreen				= false;

    mnIconID					= 1; // ICON_DEFAULT
    
    m_pClipRectangles           = NULL;
    m_nCurClipRect              = 0;
    m_nMaxClipRect              = 0;

	if( mpParent )
		mpParent->maChildren.push_back( this );

	Init( nSalFrameStyle, GetDisplay()->GetDefaultScreenNumber(), pSystemParent );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::passOnSaveYourSelf()
{
    if( this == s_pSaveYourselfFrame )
    {
        // pass on SaveYourself
        const X11SalFrame* pFrame = NULL;
        const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
        std::list< SalFrame* >::const_iterator it = rFrames.begin();
        while( it != rFrames.end() )
        {
            pFrame = static_cast< const X11SalFrame* >(*it);
            if( ! ( IsChildWindow() || pFrame->mpParent )
                && pFrame != s_pSaveYourselfFrame )
                    break;
            ++it;    
        }
        
        s_pSaveYourselfFrame = (it != rFrames.end() ) ? const_cast<X11SalFrame*>(pFrame) : NULL;
        if( s_pSaveYourselfFrame )
        {
            Atom a[4];
            int  n = 0;
            a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW );
            a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF );
            if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) )
                a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING );
            XSetWMProtocols( GetXDisplay(), s_pSaveYourselfFrame->GetShellWindow(), a, n );
        }
    }
}

X11SalFrame::~X11SalFrame()
{
	notifyDelete();
    
    if( m_pClipRectangles )
    {
        delete [] m_pClipRectangles;
        m_pClipRectangles = NULL;
        m_nCurClipRect = m_nMaxClipRect = 0;
    }
    
    if( mhBackgroundPixmap )
    {
        XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None );
        XFreePixmap( GetXDisplay(), mhBackgroundPixmap ); 
    }
	
    if( mhStackingWindow )
        aPresentationReparentList.remove( mhStackingWindow );

	// remove from parent's list
	if( mpParent )
		mpParent->maChildren.remove( this );

    // deregister on SalDisplay
    pDisplay_->deregisterFrame( this );

	// unselect all events, some may be still in the queue anyway
    if( ! IsSysChildWindow() )
        XSelectInput( GetXDisplay(), GetShellWindow(), 0 );
	XSelectInput( GetXDisplay(), GetWindow(), 0 );

	ShowFullScreen( sal_False, 0 );

	if( bMapped_ )
		Show( sal_False );

    if( mpInputContext )
    {
        mpInputContext->UnsetICFocus( this );
        mpInputContext->Unmap( this );
        delete mpInputContext;
    }

    if( GetWindow() == hPresentationWindow )
    {
        hPresentationWindow = None;
        doReparentPresentationDialogues( GetDisplay() );
    }

	if( pGraphics_ )
	{
		pGraphics_->DeInit();
		delete pGraphics_;
	}

	if( pFreeGraphics_ )
	{
		pFreeGraphics_->DeInit();
		delete pFreeGraphics_;
	}


    XDestroyWindow( GetXDisplay(), mhWindow );

    /*
     *  check if there is only the status frame left
     *  if so, free it
     */
    if( ! GetDisplay()->getFrames().empty() && I18NStatus::exists() )
    {
        SalFrame* pStatusFrame = I18NStatus::get().getStatusFrame();
        std::list< SalFrame* >::const_iterator sit = GetDisplay()->getFrames().begin();
        if( pStatusFrame
            && *sit == pStatusFrame
            && ++sit == GetDisplay()->getFrames().end() )
            vcl::I18NStatus::free();
    }

    passOnSaveYourSelf();
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetExtendedFrameStyle( SalExtStyle nStyle )
{
    if( nStyle != mnExtStyle && ! IsChildWindow() )
    {
        mnExtStyle = nStyle;
    
        XClassHint* pClass = XAllocClassHint();
        rtl::OString aResHint = X11SalData::getFrameResName( mnExtStyle );
        pClass->res_name  = const_cast<char*>(aResHint.getStr());
        pClass->res_class = const_cast<char*>(X11SalData::getFrameClassName());
        XSetClassHint( GetXDisplay(), GetShellWindow(), pClass );
        XFree( pClass );
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetBackgroundBitmap( SalBitmap* pBitmap )
{
    if( mhBackgroundPixmap )
    {
        XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None );
        XFreePixmap( GetXDisplay(), mhBackgroundPixmap );
        mhBackgroundPixmap = None;
    }
    if( pBitmap )
    {
        X11SalBitmap* pBM = static_cast<X11SalBitmap*>(pBitmap);
        Size aSize = pBM->GetSize();
        if( aSize.Width() && aSize.Height() )
        {
            mhBackgroundPixmap =
                XCreatePixmap( GetXDisplay(),
                               GetWindow(),
                               aSize.Width(),
                               aSize.Height(),
                               GetDisplay()->GetVisual( m_nScreen ).GetDepth() );
            if( mhBackgroundPixmap )
            {
                SalTwoRect aTwoRect;
                aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
                aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width();
                aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height();
                pBM->ImplDraw( mhBackgroundPixmap,
                               m_nScreen,
                               GetDisplay()->GetVisual( m_nScreen ).GetDepth(),
                               aTwoRect, GetDisplay()->GetCopyGC( m_nScreen ) );
                XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), mhBackgroundPixmap );
            }
        }
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

const SystemChildData* X11SalFrame::GetSystemData() const
{
	X11SalFrame *pFrame = const_cast<X11SalFrame*>(this);
	pFrame->maSystemChildData.nSize 		= sizeof( SystemChildData );
	pFrame->maSystemChildData.pDisplay		= GetXDisplay();
	pFrame->maSystemChildData.aWindow		= pFrame->GetWindow();
	pFrame->maSystemChildData.pSalFrame 	= pFrame;
	pFrame->maSystemChildData.pWidget		= NULL;
	pFrame->maSystemChildData.pVisual		= GetDisplay()->GetVisual( m_nScreen ).GetVisual();
	pFrame->maSystemChildData.nScreen		= m_nScreen;
	pFrame->maSystemChildData.nDepth		= GetDisplay()->GetVisual( m_nScreen ).GetDepth();
	pFrame->maSystemChildData.aColormap		= GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
	pFrame->maSystemChildData.pAppContext	= NULL;
	pFrame->maSystemChildData.aShellWindow	= pFrame->GetShellWindow();
	pFrame->maSystemChildData.pShellWidget	= NULL;
	return &maSystemChildData;
}

SalGraphics *X11SalFrame::GetGraphics()
{
	if( pGraphics_ )
		return NULL;

	if( pFreeGraphics_ )
	{
		pGraphics_		= pFreeGraphics_;
		pFreeGraphics_	= NULL;
	}
	else
	{
		pGraphics_ = new X11SalGraphics();
		pGraphics_->Init( this, GetWindow(), m_nScreen );
	}

	return pGraphics_;
}

void X11SalFrame::ReleaseGraphics( SalGraphics *pGraphics )
{
    DBG_ASSERT( pGraphics == pGraphics_, "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" );

	if( pGraphics != pGraphics_ )
		return;

	pFreeGraphics_	= pGraphics_;
	pGraphics_		= NULL;
}

void X11SalFrame::updateGraphics( bool bClear )
{
    Drawable aDrawable = bClear ? None : GetWindow();
    if( pGraphics_ )
        pGraphics_->SetDrawable( aDrawable, m_nScreen );
    if( pFreeGraphics_ )
        pFreeGraphics_->SetDrawable( aDrawable, m_nScreen );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::Enable( sal_Bool /*bEnable*/ )
{
	// NYI: enable/disable frame
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetIcon( sal_uInt16 nIcon )
{
    if ( ! IsChildWindow() )
    {
        // 0 == default icon -> #1
        if ( nIcon == 0 )
            nIcon = 1;

        mnIconID = nIcon;

        XIconSize *pIconSize = NULL;
        int nSizes = 0;
        int iconSize = 32;
        if ( XGetIconSizes( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen ), &pIconSize, &nSizes ) )
        {
#if OSL_DEBUG_LEVEL > 1
            fprintf(stderr, "X11SalFrame::SetIcon(): found %d IconSizes:\n", nSizes);
#endif

            const int ourLargestIconSize = 48;
            bool bFoundIconSize = false;

            int i;
            for( i=0; i<nSizes; i++)
            {
               // select largest supported icon

               // Note: olwm/olvwm reports a huge max icon size of
               // 160x160 pixels; always choosing the max as the
               // preferred icon size is apparently wrong under olvwm
               // - so we keep the safe default |iconSize| when we see
               // unreasonable large max icon sizes (> twice of our
               // largest available icon) reported by XGetIconSizes.
                if( pIconSize[i].max_width > iconSize
                    && pIconSize[i].max_width <= 2*ourLargestIconSize )
                {
                    iconSize = pIconSize[i].max_width;
                    bFoundIconSize = true;
                }
                iconSize = pIconSize[i].max_width;

#if OSL_DEBUG_LEVEL > 1
                fprintf(stderr, "min: %d, %d\nmax: %d, %d\ninc: %d, %d\n\n",
                        pIconSize[i].min_width, pIconSize[i].min_height,
                        pIconSize[i].max_width, pIconSize[i].max_height,
                        pIconSize[i].width_inc, pIconSize[i].height_inc);
#endif
            }

            if ( !bFoundIconSize )
            {
               // Unless someone has fixed olwm/olvwm, we have rejected
               // the max icon size from |XGetIconSizes()|.  Provide a
               // better icon size default value, in case our window manager
               // is olwm/olvwm.
               const String& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() );

               if ( rWM.EqualsAscii( "Olwm" ) )
                   iconSize = 48;
            }

            XFree( pIconSize );
        }
        else
        {
            const String& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() );
            if( rWM.EqualsAscii( "KWin" ) )			// assume KDE is running
                iconSize = 48;
            static bool bGnomeIconSize = false;
            static bool bGnomeChecked = false;
            if( ! bGnomeChecked )
            {
                bGnomeChecked=true;
                int nCount = 0;
                Atom* pProps = XListProperties( GetXDisplay(),
                                                GetDisplay()->GetRootWindow( m_nScreen ),
                                                &nCount );
                for( int i = 0; i < nCount && !bGnomeIconSize; i++ )
                 {
                    char* pName = XGetAtomName( GetXDisplay(), pProps[i] );
                    if( !strcmp( pName, "GNOME_PANEL_DESKTOP_AREA" ) )
                        bGnomeIconSize = true;
                    if( pName )
                        XFree( pName );
                 }
                if( pProps )
                    XFree( pProps );
            }
            if( bGnomeIconSize )
                iconSize = 48;
        }

        XWMHints Hints;
        Hints.flags = 0;
		XWMHints *pHints = XGetWMHints( GetXDisplay(), GetShellWindow() );
        if( pHints )
        {
            memcpy(&Hints, pHints, sizeof( XWMHints ));
            XFree( pHints );
        }
        pHints = &Hints;

		sal_Bool bOk = SelectAppIconPixmap( GetDisplay(), m_nScreen,
                                        nIcon, iconSize,
                                        pHints->icon_pixmap, pHints->icon_mask );
        if ( !bOk )
        {
            // load default icon (0)
		    bOk = SelectAppIconPixmap( GetDisplay(), m_nScreen,
                                       0, iconSize,
                                       pHints->icon_pixmap, pHints->icon_mask );
        }
		if( bOk )
        {
    		pHints->flags 	 |= IconPixmapHint;
		    if( pHints->icon_mask )
			    pHints->flags |= IconMaskHint;

		    XSetWMHints( GetXDisplay(), GetShellWindow(), pHints );
        }
	}
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetMaxClientSize( long nWidth, long nHeight )
{
    if( ! IsChildWindow() )
    {
        if( GetShellWindow() && (nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
        {
            XSizeHints* pHints = XAllocSizeHints();
            long nSupplied = 0;
            XGetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints,
                               &nSupplied
                               );
            pHints->max_width	= nWidth;
            pHints->max_height	= nHeight;
            pHints->flags |= PMaxSize;
            XSetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints );
            XFree( pHints );
        }
    }
}

void X11SalFrame::SetMinClientSize( long nWidth, long nHeight )
{
    if( ! IsChildWindow() )
    {
        if( GetShellWindow() && (nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
        {
            XSizeHints* pHints = XAllocSizeHints();
            long nSupplied = 0;
            XGetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints,
                               &nSupplied
                               );
            pHints->min_width	= nWidth;
            pHints->min_height	= nHeight;
            pHints->flags |= PMinSize;
            XSetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints );
            XFree( pHints );
        }
    }
}

// Show + Pos (x,y,z) + Size (width,height)
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate )
{
    if( ( bVisible && bMapped_ )
        || ( !bVisible && !bMapped_ ) )
        return;

    // HACK: this is a workaround for (at least) kwin
    // even though transient frames should be kept above their parent
    // this does not necessarily hold true for DOCK type windows
    // so artificially set ABOVE and remove it again on hide
    if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen())
        pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible );
    
	bMapped_   = bVisible;
	bViewable_ = bVisible;
    setXEmbedInfo();
	if( bVisible )
	{
        SessionManagerClient::open(); // will simply return after the first time

        mbInShow = sal_True;
        if( ! (nStyle_ & SAL_FRAME_STYLE_INTRO) )
        {
            // hide all INTRO frames
            const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
            for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
            {
                const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
                // look for intro bit map; if present, hide it
                if( pFrame->nStyle_ & SAL_FRAME_STYLE_INTRO )
                {
                    if( pFrame->bMapped_ )
                        const_cast<X11SalFrame*>(pFrame)->Show( sal_False );
                }
            }
        }
        
        // update NET_WM_STATE which may have been deleted due to earlier Show(sal_False)
        if( nShowState_ == SHOWSTATE_HIDDEN )
            GetDisplay()->getWMAdaptor()->frameIsMapping( this );

        /*
         *  #95097#
         *  Actually this is rather exotic and currently happens only in conjunction
         *  with the basic dialogue editor,
         *  which shows a frame and instantly hides it again. After that the
         *  editor window is shown and the WM takes this as an opportunity
         *  to show our hidden transient frame also. So Show( sal_False ) must
         *  withdraw the frame AND delete the WM_TRANSIENT_FOR property.
         *  In case the frame is shown again, the transient hint must be restored here.
         */
        if(    ! IsChildWindow()
            && ! IsOverrideRedirect()
            && ! IsFloatGrabWindow()
            && mpParent
            )
        {
            GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent );
        }
        
        // #i45160# switch to desktop where a dialog with parent will appear
        if( mpParent && mpParent->m_nWorkArea != m_nWorkArea )
            GetDisplay()->getWMAdaptor()->switchToWorkArea( mpParent->m_nWorkArea );

        if( IsFloatGrabWindow() &&
            mpParent &&
            nVisibleFloats == 0 &&
            ! GetDisplay()->GetCaptureFrame() )
        {
            /* #i39420#
             * outsmart KWin's "focus strictly under mouse" mode
             * which insists on taking the focus from the document
             * to the new float. Grab focus to parent frame BEFORE
             * showing the float (cannot grab it to the float
             * before show).
             */
            XGrabPointer( GetXDisplay(),
                          mpParent->GetWindow(),
                          True,
                          PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                          GrabModeAsync,
                          GrabModeAsync,
                          None,
                          mpParent ? mpParent->GetCursor() : None,
                          CurrentTime
                          );
        }

        XLIB_Time nUserTime = 0;
        if( ! bNoActivate && (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) == 0 )
            nUserTime = pDisplay_->GetLastUserEventTime( true );
        GetDisplay()->getWMAdaptor()->setUserTime( this, nUserTime );
        if( ! bNoActivate && (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
            m_bSetFocusOnMap = true;

        // actually map the window
        if( m_bXEmbed )
            askForXEmbedFocus( 0 );
        else
        {
            if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
            {
                if( IsChildWindow() )
                    XMapWindow( GetXDisplay(), GetShellWindow() );
                XSelectInput( GetXDisplay(), GetShellWindow(), CLIENT_EVENTS );
            }
            if( nStyle_ & SAL_FRAME_STYLE_FLOAT )
                XMapRaised( GetXDisplay(), GetWindow() );
            else
                XMapWindow( GetXDisplay(), GetWindow() );
        }
		XSelectInput( GetXDisplay(), GetWindow(), CLIENT_EVENTS );

		if( maGeometry.nWidth > 0
            && maGeometry.nHeight > 0
			&& (   nWidth_  != (int)maGeometry.nWidth
				|| nHeight_ != (int)maGeometry.nHeight ) )
		{
			nWidth_  = maGeometry.nWidth;
			nHeight_ = maGeometry.nHeight;
		}

		XSync( GetXDisplay(), False );
        
        if( IsFloatGrabWindow() )
        {
            /*
             *  #95453#
             *  Sawfish and twm can be switched to enter-exit focus behaviour. In this case
             *  we must grab the pointer else the dumb WM will put the focus to the
             *  override-redirect float window. The application window will be deactivated
             *  which causes that the floats are destroyed, so the user can never click on
             *  a menu because it vanishes as soon as he enters it.
             */
            nVisibleFloats++;
            if( nVisibleFloats == 1 && ! GetDisplay()->GetCaptureFrame() )
            {
                /* #i39420# now move grab to the new float window */
                XGrabPointer( GetXDisplay(),
                              GetWindow(),
                              True,
                              PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
                              GrabModeAsync,
                              GrabModeAsync,
                              None,
                              mpParent ? mpParent->GetCursor() : None,
                              CurrentTime
                              );
            }
        }
		CallCallback( SALEVENT_RESIZE, NULL );

        /*
         *  sometimes a message box/dialogue is brought up when a frame is not mapped
         *  the corresponding TRANSIENT_FOR hint is then set to the root window
         *  so that the dialogue shows in all cases. Correct it here if the
         *  frame is shown afterwards.
         */
        if( ! IsChildWindow()
            && ! IsOverrideRedirect()
            && ! IsFloatGrabWindow()
            )
        {
            for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
                 it != maChildren.end(); ++it )
            {
                if( (*it)->mbTransientForRoot )
                    GetDisplay()->getWMAdaptor()->changeReferenceFrame( *it, this );
            }
        }
        /*
         *  leave SHOWSTATE_UNKNOWN as this indicates first mapping
         *  and is only reset int HandleSizeEvent
         */
        if( nShowState_ != SHOWSTATE_UNKNOWN )
            nShowState_ = SHOWSTATE_NORMAL;

        /*
         *  #98107# plugged windows don't necessarily get the
         *  focus on show because the parent may already be mapped
         *  and have the focus. So try to set the focus
         *  to the child on Show(sal_True)
         */
        if( (nStyle_ & SAL_FRAME_STYLE_PLUG) && ! m_bXEmbed )
            XSetInputFocus( GetXDisplay(),
                            GetWindow(),
                            RevertToParent,
                            CurrentTime );

        if( mpParent )
        {
            // push this frame so it will be in front of its siblings
            // only necessary for insane transient behaviour of Dtwm/olwm
            mpParent->maChildren.remove( this );
            mpParent->maChildren.push_front(this);
        }
	}
	else
	{
        if( getInputContext() )
            getInputContext()->Unmap( this );

        if( ! IsChildWindow() )
        {
            /*  FIXME: Is deleting the property really necessary ? It hurts
             *  owner drawn windows at least.
             */
            if( mpParent && ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
                XDeleteProperty( GetXDisplay(), GetShellWindow(), GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::WM_TRANSIENT_FOR ) );
            XWithdrawWindow( GetXDisplay(), GetShellWindow(), m_nScreen );
        }
        else if( ! m_bXEmbed )
            XUnmapWindow( GetXDisplay(), GetWindow() );
        
        nShowState_ = SHOWSTATE_HIDDEN;
        if( IsFloatGrabWindow() && nVisibleFloats )
        {
            nVisibleFloats--;
            if( nVisibleFloats == 0  && ! GetDisplay()->GetCaptureFrame() )
                XUngrabPointer( GetXDisplay(),
                                CurrentTime );
        }
        // flush here; there may be a very seldom race between
        // the display connection used for clipboard and our connection
        Flush();
	}
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::ToTop( sal_uInt16 nFlags )
{
	if( ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
        && ! ( nStyle_ & SAL_FRAME_STYLE_FLOAT )
        && nShowState_ != SHOWSTATE_HIDDEN
        && nShowState_ != SHOWSTATE_UNKNOWN
        )
    {
        GetDisplay()->getWMAdaptor()->frameIsMapping( this );
        if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
            XMapWindow( GetXDisplay(), GetShellWindow() );
        XMapWindow( GetXDisplay(), GetWindow() );
    }

    XLIB_Window aToTopWindow = IsSysChildWindow() ? GetWindow() : GetShellWindow();
    if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) )
    {
        XRaiseWindow( GetXDisplay(), aToTopWindow );
        if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected() )
            for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
                 it != maChildren.end(); ++it )
                (*it)->ToTop( nFlags & ~SAL_FRAME_TOTOP_GRABFOCUS );
    }

    if( ( ( nFlags & SAL_FRAME_TOTOP_GRABFOCUS ) || ( nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY ) )
        && bMapped_ )
    {
        if( m_bXEmbed )
            askForXEmbedFocus( 0 );
        else
            XSetInputFocus( GetXDisplay(), aToTopWindow, RevertToParent, CurrentTime );
    }
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::GetWorkArea( Rectangle& rWorkArea )
{
    rWorkArea = pDisplay_->getWMAdaptor()->getWorkArea( 0 );
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::GetClientSize( long &rWidth, long &rHeight )
{
	if( ! bViewable_  )
	{
		rWidth = rHeight = 0;
		return;
	}

	rWidth	= maGeometry.nWidth;
	rHeight = maGeometry.nHeight;

	if( !rWidth || !rHeight )
	{
		XWindowAttributes aAttrib;

		XGetWindowAttributes( GetXDisplay(), GetWindow(), &aAttrib );

		maGeometry.nWidth = rWidth = aAttrib.width;
		maGeometry.nHeight = rHeight = aAttrib.height;
	}
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetWindowGravity (int nGravity) const
{
    if( ! IsChildWindow() )
    {
        XSizeHints* pHint = XAllocSizeHints();
        long        nFlag;
    
        XGetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint, &nFlag);
        pHint->flags       |= PWinGravity;
        pHint->win_gravity  = nGravity;
    
        XSetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint);
        XSync (GetXDisplay(), False);
    
        XFree (pHint);
    }
}

void X11SalFrame::Center( )
{
	int 			nX, nY, nScreenWidth, nScreenHeight;
	int				nRealScreenWidth, nRealScreenHeight;
	int				nScreenX = 0, nScreenY = 0;

    const Size& aScreenSize = GetDisplay()->getDataForScreen( m_nScreen ).m_aSize;
    nScreenWidth		= aScreenSize.Width();
    nScreenHeight		= aScreenSize.Height();
    nRealScreenWidth	= nScreenWidth;
    nRealScreenHeight	= nScreenHeight;

    if( GetDisplay()->IsXinerama() )
    {
        // get xinerama screen we are on
        // if there is a parent, use its center for screen determination
        // else use the pointer
        XLIB_Window aRoot, aChild;
        int root_x, root_y, x, y;
        unsigned int mask;
        if( mpParent )
        {
            root_x = mpParent->maGeometry.nX + mpParent->maGeometry.nWidth/2;
            root_y = mpParent->maGeometry.nY + mpParent->maGeometry.nHeight/2;
        }
        else
            XQueryPointer( GetXDisplay(),
                           GetShellWindow(),
                           &aRoot, &aChild,
                           &root_x, &root_y,
                           &x, &y,
                           &mask );
        const std::vector< Rectangle >& rScreens = GetDisplay()->GetXineramaScreens();
        for( unsigned int i = 0; i < rScreens.size(); i++ )
            if( rScreens[i].IsInside( Point( root_x, root_y ) ) )
            {
                nScreenX			= rScreens[i].Left();
                nScreenY			= rScreens[i].Top();
                nRealScreenWidth	= rScreens[i].GetWidth();
                nRealScreenHeight	= rScreens[i].GetHeight();
                break;
            }
    }

	if( mpParent )
	{
		X11SalFrame* pFrame = mpParent;
		while( pFrame->mpParent )
			pFrame = pFrame->mpParent;
		if( pFrame->maGeometry.nWidth < 1  || pFrame->maGeometry.nHeight < 1 )
        {
            Rectangle aRect;
			pFrame->GetPosSize( aRect );
            pFrame->maGeometry.nX		= aRect.Left();
            pFrame->maGeometry.nY		= aRect.Top();
            pFrame->maGeometry.nWidth	= aRect.GetWidth();
            pFrame->maGeometry.nHeight	= aRect.GetHeight();
        }

		if( pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG )
		{
			XLIB_Window aRoot;
			unsigned int bw, depth;
			XGetGeometry( GetXDisplay(),
						  pFrame->GetShellWindow(),
						  &aRoot,
						  &nScreenX, &nScreenY,
						  (unsigned int*)&nScreenWidth,
						  (unsigned int*)&nScreenHeight,
						  &bw, &depth );
		}
		else
		{
			nScreenX		= pFrame->maGeometry.nX;
			nScreenY		= pFrame->maGeometry.nY;
			nScreenWidth	= pFrame->maGeometry.nWidth;
			nScreenHeight	= pFrame->maGeometry.nHeight;
		}
	}

	if( mpParent && mpParent->nShowState_ == SHOWSTATE_NORMAL )
	{
		if( maGeometry.nWidth >= mpParent->maGeometry.nWidth &&
			maGeometry.nHeight >= mpParent->maGeometry.nHeight )
		{
			nX = nScreenX + 40;
			nY = nScreenY + 40;
		}
		else
		{
			// center the window relative to the top level frame
			nX = (nScreenWidth	- (int)maGeometry.nWidth ) / 2 + nScreenX;
			nY = (nScreenHeight - (int)maGeometry.nHeight) / 2 + nScreenY;
		}
	}
	else
	{
		// center the window relative to screen
		nX = (nRealScreenWidth	- (int)maGeometry.nWidth ) / 2 + nScreenX;
		nY = (nRealScreenHeight - (int)maGeometry.nHeight) / 2 + nScreenY;
	}
    nX = nX < 0 ? 0 : nX;
    nY = nY < 0 ? 0 : nY;

	bDefaultPosition_ = False;
    if( mpParent )
    {
        nX -= mpParent->maGeometry.nX;
        nY -= mpParent->maGeometry.nY;
    }

    Point aPoint(nX, nY);
	SetPosSize( Rectangle( aPoint, Size( maGeometry.nWidth, maGeometry.nHeight ) ) );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::updateScreenNumber()
{
    if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
    {
        Point aPoint( maGeometry.nX, maGeometry.nY );
        const std::vector<Rectangle>& rScreenRects( GetDisplay()->GetXineramaScreens() );
        size_t nScreens = rScreenRects.size();
        for( size_t i = 0; i < nScreens; i++ )
        {
            if( rScreenRects[i].IsInside( aPoint ) )
            {
                maGeometry.nScreenNumber = static_cast<unsigned int>(i);
                break;
            }
        }
    }
    else
        maGeometry.nScreenNumber = static_cast<unsigned int>(m_nScreen);
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
{
    if( nStyle_ & SAL_FRAME_STYLE_PLUG )
        return;
    
    // relative positioning in X11SalFrame::SetPosSize
    Rectangle aPosSize( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) );
    aPosSize.Justify();

    if( ! ( nFlags & SAL_FRAME_POSSIZE_X ) )
    {
        nX = aPosSize.Left();
        if( mpParent )
            nX -= mpParent->maGeometry.nX;
    }
    if( ! ( nFlags & SAL_FRAME_POSSIZE_Y ) )
    {
        nY = aPosSize.Top();
        if( mpParent )
            nY -= mpParent->maGeometry.nY;
    }
    if( ! ( nFlags & SAL_FRAME_POSSIZE_WIDTH ) )
        nWidth = aPosSize.GetWidth();
    if( ! ( nFlags & SAL_FRAME_POSSIZE_HEIGHT ) )
        nHeight = aPosSize.GetHeight();

    aPosSize = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );

    if( ! ( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) )
    {
        if( bDefaultPosition_ )
        {
            maGeometry.nWidth = aPosSize.GetWidth();
            maGeometry.nHeight = aPosSize.GetHeight();
            Center();
        }
        else
            SetSize( Size( nWidth, nHeight ) );
    }
    else
        SetPosSize( aPosSize );

    bDefaultPosition_ = False;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::SetAlwaysOnTop( sal_Bool bOnTop )
{
    if( ! IsOverrideRedirect() )
    {
        bAlwaysOnTop_ = bOnTop;
        pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bOnTop );
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

#define _FRAMESTATE_MASK_GEOMETRY \
     (SAL_FRAMESTATE_MASK_X     | SAL_FRAMESTATE_MASK_Y |   \
      SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)
#define _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY \
     (SAL_FRAMESTATE_MASK_MAXIMIZED_X     | SAL_FRAMESTATE_MASK_MAXIMIZED_Y |   \
      SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT)

void X11SalFrame::SetWindowState( const SalFrameState *pState )
{
    if (pState == NULL)
        return;

    // Request for position or size change
    if (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY)
    {
        Rectangle aPosSize;
        bool bDoAdjust = false;
        
        /* #i44325#
         * if maximized, set restore size and guess maximized size from last time
         * in state change below maximize window
         */
        if( ! IsChildWindow() &&
            (pState->mnMask & SAL_FRAMESTATE_MASK_STATE) &&
            (pState->mnState & SAL_FRAMESTATE_MAXIMIZED) &&
            (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY) == _FRAMESTATE_MASK_GEOMETRY &&
            (pState->mnMask & _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY) == _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY
            )
        {
            XSizeHints* pHints = XAllocSizeHints();
            long nSupplied = 0;
            XGetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints,
                               &nSupplied );
            pHints->flags |= PPosition | PWinGravity;
            pHints->x			= pState->mnX;
            pHints->y			= pState->mnY;
            pHints->win_gravity	= pDisplay_->getWMAdaptor()->getPositionWinGravity();
            XSetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints );
            XFree( pHints );
            
            XMoveResizeWindow( GetXDisplay(), GetShellWindow(),
                               pState->mnX, pState->mnY,
                               pState->mnWidth, pState->mnHeight );
            // guess maximized geometry from last time
            maGeometry.nX      = pState->mnMaximizedX;
            maGeometry.nY      = pState->mnMaximizedY;
            maGeometry.nWidth  = pState->mnMaximizedWidth;
            maGeometry.nHeight = pState->mnMaximizedHeight;
            updateScreenNumber();
        }
        else
        {
            // initialize with current geometry
            if ((pState->mnMask & _FRAMESTATE_MASK_GEOMETRY) != _FRAMESTATE_MASK_GEOMETRY)
                GetPosSize (aPosSize);
            
            // change requested properties
            if (pState->mnMask & SAL_FRAMESTATE_MASK_X)
            {
                aPosSize.setX (pState->mnX);
            }
            if (pState->mnMask & SAL_FRAMESTATE_MASK_Y)
            {
                aPosSize.setY (pState->mnY);
            }
            if (pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH)
            {
                long nWidth = pState->mnWidth > 0 ? pState->mnWidth  - 1 : 0;
                aPosSize.setWidth (nWidth);
                bDoAdjust = true;
            }
            if (pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT)
            {
                int nHeight = pState->mnHeight > 0 ? pState->mnHeight - 1 : 0;
                aPosSize.setHeight (nHeight);
                bDoAdjust = true;
            }
            
            const Size& aScreenSize = pDisplay_->getDataForScreen( m_nScreen ).m_aSize;
            const WMAdaptor *pWM = GetDisplay()->getWMAdaptor();
            
            if( bDoAdjust && aPosSize.GetWidth() <= aScreenSize.Width()
                && aPosSize.GetHeight() <= aScreenSize.Height() )
            {
                SalFrameGeometry aGeom = maGeometry;
                
                if( ! (nStyle_ & ( SAL_FRAME_STYLE_FLOAT | SAL_FRAME_STYLE_PLUG ) ) &&
                    mpParent &&
                aGeom.nLeftDecoration == 0 &&
                aGeom.nTopDecoration == 0 )
                {
                    aGeom = mpParent->maGeometry;
                    if( aGeom.nLeftDecoration == 0 &&
                        aGeom.nTopDecoration == 0 )
                    {
                        aGeom.nLeftDecoration = 5;
                        aGeom.nTopDecoration = 20;
                        aGeom.nRightDecoration = 5;
                        aGeom.nBottomDecoration = 5;
                    }
                }
                
                // adjust position so that frame fits onto screen
                if( aPosSize.Right()+(long)aGeom.nRightDecoration > aScreenSize.Width()-1 )
                    aPosSize.Move( (long)aScreenSize.Width() - (long)aPosSize.Right() - (long)aGeom.nRightDecoration, 0 );
                if( aPosSize.Bottom()+(long)aGeom.nBottomDecoration > aScreenSize.Height()-1 )
                    aPosSize.Move( 0, (long)aScreenSize.Height() - (long)aPosSize.Bottom() - (long)aGeom.nBottomDecoration );
                if( aPosSize.Left() < (long)aGeom.nLeftDecoration )
                    aPosSize.Move( (long)aGeom.nLeftDecoration - (long)aPosSize.Left(), 0 );
                if( aPosSize.Top() < (long)aGeom.nTopDecoration )
                    aPosSize.Move( 0, (long)aGeom.nTopDecoration - (long)aPosSize.Top() );
            }
            
            // resize with new args
            if (pWM->supportsICCCMPos())
            {
                if( mpParent )
                    aPosSize.Move( -mpParent->maGeometry.nX,
                -mpParent->maGeometry.nY );
                SetPosSize( aPosSize );
                bDefaultPosition_ = False;
            }
            else
                SetPosSize( 0, 0, aPosSize.GetWidth(), aPosSize.GetHeight(), SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
        }
    }

    // request for status change
    if (pState->mnMask & SAL_FRAMESTATE_MASK_STATE)
    {
	    if (pState->mnState & SAL_FRAMESTATE_MAXIMIZED)
	    {
		    nShowState_ = SHOWSTATE_NORMAL;
            if( ! (pState->mnState & (SAL_FRAMESTATE_MAXIMIZED_HORZ|SAL_FRAMESTATE_MAXIMIZED_VERT) ) )
                Maximize();
            else
            {
                bool bHorz = (pState->mnState & SAL_FRAMESTATE_MAXIMIZED_HORZ) ? true : false;
                bool bVert = (pState->mnState & SAL_FRAMESTATE_MAXIMIZED_VERT) ? true : false;
                GetDisplay()->getWMAdaptor()->maximizeFrame( this, bHorz, bVert );
            }
            maRestorePosSize.Left() = pState->mnX;
            maRestorePosSize.Top() = pState->mnY;
            maRestorePosSize.Right() = maRestorePosSize.Left() + pState->mnWidth;
            maRestorePosSize.Right() = maRestorePosSize.Left() + pState->mnHeight;
	    }
        else if( mbMaximizedHorz || mbMaximizedVert )
            GetDisplay()->getWMAdaptor()->maximizeFrame( this, false, false );

	    if (pState->mnState & SAL_FRAMESTATE_MINIMIZED)
	    {
		    if (nShowState_ == SHOWSTATE_UNKNOWN)
			    nShowState_ = SHOWSTATE_NORMAL;
		    Minimize();
        }
        if (pState->mnState & SAL_FRAMESTATE_NORMAL)
        {
            if (nShowState_ != SHOWSTATE_NORMAL)
                Restore();
        }
        if (pState->mnState & SAL_FRAMESTATE_ROLLUP)
            GetDisplay()->getWMAdaptor()->shade( this, true );
	}
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
sal_Bool X11SalFrame::GetWindowState( SalFrameState* pState )
{
	if( SHOWSTATE_MINIMIZED == nShowState_ )
		pState->mnState = SAL_FRAMESTATE_MINIMIZED;
	else
		pState->mnState = SAL_FRAMESTATE_NORMAL;

	Rectangle aPosSize;
    if( maRestorePosSize.IsEmpty() )
        GetPosSize( aPosSize );
    else
        aPosSize = maRestorePosSize;
    
    if( mbMaximizedHorz )
        pState->mnState |= SAL_FRAMESTATE_MAXIMIZED_HORZ;
    if( mbMaximizedVert )
        pState->mnState |= SAL_FRAMESTATE_MAXIMIZED_VERT;
    if( mbShaded )
        pState->mnState |= SAL_FRAMESTATE_ROLLUP;

	pState->mnX 	 = aPosSize.Left();
	pState->mnY 	 = aPosSize.Top();
	pState->mnWidth  = aPosSize.GetWidth();
	pState->mnHeight = aPosSize.GetHeight();

    pState->mnMask   = _FRAMESTATE_MASK_GEOMETRY | SAL_FRAMESTATE_MASK_STATE;


	if (! maRestorePosSize.IsEmpty() )
	{
        GetPosSize( aPosSize );
		pState->mnState |= SAL_FRAMESTATE_MAXIMIZED;
        pState->mnMaximizedX      = aPosSize.Left();
        pState->mnMaximizedY      = aPosSize.Top();
        pState->mnMaximizedWidth  = aPosSize.GetWidth();
        pState->mnMaximizedHeight = aPosSize.GetHeight();
        pState->mnMask |= _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY;
	}

	return sal_True;
}

// ----------------------------------------------------------------------------
// get a screenshot of the current frame including window manager decoration
SalBitmap* X11SalFrame::SnapShot()
{
    Display* pDisplay = GetXDisplay();

    // make sure the frame has been reparented and all paint timer have been
    // expired
    do
    {
        XSync(pDisplay, False);
        Application::Reschedule ();
    }
    while (XPending(pDisplay));
    TimeValue aVal;
    aVal.Seconds = 0;
    aVal.Nanosec = 50000000;
    osl_waitThread( &aVal );
    do
    {
        XSync(pDisplay, False);
        Application::Reschedule ();
    }
    while (XPending(pDisplay));

    // get the most outer window, usually the window manager decoration
    Drawable hWindow = None;
    if (IsOverrideRedirect())
        hWindow = GetDrawable();
    else
    if (hPresentationWindow != None)
        hWindow = hPresentationWindow;
    else
        hWindow = GetStackingWindow();

    // query the contents of the window
    if (hWindow != None)
    {
        X11SalBitmap *pBmp = new X11SalBitmap;
        if (pBmp->SnapShot (pDisplay, hWindow))
            return pBmp;
        else
            delete pBmp;
    }

    return NULL;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// native menu implementation - currently empty
void X11SalFrame::DrawMenuBar()
{
}

void X11SalFrame::SetMenu( SalMenu* )
{
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::GetPosSize( Rectangle &rPosSize )
{
	if( maGeometry.nWidth < 1 || maGeometry.nHeight < 1 )
	{
        const Size& aScreenSize = pDisplay_->getDataForScreen( m_nScreen ).m_aSize;
		long w = aScreenSize.Width()  - maGeometry.nLeftDecoration - maGeometry.nRightDecoration;
		long h = aScreenSize.Height() - maGeometry.nTopDecoration - maGeometry.nBottomDecoration;

		rPosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( w, h ) );
	}
	else
		rPosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ),
                              Size( maGeometry.nWidth, maGeometry.nHeight ) );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::SetSize( const Size &rSize )
{
	if( rSize.Width() > 0 && rSize.Height() > 0 )
	{
 		if( ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
            && ! IsChildWindow()
            && ( nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
 		{
            XSizeHints* pHints = XAllocSizeHints();
            long nSupplied = 0;
            XGetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints,
                               &nSupplied
                               );
            pHints->min_width	= rSize.Width();
            pHints->min_height	= rSize.Height();
            pHints->max_width	= rSize.Width();
            pHints->max_height	= rSize.Height();
            pHints->flags |= PMinSize | PMaxSize;
            XSetWMNormalHints( GetXDisplay(),
                               GetShellWindow(),
                               pHints );
            XFree( pHints );
 		}
        XResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), rSize.Width(), rSize.Height() );
        if( GetWindow() != GetShellWindow() )
        {
            if( (nStyle_ & SAL_FRAME_STYLE_PLUG ) )
                XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, rSize.Width(), rSize.Height() );
            else
                XResizeWindow( GetXDisplay(), GetWindow(), rSize.Width(), rSize.Height() );
        }

        maGeometry.nWidth  = rSize.Width();
        maGeometry.nHeight = rSize.Height();

		// allow the external status window to reposition
		if (mbInputFocus && mpInputContext != NULL)
			mpInputContext->SetICFocus ( this );
	}
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetPosSize( const Rectangle &rPosSize )
{
	XWindowChanges values;
	values.x		= rPosSize.Left();
	values.y		= rPosSize.Top();
	values.width	= rPosSize.GetWidth();
	values.height	= rPosSize.GetHeight();

    if( !values.width || !values.height )
        return;

 	if( mpParent && ! IsSysChildWindow() )
 	{
        // --- RTL --- (mirror window pos)
        if( Application::GetSettings().GetLayoutRTL() )
            values.x = mpParent->maGeometry.nWidth-values.width-1-values.x;

 		XLIB_Window aChild;
 		// coordinates are relative to parent, so translate to root coordinates
 		XTranslateCoordinates( GetDisplay()->GetDisplay(),
 							   mpParent->GetWindow(),
 							   GetDisplay()->GetRootWindow( m_nScreen ),
 							   values.x, values.y,
 							   &values.x, &values.y,
 							   & aChild );
 	}

    bool bMoved = false;
    bool bSized = false;
    if( values.x != maGeometry.nX || values.y != maGeometry.nY )
        bMoved = true;
    if( values.width != (int)maGeometry.nWidth || values.height != (int)maGeometry.nHeight )
        bSized = true;

	if( ! ( nStyle_ & ( SAL_FRAME_STYLE_PLUG | SAL_FRAME_STYLE_FLOAT ) )
        && !(pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_ClientPos) )
    {
        values.x	-= maGeometry.nLeftDecoration;
        values.y	-= maGeometry.nTopDecoration;
    }

    // do net set WMNormalHints for ..
    if(
        // child windows
        ! IsChildWindow()
        // popups (menu, help window, etc.)
        && 	(nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT
        // shown, sizeable windows
        && ( nShowState_ == SHOWSTATE_UNKNOWN ||
             nShowState_ == SHOWSTATE_HIDDEN ||
             ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
             )
        )
    {
        XSizeHints* pHints = XAllocSizeHints();
        long nSupplied = 0;
        XGetWMNormalHints( GetXDisplay(),
                           GetShellWindow(),
                           pHints,
                           &nSupplied
                           );
        if( ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
        {
            pHints->min_width	= rPosSize.GetWidth();
            pHints->min_height	= rPosSize.GetHeight();
            pHints->max_width	= rPosSize.GetWidth();
            pHints->max_height	= rPosSize.GetHeight();
            pHints->flags |= PMinSize | PMaxSize;
        }
        if( nShowState_ == SHOWSTATE_UNKNOWN || nShowState_ == SHOWSTATE_HIDDEN )
        {
            pHints->flags |= PPosition | PWinGravity;
            pHints->x			= values.x;
            pHints->y			= values.y;
            pHints->win_gravity	= pDisplay_->getWMAdaptor()->getPositionWinGravity();
        }
        if( mbFullScreen )
        {
            pHints->max_width	= 10000;
            pHints->max_height	= 10000;
            pHints->flags |= PMaxSize;
        }
        XSetWMNormalHints( GetXDisplay(),
                           GetShellWindow(),
                           pHints );
        XFree( pHints );
    }

    XMoveResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), values.x, values.y, values.width, values.height );
    if( GetShellWindow() != GetWindow() )
    {
        if( (nStyle_ & SAL_FRAME_STYLE_PLUG ) )
            XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, values.width, values.height );
        else
            XMoveResizeWindow( GetXDisplay(), GetWindow(), values.x, values.y, values.width, values.height );
    }            

    maGeometry.nX		= values.x;
    maGeometry.nY		= values.y;
    maGeometry.nWidth	= values.width;
    maGeometry.nHeight	= values.height;
    if( IsSysChildWindow() && mpParent )
    {
        // translate back to root coordinates
        maGeometry.nX += mpParent->maGeometry.nX;
        maGeometry.nY += mpParent->maGeometry.nY;
    }
    
    updateScreenNumber();
    if( bSized && ! bMoved )
        CallCallback( SALEVENT_RESIZE, NULL );
    else if( bMoved && ! bSized )
        CallCallback( SALEVENT_MOVE, NULL );
    else
        CallCallback( SALEVENT_MOVERESIZE, NULL );

	// allow the external status window to reposition
	if (mbInputFocus && mpInputContext != NULL)
		mpInputContext->SetICFocus ( this );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::Minimize()
{
    if( IsSysChildWindow() )
        return;
    
	if( SHOWSTATE_UNKNOWN == nShowState_ || SHOWSTATE_HIDDEN == nShowState_ )
	{
		stderr0( "X11SalFrame::Minimize on withdrawn window\n" );
		return;
	}

	if( XIconifyWindow( GetXDisplay(),
						GetShellWindow(),
						pDisplay_->GetDefaultScreenNumber() ) )
		nShowState_ = SHOWSTATE_MINIMIZED;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::Maximize()
{
    if( IsSysChildWindow() )
        return;
    
	if( SHOWSTATE_MINIMIZED == nShowState_ )
	{
        GetDisplay()->getWMAdaptor()->frameIsMapping( this );
		XMapWindow( GetXDisplay(), GetShellWindow() );
		nShowState_ = SHOWSTATE_NORMAL;
	}

    pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::Restore()
{
    if( IsSysChildWindow() )
        return;
    
	if( SHOWSTATE_UNKNOWN == nShowState_ || SHOWSTATE_HIDDEN == nShowState_ )
	{
		stderr0( "X11SalFrame::Restore on withdrawn window\n" );
		return;
	}

	if( SHOWSTATE_MINIMIZED == nShowState_ )
	{
        GetDisplay()->getWMAdaptor()->frameIsMapping( this );
		XMapWindow( GetXDisplay(), GetShellWindow() );
		nShowState_ = SHOWSTATE_NORMAL;
	}

    pDisplay_->getWMAdaptor()->maximizeFrame( this, false, false );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetScreenNumber( unsigned int nNewScreen )
{
    if( nNewScreen == maGeometry.nScreenNumber )
        return;
    
    if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
    {
        if( nNewScreen >= GetDisplay()->GetXineramaScreens().size() )
            return;
        
        Rectangle aOldScreenRect( GetDisplay()->GetXineramaScreens()[maGeometry.nScreenNumber] );
        Rectangle aNewScreenRect( GetDisplay()->GetXineramaScreens()[nNewScreen] );
        bool bVisible = bMapped_;
        if( bVisible )
            Show( sal_False );
        maGeometry.nX = aNewScreenRect.Left() + (maGeometry.nX - aOldScreenRect.Left());
        maGeometry.nY = aNewScreenRect.Top() + (maGeometry.nY - aOldScreenRect.Top());
        createNewWindow( None, m_nScreen );
        if( bVisible )
            Show( sal_True );
        maGeometry.nScreenNumber = nNewScreen;
    }
    else if( sal_Int32(nNewScreen) < GetDisplay()->GetScreenCount() )
    {
        bool bVisible = bMapped_;
        if( bVisible )
            Show( sal_False );
        createNewWindow( None, nNewScreen );
        if( bVisible )
            Show( sal_True );
        maGeometry.nScreenNumber = nNewScreen;
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nScreen )
{
    if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
    {
        if( mbFullScreen == (bool)bFullScreen )
            return;
        if( bFullScreen )
        {
            maRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ),
                                          Size( maGeometry.nWidth, maGeometry.nHeight ) );
            Rectangle aRect;
            if( nScreen < 0 || nScreen >= static_cast<int>(GetDisplay()->GetXineramaScreens().size()) )
                aRect = Rectangle( Point(0,0), GetDisplay()->GetScreenSize( m_nScreen ) );
            else
                aRect = GetDisplay()->GetXineramaScreens()[nScreen];
            nStyle_ |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN;
            bool bVisible = bMapped_;
            if( bVisible )
                Show( sal_False );
            maGeometry.nX = aRect.Left();
            maGeometry.nY = aRect.Top();
            maGeometry.nWidth = aRect.GetWidth();
            maGeometry.nHeight = aRect.GetHeight();
            mbMaximizedHorz = mbMaximizedVert = false;
            mbFullScreen = true;
            createNewWindow( None, m_nScreen );
            if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() )
                GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true );
            else
            {
                GetDisplay()->getWMAdaptor()->setFullScreenMonitors( GetShellWindow(), nScreen );
                GetDisplay()->getWMAdaptor()->showFullScreen( this, true );
            }
            if( bVisible )
                Show(sal_True);

        }
        else
        {
            mbFullScreen = false;
            nStyle_ &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN;
            bool bVisible = bMapped_;
            Rectangle aRect = maRestorePosSize;
            maRestorePosSize = Rectangle();
            if( bVisible )
                Show( sal_False );
            createNewWindow( None, m_nScreen );
            if( !aRect.IsEmpty() )
                SetPosSize( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
                            SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y |
                            SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
            if( bVisible )
                Show( sal_True );
        }
    }
    else
    {
        if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
            nScreen = m_nScreen;
        if( nScreen != m_nScreen )
        {
            bool bVisible = bMapped_;
            if( mbFullScreen )
                pDisplay_->getWMAdaptor()->showFullScreen( this, false );
            if( bVisible )
                Show( sal_False );
            createNewWindow( None, nScreen );
            if( mbFullScreen )
                pDisplay_->getWMAdaptor()->showFullScreen( this, true );
            if( bVisible )
                Show( sal_True );
        }
        if( mbFullScreen == (bool)bFullScreen )
            return;
    
        pDisplay_->getWMAdaptor()->showFullScreen( this, bFullScreen );
        if( IsOverrideRedirect()
            && WMSupportsFWS( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen ) ) )
        {
            AddFwsProtocols( GetXDisplay(), GetShellWindow() );
            RegisterFwsWindow( GetXDisplay(), GetShellWindow() );
        }
    }
}

/* ---------------------------------------------------------------------
   the xautolock pseudo screen saver needs special treatment since it
   doesn't cooperate with XxxxScreenSaver settings
   ------------------------------------------------------------------- */

static Bool
IsRunningXAutoLock( Display *p_display, XLIB_Window a_window )
{
	const char *p_atomname = "XAUTOLOCK_SEMAPHORE_PID";
	Atom		a_pidatom;

	// xautolock interns this atom
	a_pidatom    = XInternAtom( p_display, p_atomname, True );
	if ( a_pidatom == None )
		return False;

	Atom          a_type;
	int           n_format;
	unsigned long n_items;
	unsigned long n_bytes_after;
	pid_t		 *p_pid;
	pid_t         n_pid;
	// get pid of running xautolock
	XGetWindowProperty (p_display, a_window, a_pidatom, 0L, 2L, False,
    		AnyPropertyType, &a_type, &n_format, &n_items, &n_bytes_after,
            (unsigned char**) &p_pid );
	n_pid = *p_pid;
	XFree( p_pid );

  	if ( a_type == XA_INTEGER )
  	{
		// check if xautolock pid points to a running process
		if ( kill(n_pid, 0) == -1 )
			return False;
		else
			return True;
	}

	return False;
}

/* definitions from xautolock.c (pl15) */
#define XAUTOLOCK_DISABLE 1
#define XAUTOLOCK_ENABLE  2

static Bool
MessageToXAutoLock( Display *p_display, int n_message )
{
	const char *p_atomname = "XAUTOLOCK_MESSAGE" ;
	Atom        a_messageatom;
	XLIB_Window a_rootwindow;

	a_rootwindow = RootWindowOfScreen( ScreenOfDisplay(p_display, 0) );
	if ( ! IsRunningXAutoLock(p_display, a_rootwindow) )
	{
		// remove any pending messages
		a_messageatom = XInternAtom( p_display, p_atomname, True );
		if ( a_messageatom != None )
			XDeleteProperty( p_display, a_rootwindow, a_messageatom );
		return False;
	}

	a_messageatom = XInternAtom( p_display, p_atomname, False );
	XChangeProperty (p_display, a_rootwindow, a_messageatom, XA_INTEGER,
    		8, PropModeReplace, (unsigned char*)&n_message, sizeof(n_message) );

	return True;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::StartPresentation( sal_Bool bStart )
{
    I18NStatus::get().show( !bStart, I18NStatus::presentation );
	if ( bStart )
		MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_DISABLE );
	else
		MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_ENABLE );

    if( ! bStart && hPresentationWindow != None )
        doReparentPresentationDialogues( GetDisplay() );
    hPresentationWindow = (bStart && IsOverrideRedirect() ) ? GetWindow() : None;
	
	
	// needs static here to save DPMS settings
    int dummy; 	
    static bool DPMSExtensionAvailable =
#ifndef SOLARIS
        (DPMSQueryExtension(GetXDisplay(), &dummy, &dummy) != 0);
	static sal_Bool DPMSEnabled = false;
#else
        false;
    bool DPMSEnabled = false;
    (void)dummy;
#define CARD16 unsigned short
#endif
	static CARD16 dpms_standby_timeout=0;
	static CARD16 dpms_suspend_timeout=0;
	static CARD16 dpms_off_timeout=0;
		
				
	if( bStart || nScreenSaversTimeout_ || DPMSEnabled)
	{
        if( hPresentationWindow )
        {
            /*  #i10559# workaround for WindowMaker: try to restore
             *  current focus after presentation window is gone
             */
            int revert_to = 0;
            XGetInputFocus( GetXDisplay(), &hPresFocusWindow, &revert_to );
        }
		int timeout, interval, prefer_blanking, allow_exposures;
		XGetScreenSaver( GetXDisplay(),
						 &timeout,
						 &interval,
						 &prefer_blanking,
						 &allow_exposures );
						 
				
		// get the DPMS state right before the start
		if (DPMSExtensionAvailable)
        {
#ifndef SOLARIS
			CARD16 state; // card16 is defined in Xdm.h 
			DPMSInfo(	GetXDisplay(), 
						&state, 
						&DPMSEnabled);
#endif
		} 				 
		if( bStart ) // start show 
		{	
			if ( timeout )
			{
				nScreenSaversTimeout_ = timeout;
				XResetScreenSaver( GetXDisplay() );
				XSetScreenSaver( GetXDisplay(),
								 0,
								 interval,
								 prefer_blanking,
								 allow_exposures );	  
			}
#ifndef SOLARIS
			if( DPMSEnabled )
			{
				if ( DPMSExtensionAvailable )
				{
					DPMSGetTimeouts(	GetXDisplay(), 
										&dpms_standby_timeout, 
										&dpms_suspend_timeout, 
										&dpms_off_timeout); 
					DPMSSetTimeouts(GetXDisplay(), 0,0,0); 	
				}
			}
#endif
		}				 
		else // if( !bStart ) // end of show
		{
			if( nScreenSaversTimeout_ ) 
			{
				XSetScreenSaver( GetXDisplay(),
							 nScreenSaversTimeout_,
							 interval,
							 prefer_blanking,
							 allow_exposures );
				nScreenSaversTimeout_ = 0;		
			}
#ifndef SOLARIS
			if ( DPMSEnabled )
			{			
				if ( DPMSExtensionAvailable )
				{
				// restore timeouts 
					DPMSSetTimeouts(GetXDisplay(), dpms_standby_timeout, 
						dpms_suspend_timeout, dpms_off_timeout); 
				}
			}
#endif
		}
	}
}

// Pointer
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::SetPointer( PointerStyle ePointerStyle )
{
	hCursor_ = pDisplay_->GetPointer( ePointerStyle );
	XDefineCursor( GetXDisplay(), GetWindow(), hCursor_ );

	if( IsCaptured() || nVisibleFloats > 0 )
		XChangeActivePointerGrab( GetXDisplay(),
						PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
						hCursor_,
						CurrentTime );
}

void X11SalFrame::SetPointerPos(long nX, long nY)
{
    /* #87921# when the application tries to center the mouse in the dialog the
     * window isn't mapped already. So use coordinates relative to the root window.
     */
    unsigned int nWindowLeft = maGeometry.nX + nX;
    unsigned int nWindowTop  = maGeometry.nY + nY;

    XWarpPointer( GetXDisplay(), None, pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() ),
                  0, 0, 0, 0, nWindowLeft, nWindowTop);
}

// delay handling of extended text input
#if !defined(__synchronous_extinput__)
void
X11SalFrame::PostExtTextEvent (sal_uInt16 nExtTextEventType, void *pExtTextEvent)
{
	XLIB_Window nFocusWindow = GetWindow();
	Atom 		nEventAtom	 = GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::SAL_EXTTEXTEVENT );

    XEvent aEvent;
    aEvent.xclient.type			= ClientMessage;
    aEvent.xclient.serial		= 0;
    aEvent.xclient.send_event	= True;
    aEvent.xclient.display		= GetXDisplay();
    aEvent.xclient.window		= nFocusWindow;
    aEvent.xclient.message_type	= nEventAtom;
    aEvent.xclient.format		= 32;

#if SAL_TYPES_SIZEOFLONG > 4
    aEvent.xclient.data.l[0] = (sal_uInt32)((long)pExtTextEvent & 0xffffffff);
    aEvent.xclient.data.l[1] = (sal_uInt32)((long)pExtTextEvent >> 32);
#else
    aEvent.xclient.data.l[0] = (sal_uInt32)((long)pExtTextEvent);
    aEvent.xclient.data.l[1] = 0;
#endif
    aEvent.xclient.data.l[2] = (sal_uInt32)nExtTextEventType;
    aEvent.xclient.data.l[3] = 0;
    aEvent.xclient.data.l[4] = 0;

    XPutBackEvent( GetXDisplay(), &aEvent );
}

void
X11SalFrame::HandleExtTextEvent (XClientMessageEvent *pEvent)
{
	#if SAL_TYPES_SIZEOFLONG > 4
	void* pExtTextEvent = (void*)(  (pEvent->data.l[0] & 0xffffffff)
								  | (pEvent->data.l[1] << 32) );
	#else
	void* pExtTextEvent = (void*)(pEvent->data.l[0]);
	#endif
	sal_uInt16 nExtTextEventType = sal_uInt16(pEvent->data.l[2]);

	CallCallback(nExtTextEventType, pExtTextEvent);

	switch (nExtTextEventType)
	{
		case SALEVENT_ENDEXTTEXTINPUT:
			break;

		case SALEVENT_EXTTEXTINPUT:
			break;

		default:

			fprintf(stderr, "X11SalFrame::HandleExtTextEvent: invalid extended input\n");
	}
}
#endif /* defined(__synchronous_extinput__) */

// PostEvent
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
sal_Bool X11SalFrame::PostEvent( void *pData )
{
    GetDisplay()->SendInternalEvent( this, pData );
	return sal_True;
}

// Title
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::SetTitle( const XubString& rTitle )
{
    if( ! ( IsChildWindow() || (nStyle_ & SAL_FRAME_STYLE_FLOAT ) ) )
    {
        m_aTitle = rTitle;
        GetDisplay()->getWMAdaptor()->setWMName( this, rTitle );
    }
}

// -----------------------------------------------------------------------

void X11SalFrame::Flush()
{
	XFlush( GetDisplay()->GetDisplay() );
}

// -----------------------------------------------------------------------

void X11SalFrame::Sync()
{
	XSync( GetDisplay()->GetDisplay(), False );
}

// Keyboard
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// -----------------------------------------------------------------------

void X11SalFrame::SetInputContext( SalInputContext* pContext )
{
  	if (pContext == NULL)
		return;

  	// 1. We should create an input context for this frame
  	//    only when SAL_INPUTCONTEXT_TEXT is set.

  	if (!(pContext->mnOptions & SAL_INPUTCONTEXT_TEXT))
    {
        if( mpInputContext )
            mpInputContext->Unmap( this );
		return;
    }

	// 2. We should use on-the-spot inputstyle
  	//    only when SAL_INPUTCONTEXT_EXTTEXTINPUT is set.

  	if (mpInputContext == NULL)
	{
        I18NStatus& rStatus( I18NStatus::get() );
        rStatus.setParent( this );
        mpInputContext = new SalI18N_InputContext( this );
		if (mpInputContext->UseContext())
		{
	  		mpInputContext->ExtendEventMask( GetShellWindow() );
	  		if (pContext->mnOptions & SAL_INPUTCONTEXT_CHANGELANGUAGE)
				mpInputContext->SetLanguage(pContext->meLanguage);
			if (mbInputFocus)
				mpInputContext->SetICFocus( this );
		}
  	}
    else
        mpInputContext->Map( this );
  	return;
}

// -----------------------------------------------------------------------

void X11SalFrame::EndExtTextInput( sal_uInt16 nFlags )
{
    if (mpInputContext != NULL)
  	    mpInputContext->EndExtTextInput( nFlags );
}

// -----------------------------------------------------------------------

XubString X11SalFrame::GetKeyName( sal_uInt16 nKeyCode )
{
	return GetDisplay()->GetKeyName( nKeyCode );
}

XubString X11SalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode )
{
  return GetKeyName( nKeyCode );
}

sal_Bool X11SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& )
{
    // not supported yet
    return sal_False;
}

LanguageType X11SalFrame::GetInputLanguage()
{
    // could be improved by checking unicode ranges of the last input
    return LANGUAGE_DONTKNOW;
}

// Settings
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

inline Color getColorFromLong( long nColor )
{
	return Color( (nColor & 0xff), (nColor & 0xff00)>>8, (nColor & 0xff0000)>>16);
}

void X11SalFrame::UpdateSettings( AllSettings& rSettings )
{

    DtIntegrator* pIntegrator = GetDisplay()->getDtIntegrator();
#if OSL_DEBUG_LEVEL > 1
    fprintf( stderr, "DtIntegrator: %d\n", pIntegrator ? pIntegrator->GetDtType() : -1 );
#endif
    if( pIntegrator )
        pIntegrator->GetSystemLook( rSettings );
}

void X11SalFrame::CaptureMouse( sal_Bool bCapture )
{
    nCaptured_ = pDisplay_->CaptureMouse( bCapture ? this : NULL );
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void X11SalFrame::SetParent( SalFrame* pNewParent )
{
    if( mpParent != pNewParent )
    {
        if( mpParent )
            mpParent->maChildren.remove( this );

        mpParent = static_cast<X11SalFrame*>(pNewParent);
        mpParent->maChildren.push_back( this );
        if( mpParent->m_nScreen != m_nScreen )
            createNewWindow( None, mpParent->m_nScreen );
        GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent );
    }
}

SalFrame* X11SalFrame::GetParent() const
{
    return mpParent;
}

void X11SalFrame::createNewWindow( XLIB_Window aNewParent, int nScreen )
{
    bool bWasVisible = bMapped_;
    if( bWasVisible )
        Show( sal_False );
    
    if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
        nScreen = m_nScreen;

    SystemParentData aParentData;
    aParentData.aWindow = aNewParent;
    aParentData.bXEmbedSupport = (aNewParent != None && m_bXEmbed); // caution: this is guesswork
    if( aNewParent == None )
    {
        aNewParent = GetDisplay()->GetRootWindow(nScreen);
        aParentData.aWindow = None;
        m_bXEmbed = false;
    }
    else
    {
        // is new parent a root window ?
        Display* pDisp = GetDisplay()->GetDisplay();
        int nScreens = GetDisplay()->GetScreenCount();
        for( int i = 0; i < nScreens; i++ )
        {
            if( aNewParent == RootWindow( pDisp, i ) )
            {
                nScreen = i;
                aParentData.aWindow = None;
                m_bXEmbed = false;
                break;
            }
        }
    }

    // first deinit frame
    updateGraphics(true);
    if( mpInputContext )
    {
        mpInputContext->UnsetICFocus( this );
        mpInputContext->Unmap( this );
    }
    if( GetWindow() == hPresentationWindow )
    {
        hPresentationWindow = None;
        doReparentPresentationDialogues( GetDisplay() );
    }
    XDestroyWindow( GetXDisplay(), mhWindow );
    mhWindow = None;

    passOnSaveYourSelf();

    // now init with new parent again
    if ( aParentData.aWindow != None )
	    Init( nStyle_ | SAL_FRAME_STYLE_PLUG, nScreen, &aParentData );
    else
	    Init( nStyle_ & ~SAL_FRAME_STYLE_PLUG, nScreen, NULL, true );

	// update graphics if necessary
    updateGraphics(false);
    
    if( m_aTitle.Len() )
        SetTitle( m_aTitle );
    
    if( mpParent )
    {
        if( mpParent->m_nScreen != m_nScreen )
            SetParent( NULL );
        else
            pDisplay_->getWMAdaptor()->changeReferenceFrame( this, mpParent );
    }

    if( bWasVisible )
        Show( sal_True );
    
    std::list< X11SalFrame* > aChildren = maChildren;
    for( std::list< X11SalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it )
        (*it)->createNewWindow( None, m_nScreen );
    
    // FIXME: SalObjects
}

bool X11SalFrame::SetPluginParent( SystemParentData* pNewParent )
{
    if( pNewParent->nSize >= sizeof(SystemParentData) )
        m_bXEmbed = pNewParent->aWindow != None && pNewParent->bXEmbedSupport;
    createNewWindow( pNewParent ? pNewParent->aWindow : None );

    return true;
}

// Sound
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void X11SalFrame::Beep( SoundType eSoundType ) // not fully suported
{
    switch( eSoundType )
    {
        case SOUND_DEFAULT:
        case SOUND_ERROR:
            GetDisplay()->Beep();
            break;
        default:
            // Excessive beeping averted
            break;
    }
}

// Event Handling
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
static sal_uInt16 sal_GetCode( int state )
{
	sal_uInt16 nCode = 0;

	if( state & Button1Mask )
		nCode |= MOUSE_LEFT;
	if( state & Button2Mask )
		nCode |= MOUSE_MIDDLE;
	if( state & Button3Mask )
		nCode |= MOUSE_RIGHT;

	if( state & ShiftMask )
		nCode |= KEY_SHIFT;
	if( state & ControlMask )
		nCode |= KEY_MOD1;
	if( state & Mod1Mask )
		nCode |= KEY_MOD2;

        // Map Meta/Super modifier to MOD3 on all Unix systems
        // except Mac OS X
        if( (state & Mod3Mask) )
            nCode |= KEY_MOD3;

	return nCode;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

SalFrame::SalPointerState X11SalFrame::GetPointerState()
{
    SalPointerState aState;
    XLIB_Window aRoot, aChild;
    int rx, ry, wx, wy;
    unsigned int nMask = 0;
    XQueryPointer( GetXDisplay(),
                   GetShellWindow(),
                   &aRoot,
                   &aChild,
                   &rx, &ry,
                   &wx, &wy,
                   &nMask
                   );

    aState.maPos = Point(wx, wy);
    aState.mnState = sal_GetCode( nMask );
    return aState;
}

long X11SalFrame::HandleMouseEvent( XEvent *pEvent )
{
	SalMouseEvent		aMouseEvt;
	sal_uInt16				nEvent = 0;
    bool				bClosePopups = false;

    if( nVisibleFloats && pEvent->type == EnterNotify )
        return 0;

	// Solaris X86: clicking the right button on a two-button mouse
	// generates a button2 event not a button3 event
	if (pDisplay_->GetProperties() & PROPERTY_SUPPORT_3ButtonMouse )
	{
		switch (pEvent->type)
		{
			case EnterNotify:
			case LeaveNotify:
				if ( pEvent->xcrossing.state & Button2Mask )
				{
					pEvent->xcrossing.state &= ~Button2Mask;
					pEvent->xcrossing.state |=	Button3Mask;
				}
				break;

			case MotionNotify:
				if ( pEvent->xmotion.state & Button2Mask )
				{
					pEvent->xmotion.state &= ~Button2Mask;
					pEvent->xmotion.state |=  Button3Mask;
				}
				break;

			default:
				if ( Button2 == pEvent->xbutton.button )
				{
					pEvent->xbutton.state &= ~Button2Mask;
					pEvent->xbutton.state |=  Button3Mask;
					pEvent->xbutton.button =  Button3;
				}
				break;
		}
	}


	if( LeaveNotify == pEvent->type || EnterNotify == pEvent->type )
	{
        /*
         *  #89075# #89335#
         *
         *  some WMs (and/or) applications  have a passive grab on
         *  mouse buttons (XGrabButton). This leads to enter/leave notifies
         *  with mouse buttons pressed in the state mask before the actual
         *  ButtonPress event gets dispatched. But EnterNotify
         *  is reported in vcl as MouseMove event. Some office code
         *  decides that a pressed button in a MouseMove belongs to
         *  a drag operation which leads to doing things differently.
         *
         *  #95901#
         *  ignore Enter/LeaveNotify resulting from grabs so that
         *  help windows do not disappear just after appearing
         *
         *  hopefully this workaround will not break anything.
         */
        if( pEvent->xcrossing.mode == NotifyGrab || pEvent->xcrossing.mode == NotifyUngrab  )
            return 0;

		aMouseEvt.mnX		= pEvent->xcrossing.x;
		aMouseEvt.mnY		= pEvent->xcrossing.y;
		aMouseEvt.mnTime	= pEvent->xcrossing.time;
        aMouseEvt.mnCode	= sal_GetCode( pEvent->xcrossing.state );
		aMouseEvt.mnButton	= 0;

		nEvent				= LeaveNotify == pEvent->type
							  ? SALEVENT_MOUSELEAVE
							  : SALEVENT_MOUSEMOVE;
	}
	else if( pEvent->type == MotionNotify )
	{
		aMouseEvt.mnX		= pEvent->xmotion.x;
		aMouseEvt.mnY		= pEvent->xmotion.y;
		aMouseEvt.mnTime	= pEvent->xmotion.time;
		aMouseEvt.mnCode	= sal_GetCode( pEvent->xmotion.state );

		aMouseEvt.mnButton	= 0;

		nEvent				= SALEVENT_MOUSEMOVE;
        if( nVisibleFloats > 0 && mpParent )
        {
            XLIB_Cursor aCursor = mpParent->GetCursor();
            if( pEvent->xmotion.x >= 0 && pEvent->xmotion.x < (int)maGeometry.nWidth &&
                pEvent->xmotion.y >= 0 && pEvent->xmotion.y < (int)maGeometry.nHeight )
                aCursor = None;

            XChangeActivePointerGrab( GetXDisplay(),
                                      PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
                                      aCursor,
                                      CurrentTime );
        }
	}
	else
	{
        // let mouse events reach the correct window
        if( nVisibleFloats < 1 )
        {
            if( ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
                XUngrabPointer( GetXDisplay(), CurrentTime );
        }
        else if( pEvent->type == ButtonPress )
        {
            // see if the user clicks outside all of the floats
            // if yes release the grab
            bool bInside = false;
            const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
            for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
            {
                const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
                if( pFrame->IsFloatGrabWindow()										&&
                    pFrame->bMapped_												&&
                    pEvent->xbutton.x_root >= pFrame->maGeometry.nX								&&
                    pEvent->xbutton.x_root < pFrame->maGeometry.nX + (int)pFrame->maGeometry.nWidth	&&
                    pEvent->xbutton.y_root >= pFrame->maGeometry.nY								&&
                    pEvent->xbutton.y_root < pFrame->maGeometry.nY + (int)pFrame->maGeometry.nHeight )
                {
                    bInside = true;
                    break;
                }
            }
            if( ! bInside )
            {
                // need not take care of the XUngrabPointer in Show( sal_False )
                // because XUngrabPointer does not produce errors if pointer
                // is not grabbed
                XUngrabPointer( GetXDisplay(), CurrentTime );
                bClosePopups = true;

                /*  #i15246# only close popups if pointer is outside all our frames
                 *  cannot use our own geometry data here because stacking
                 *  is unknown (the above case implicitly assumes
                 *  that floats are on top which should be true)
                 */
                XLIB_Window aRoot, aChild;
                int root_x, root_y, win_x, win_y;
                unsigned int mask_return;
                if( XQueryPointer( GetXDisplay(),
                                   GetDisplay()->GetRootWindow( m_nScreen ),
                                   &aRoot, &aChild,
                                   &root_x, &root_y,
                                   &win_x, &win_y,
                                   &mask_return )
                    && aChild // pointer may not be in any child
                    )
                {
                    for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
                    {
                        const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
                        if( ! pFrame->IsFloatGrabWindow()
                            && ( pFrame->GetWindow() == aChild ||
                                 pFrame->GetShellWindow() == aChild ||
                                 pFrame->GetStackingWindow() == aChild )
                            )
                        {
                            // #i63638# check that pointer is inside window, not
                            // only inside stacking window
                            if( root_x >= pFrame->maGeometry.nX && root_x < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nWidth) &&
                                root_y >= pFrame->maGeometry.nY && root_y < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nHeight) )
                            {
                                bClosePopups = false;
                            }
                            break;
                        }
                    }
                }
            }
        }
        
        if( m_bXEmbed && pEvent->xbutton.button == Button1 )
            askForXEmbedFocus( pEvent->xbutton.time );

		if( pEvent->xbutton.button == Button1 ||
			pEvent->xbutton.button == Button2 ||
			pEvent->xbutton.button == Button3 )
		{
			aMouseEvt.mnX		= pEvent->xbutton.x;
			aMouseEvt.mnY		= pEvent->xbutton.y;
			aMouseEvt.mnTime	= pEvent->xbutton.time;
			aMouseEvt.mnCode	= sal_GetCode( pEvent->xbutton.state );

			if( Button1 == pEvent->xbutton.button )
				aMouseEvt.mnButton	= MOUSE_LEFT;
			else if( Button2 == pEvent->xbutton.button )
				aMouseEvt.mnButton	= MOUSE_MIDDLE;
			else if( Button3 == pEvent->xbutton.button )
				aMouseEvt.mnButton	= MOUSE_RIGHT;

			nEvent				= ButtonPress == pEvent->type
				? SALEVENT_MOUSEBUTTONDOWN
				: SALEVENT_MOUSEBUTTONUP;
		}
		else if( pEvent->xbutton.button == Button4 ||
                 pEvent->xbutton.button == Button5 ||
                 pEvent->xbutton.button == Button6 ||
                 pEvent->xbutton.button == Button7 )
		{
            const bool bIncrement( 
                pEvent->xbutton.button == Button4 ||
                pEvent->xbutton.button == Button6 );
            const bool bHoriz( 
                pEvent->xbutton.button == Button6 ||
                pEvent->xbutton.button == Button7 );

            if( pEvent->type == ButtonRelease )
                return 0;

            static sal_uLong		nLines = 0;
			if( ! nLines )
			{
				char* pEnv = getenv( "SAL_WHEELLINES" );
				nLines = pEnv ? atoi( pEnv ) : 3;
				if( nLines > 10 )
					nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
			}

			SalWheelMouseEvent	aWheelEvt;
			aWheelEvt.mnTime		= pEvent->xbutton.time;
			aWheelEvt.mnX			= pEvent->xbutton.x;
			aWheelEvt.mnY			= pEvent->xbutton.y;
			aWheelEvt.mnDelta		= bIncrement ? 120 : -120;
			aWheelEvt.mnNotchDelta	= bIncrement ? 1 : -1;
			aWheelEvt.mnScrollLines = nLines;
			aWheelEvt.mnCode		= sal_GetCode( pEvent->xbutton.state );
			aWheelEvt.mbHorz		= bHoriz;

			nEvent = SALEVENT_WHEELMOUSE;

            // --- RTL --- (mirror mouse pos)
            if( Application::GetSettings().GetLayoutRTL() )
                aWheelEvt.mnX = nWidth_-1-aWheelEvt.mnX;
			return CallCallback( nEvent, &aWheelEvt );
		}
	}

    int nRet = 0;
	if( nEvent == SALEVENT_MOUSELEAVE
		|| ( aMouseEvt.mnX <  nWidth_  && aMouseEvt.mnX >  -1 &&
			 aMouseEvt.mnY <  nHeight_ && aMouseEvt.mnY >  -1 )
		|| pDisplay_->MouseCaptured( this )
        )
    {
        // --- RTL --- (mirror mouse pos)
        if( Application::GetSettings().GetLayoutRTL() )
            aMouseEvt.mnX = nWidth_-1-aMouseEvt.mnX;
		nRet = CallCallback( nEvent, &aMouseEvt );
    }

    if( bClosePopups )
    {
        /*  #108213# close popups after dispatching the event outside the popup;
         *  applications do weird things.
         */
        ImplSVData* pSVData = ImplGetSVData();
        if ( pSVData->maWinData.mpFirstFloat )
        {
            static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
            if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) && !(pEnv && *pEnv) )
                pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
        }
    }

	return nRet;
}

// F10 means either KEY_F10 or KEY_MENU, which has to be decided
// in the independent part.
struct KeyAlternate
{
	sal_uInt16			nKeyCode;
	sal_Unicode		nCharCode;
	KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {}
	KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {}
};

inline KeyAlternate
GetAlternateKeyCode( const sal_uInt16 nKeyCode )
{
	KeyAlternate aAlternate;

	switch( nKeyCode )
	{
		case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break;
		case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break;
	}

	return aAlternate;
}

void X11SalFrame::beginUnicodeSequence()
{
    rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );
    DeletionListener aDeleteWatch( this );

    if( rSeq.getLength() )
        endUnicodeSequence();

    rSeq = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "u" ) );

    if( ! aDeleteWatch.isDeleted() )
    {
        sal_uInt16 nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
        SalExtTextInputEvent aEv;
        aEv.mnTime          = 0;
        aEv.maText          = rSeq;
        aEv.mpTextAttr      = &nTextAttr;
        aEv.mnCursorPos     = 0;
        aEv.mnDeltaStart    = 0;
        aEv.mnCursorFlags   = 0;
        aEv.mbOnlyCursor    = sal_False;
        
        CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
    }
}

bool X11SalFrame::appendUnicodeSequence( sal_Unicode c )
{
    bool bRet = false;
    rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );
    if( rSeq.getLength() > 0 )
    {
        // range check
        if( (c >= sal_Unicode('0') && c <= sal_Unicode('9')) ||
            (c >= sal_Unicode('a') && c <= sal_Unicode('f')) ||
            (c >= sal_Unicode('A') && c <= sal_Unicode('F')) )
        {
            rtl::OUStringBuffer aBuf( rSeq.getLength() + 1 );
            aBuf.append( rSeq );
            aBuf.append( c );
            rSeq = aBuf.makeStringAndClear();
            std::vector<sal_uInt16> attribs( rSeq.getLength(), SAL_EXTTEXTINPUT_ATTR_UNDERLINE );

            SalExtTextInputEvent aEv;
            aEv.mnTime          = 0;
            aEv.maText          = rSeq;
            aEv.mpTextAttr      = &attribs[0];
            aEv.mnCursorPos     = 0;
            aEv.mnDeltaStart    = 0;
            aEv.mnCursorFlags   = 0;
            aEv.mbOnlyCursor    = sal_False;
            
            CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
            bRet = true;
        }
        else
            bRet = endUnicodeSequence();
    }
    else
        endUnicodeSequence();
    return bRet;
}

bool X11SalFrame::endUnicodeSequence()
{
    rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );

    DeletionListener aDeleteWatch( this );
    if( rSeq.getLength() > 1 && rSeq.getLength() < 6 )
    {
        // cut the "u"
        rtl::OUString aNumbers( rSeq.copy( 1 ) );
        sal_Int32 nValue = aNumbers.toInt32( 16 );
        if( nValue >= 32 )
        {
            sal_uInt16 nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
            SalExtTextInputEvent aEv;
            aEv.mnTime          = 0;
            aEv.maText          = rtl::OUString( sal_Unicode(nValue) );
            aEv.mpTextAttr      = &nTextAttr;
            aEv.mnCursorPos     = 0;
            aEv.mnDeltaStart    = 0;
            aEv.mnCursorFlags   = 0;
            aEv.mbOnlyCursor    = sal_False;
            CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
        }
    }
    bool bWasInput = rSeq.getLength() > 0;
    rSeq = rtl::OUString();
    if( bWasInput && ! aDeleteWatch.isDeleted() )
        CallCallback(SALEVENT_ENDEXTTEXTINPUT, NULL);
    return bWasInput;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent )
{
	KeySym			nKeySym;
    KeySym          nUnmodifiedKeySym;
	int 			nLen = 2048;
	unsigned char	*pPrintable = (unsigned char*)alloca( nLen );

	// singlebyte code composed by input method, the new default
	if (mpInputContext != NULL && mpInputContext->UseContext())
	{
		// returns a keysym as well as the pPrintable (in system encoding)
		// printable may be empty.
		Status nStatus;
    	nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
                                        &nUnmodifiedKeySym,
                                        &nStatus, mpInputContext->GetContext() );
		if ( nStatus == XBufferOverflow )
		{
			nLen *= 2;
			pPrintable = (unsigned char*)alloca( nLen );
			nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
                                            &nUnmodifiedKeySym,
                                            &nStatus, mpInputContext->GetContext() );
		}
	}
	else
	{
		// fallback, this should never ever be called
		Status nStatus = 0;
       	nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, &nUnmodifiedKeySym, &nStatus );
 	}

	SalKeyEvent aKeyEvt;
	sal_uInt16      nKeyCode;
	sal_uInt16 nModCode = 0;
	char		aDummy;

	if( pEvent->state & ShiftMask )
		nModCode |= KEY_SHIFT;
	if( pEvent->state & ControlMask )
		nModCode |= KEY_MOD1;
	if( pEvent->state & Mod1Mask )
		nModCode |= KEY_MOD2;
    
    if( nModCode != (KEY_SHIFT|KEY_MOD1) )
        endUnicodeSequence();

	if( 	nKeySym == XK_Shift_L 	|| nKeySym == XK_Shift_R
		|| 	nKeySym == XK_Control_L || nKeySym == XK_Control_R
		|| 	nKeySym == XK_Alt_L		|| nKeySym == XK_Alt_R
		|| 	nKeySym == XK_Meta_L 	|| nKeySym == XK_Meta_R
                ||      nKeySym == XK_Super_L   || nKeySym == XK_Super_R )
	{
		SalKeyModEvent aModEvt;
        aModEvt.mnModKeyCode = 0;
        if( pEvent->type == XLIB_KeyPress && mnExtKeyMod == 0 )
            mbSendExtKeyModChange = true;
        else if( pEvent->type == KeyRelease && mbSendExtKeyModChange )
        {
            aModEvt.mnModKeyCode = mnExtKeyMod;
            mnExtKeyMod = 0;
        }

		// pressing just the ctrl key leads to a keysym of XK_Control but
		// the event state does not contain ControlMask. In the release
		// event its the other way round: it does contain the Control mask.
		// The modifier mode therefore has to be adapted manually.
        sal_uInt16 nExtModMask = 0;
        sal_uInt16 nModMask = 0;
        switch( nKeySym )
        {
            case XK_Control_L:
                nExtModMask = MODKEY_LMOD1;
                nModMask = KEY_MOD1;
                break;
            case XK_Control_R:
                nExtModMask = MODKEY_RMOD1;
                nModMask = KEY_MOD1;
                break;
            case XK_Alt_L:
                nExtModMask = MODKEY_LMOD2;
                nModMask = KEY_MOD2;
                break;
            case XK_Alt_R:
                nExtModMask = MODKEY_RMOD2;
                nModMask = KEY_MOD2;
                break;
            case XK_Shift_L:
                nExtModMask = MODKEY_LSHIFT;
                nModMask = KEY_SHIFT;
                break;
            case XK_Shift_R:
                nExtModMask = MODKEY_RSHIFT;
                nModMask = KEY_SHIFT;
                break;
            // Map Meta/Super keys to MOD3 modifier on all Unix systems
            // except Mac OS X
            case XK_Meta_L:
            case XK_Super_L:
                nExtModMask = MODKEY_LMOD3;
                nModMask = KEY_MOD3;
                break;
            case XK_Meta_R:
            case XK_Super_R:
                nExtModMask = MODKEY_RMOD3;
                nModMask = KEY_MOD3;
                break;
        }
        if( pEvent->type == KeyRelease )
        {
            nModCode &= ~nModMask;
            mnExtKeyMod &= ~nExtModMask;
        }
        else
        {
            nModCode |= nModMask;
            mnExtKeyMod |= nExtModMask;
        }

		aModEvt.mnCode = nModCode;
		aModEvt.mnTime = pEvent->time;

		int nRet = CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );

        // emulate KEY_MENU
        if ( ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) ) &&
             ( (nModCode & ~(KEY_MOD3|KEY_MOD2)) == 0 ) )
        {
            if( pEvent->type == XLIB_KeyPress )
                mbKeyMenu = true;
            else if( mbKeyMenu )
            {
                // simulate KEY_MENU
                aKeyEvt.mnCode	   = KEY_MENU | nModCode;
                aKeyEvt.mnRepeat   = 0;
                aKeyEvt.mnTime	   = pEvent->time;
                aKeyEvt.mnCharCode = 0;
                nRet = CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
                nRet = CallCallback( SALEVENT_KEYUP, &aKeyEvt );
            }
        }
        else
            mbKeyMenu = false;
        return nRet;
	}

    mbSendExtKeyModChange = mbKeyMenu = false;

	// try to figure out the vcl code for the keysym
    // #i52338# use the unmodified KeySym if there is none for the real KeySym
    // because the independent part has only keycodes for unshifted keys
	nKeyCode = pDisplay_->GetKeyCode( nKeySym, &aDummy );
    if( nKeyCode == 0 )
        nKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy );

	// try to figure out a printable if XmbLookupString returns only a keysym
	// and NOT a printable. Do not store it in pPrintable[0] since it is expected to
	// be in system encoding, not unicode.
    // #i8988##, if KeySym and printable look equally promising then prefer KeySym
    // the printable is bound to the encoding so the KeySym might contain more
    // information (in et_EE locale: "Compose + Z + <" delivers "," in printable and
    // (the desired) Zcaron in KeySym
	sal_Unicode nKeyString = 0x0;
	if (   (nLen == 0) 
        || ((nLen == 1) && (nKeySym > 0)) )
		nKeyString = KeysymToUnicode (nKeySym);
	// if we have nothing we give up
	if( !nKeyCode && !nLen && !nKeyString)
		return 0;
    
    DeletionListener aDeleteWatch( this );

    if( nModCode == (KEY_SHIFT | KEY_MOD1) && pEvent->type == XLIB_KeyPress )
    {
        sal_uInt16 nSeqKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy );
        if( nSeqKeyCode == KEY_U )
        {
            beginUnicodeSequence();
            return 1;
        }
        else if( nSeqKeyCode >= KEY_0 && nSeqKeyCode <= KEY_9 )
        {
            if( appendUnicodeSequence( sal_Unicode( '0' ) + sal_Unicode(nSeqKeyCode - KEY_0) ) )
                return 1;
        }
        else if( nSeqKeyCode >= KEY_A && nSeqKeyCode <= KEY_F )
        {
            if( appendUnicodeSequence( sal_Unicode( 'a' ) + sal_Unicode(nSeqKeyCode - KEY_A) ) )
                return 1;
        }
        else
            endUnicodeSequence();
    }
    
    if( aDeleteWatch.isDeleted() )
        return 0;

	rtl_TextEncoding nEncoding;

    if (mpInputContext != NULL && mpInputContext->IsMultiLingual() )
        nEncoding = RTL_TEXTENCODING_UTF8;
    else
        nEncoding = osl_getThreadTextEncoding();

	sal_Unicode *pBuffer;
	sal_Unicode *pString;
	sal_Size     nBufferSize = nLen * 2;
	sal_Size     nSize;
	pBuffer = (sal_Unicode*) malloc( nBufferSize + 2 );
	pBuffer[ 0 ] = 0;

	if (nKeyString != 0)
	{
		pString = &nKeyString;
		nSize = 1;
	}
	else
	if (nLen > 0 && nEncoding != RTL_TEXTENCODING_UNICODE)
	{
		// create text converter
		rtl_TextToUnicodeConverter aConverter =
				rtl_createTextToUnicodeConverter( nEncoding );
		rtl_TextToUnicodeContext aContext =
			 	rtl_createTextToUnicodeContext( aConverter );

		sal_uInt32  nConversionInfo;
		sal_Size    nConvertedChars;

		// convert to single byte text stream
		nSize = rtl_convertTextToUnicode(
				                aConverter, aContext,
                                (char*)pPrintable, nLen,
                                pBuffer, nBufferSize,
                                RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE |
                                RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE,
                                &nConversionInfo, &nConvertedChars );

		// destroy converter
		rtl_destroyTextToUnicodeContext( aConverter, aContext );
		rtl_destroyTextToUnicodeConverter( aConverter );

		pString = pBuffer;
	}
	else
	if (nLen > 0 /* nEncoding == RTL_TEXTENCODING_UNICODE */)
	{
		pString = (sal_Unicode*)pPrintable;
	  	nSize = nLen;
	}
    else
    {
        pString = pBuffer;
        nSize   = 0;
    }

	if (   mpInputContext != NULL
		&& mpInputContext->UseContext()
		&& KeyRelease != pEvent->type
		&& (   (nSize >  1)
            || (nSize >  0 && mpInputContext->IsPreeditMode())) )
	{
        mpInputContext->CommitKeyEvent(pString, nSize);
	}
	else
    // normal single character keyinput
	{
		aKeyEvt.mnCode	   = nKeyCode | nModCode;
		aKeyEvt.mnRepeat   = 0;
		aKeyEvt.mnTime	   = pEvent->time;
		aKeyEvt.mnCharCode = pString[ 0 ];

		if( KeyRelease == pEvent->type )
		{
			CallCallback( SALEVENT_KEYUP, &aKeyEvt );
		}
		else
		{
			if ( ! CallCallback(SALEVENT_KEYINPUT, &aKeyEvt) )
			{
				// independent layer doesn't want to handle key-event, so check
				// whether the keycode may have an alternate meaning
				KeyAlternate aAlternate = GetAlternateKeyCode( nKeyCode );
				if ( aAlternate.nKeyCode != 0 )
				{
					aKeyEvt.mnCode = aAlternate.nKeyCode | nModCode;
					if( aAlternate.nCharCode )
						aKeyEvt.mnCharCode = aAlternate.nCharCode;
					CallCallback(SALEVENT_KEYINPUT, &aKeyEvt);
				}
			}
		}
	}

  	//
  	// update the spot location for PreeditPosition IME style
  	//
    if (! aDeleteWatch.isDeleted())
    {
        if (mpInputContext != NULL && mpInputContext->UseContext())
            mpInputContext->UpdateSpotLocation();
    }

	free (pBuffer);
	return True;
}


// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleFocusEvent( XFocusChangeEvent *pEvent )
{
    // #107739# ReflectionX in Windows mode changes focus while mouse is grabbed
	if( nVisibleFloats > 0 && GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "ReflectionX Windows" ) )
		return 1;

	/*	#55691# ignore focusout resulting from keyboard grabs
	 *	we do not grab it and are not interested when
	 *	someone else does CDE e.g. does a XGrabKey on arrow keys
	 *	#73179# handle focus events with mode NotifyWhileGrabbed
	 *	because with CDE alt-tab focus changing we do not get
	 *	normal focus events
	 *	#71791# cast focus event to the input context, otherwise the
	 *	status window does not follow the application frame
	 */

	if ( mpInputContext != NULL  )
	{
		if( FocusIn == pEvent->type )
            mpInputContext->SetICFocus( this );
        else
        {
            /*
             *  do not unset the IC focuse here because would kill
             *  a lookup choice windows that might have the focus now
             *  	mpInputContext->UnsetICFocus( this );
             */
            I18NStatus::get().show( false, I18NStatus::focus );
        }
	}


	if ( pEvent->mode == NotifyNormal || pEvent->mode == NotifyWhileGrabbed ||
         ( ( nStyle_ & SAL_FRAME_STYLE_PLUG ) && pEvent->window == GetShellWindow() )
         )
	{
        if( hPresentationWindow != None && hPresentationWindow != GetShellWindow() )
            return 0;

		if( FocusIn == pEvent->type )
		{
            vcl_sal::PrinterUpdate::update();
			mbInputFocus = True;
            ImplSVData* pSVData = ImplGetSVData();



			long nRet = CallCallback( SALEVENT_GETFOCUS,  0 );
            if ((mpParent != NULL && nStyle_ == 0)
                && pSVData->maWinData.mpFirstFloat )
            {
                sal_uLong nMode = pSVData->maWinData.mpFirstFloat->GetPopupModeFlags();
                pSVData->maWinData.mpFirstFloat->SetPopupModeFlags(
                                        nMode & ~(FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE));
            }
            return nRet;
		}
		else
		{
			mbInputFocus = False;
            mbSendExtKeyModChange = mbKeyMenu = false;
            mnExtKeyMod = 0;
			return CallCallback( SALEVENT_LOSEFOCUS, 0 );
		}
	}

	return 0;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

long X11SalFrame::HandleExposeEvent( XEvent *pEvent )
{
	XRectangle	aRect = { 0, 0, 0, 0 };
	sal_uInt16		nCount = 0;

	if( pEvent->type == Expose )
	{
		aRect.x 		= pEvent->xexpose.x;
		aRect.y 		= pEvent->xexpose.y;
		aRect.width 	= pEvent->xexpose.width;
		aRect.height	= pEvent->xexpose.height;
		nCount			= pEvent->xexpose.count;
	}
	else if( pEvent->type == GraphicsExpose )
	{
		aRect.x 		= pEvent->xgraphicsexpose.x;
		aRect.y 		= pEvent->xgraphicsexpose.y;
		aRect.width 	= pEvent->xgraphicsexpose.width;
		aRect.height	= pEvent->xgraphicsexpose.height;
		nCount			= pEvent->xgraphicsexpose.count;
	}

    if( IsOverrideRedirect() && mbFullScreen &&
        aPresentationReparentList.begin() == aPresentationReparentList.end() )
		// we are in fullscreen mode -> override redirect
 		// focus is possibly lost, so reget it
 		XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToNone, CurrentTime );

    // width and height are extents, so they are of by one for rectangle
    maPaintRegion.Union( Rectangle( Point(aRect.x, aRect.y), Size(aRect.width+1, aRect.height+1) ) );

	if( nCount )
        // wait for last expose rectangle, do not wait for resize timer
        // if a completed graphics expose sequence is available
		return 1;

	SalPaintEvent aPEvt( maPaintRegion.Left(), maPaintRegion.Top(), maPaintRegion.GetWidth(), maPaintRegion.GetHeight() );

 	CallCallback( SALEVENT_PAINT, &aPEvt );
    maPaintRegion = Rectangle();

	return 1;
}

void X11SalFrame::RestackChildren( XLIB_Window* pTopLevelWindows, int nTopLevelWindows )
{
    if( maChildren.begin() != maChildren.end() )
    {
        int nWindow = nTopLevelWindows;
        while( nWindow-- )
            if( pTopLevelWindows[nWindow] == GetStackingWindow() )
                break;
        if( nWindow < 0 )
            return;

        std::list< X11SalFrame* >::const_iterator it;
        for( it = maChildren.begin(); it != maChildren.end(); ++it )
        {
            X11SalFrame* pData = *it;
            if( pData->bMapped_ )
            {
                int nChild = nWindow;
                while( nChild-- )
                {
                    if( pTopLevelWindows[nChild] == pData->GetStackingWindow() )
                    {
                        // if a child is behind its parent, place it above the
                        // parent (for insane WMs like Dtwm and olwm)
                        XWindowChanges aCfg;
                        aCfg.sibling	= GetStackingWindow();
                        aCfg.stack_mode	= Above;
                        XConfigureWindow( GetXDisplay(), pData->GetStackingWindow(), CWSibling|CWStackMode, &aCfg );
                        break;
                    }
                }
            }
        }
        for( it = maChildren.begin(); it != maChildren.end(); ++it )
        {
            X11SalFrame* pData = *it;
            pData->RestackChildren( pTopLevelWindows, nTopLevelWindows );
        }
    }
}

void X11SalFrame::RestackChildren()
{
    if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected()
        && maChildren.begin() != maChildren.end() )
    {
        XLIB_Window aRoot, aParent, *pChildren = NULL;
        unsigned int nChildren;
        if( XQueryTree( GetXDisplay(),
                        GetDisplay()->GetRootWindow( m_nScreen ),
                        &aRoot,
                        &aParent,
                        &pChildren,
                        &nChildren ) )
        {
            RestackChildren( pChildren, nChildren );
            XFree( pChildren );
        }
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleSizeEvent( XConfigureEvent *pEvent )
{
	if (   pEvent->window != GetShellWindow()
           && pEvent->window != GetWindow()
           && pEvent->window != GetForeignParent()
           && pEvent->window != GetStackingWindow()
           )
	{
		// could be as well a sys-child window (aka SalObject)
		return 1;
	}


	if( ( nStyle_ & SAL_FRAME_STYLE_PLUG ) && pEvent->window == GetShellWindow() )
	{
		// just update the children's positions
		RestackChildren();
		return 1;
	}

	if( pEvent->window == GetForeignParent() )
        XResizeWindow( GetXDisplay(),
                       GetWindow(),
                       pEvent->width,
                       pEvent->height );

	XLIB_Window hDummy;
	XTranslateCoordinates( GetXDisplay(),
						   GetWindow(),
						   pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() ),
						   0, 0,
						   &pEvent->x, &pEvent->y,
						   &hDummy );

    if( pEvent->window == GetStackingWindow() )
    {
        if( maGeometry.nX != pEvent->x || maGeometry.nY != pEvent->y )
        {
            maGeometry.nX = pEvent->x;
            maGeometry.nY = pEvent->y;
            CallCallback( SALEVENT_MOVE, NULL );
        }
        return 1;
    }

    // check size hints in first time SalFrame::Show
	if( SHOWSTATE_UNKNOWN == nShowState_ && bMapped_ )
        nShowState_ = SHOWSTATE_NORMAL;

    nWidth_ 	= pEvent->width;
    nHeight_	= pEvent->height;

    bool bMoved = ( pEvent->x != maGeometry.nX || pEvent->y != maGeometry.nY );
    bool bSized = ( pEvent->width != (int)maGeometry.nWidth || pEvent->height != (int)maGeometry.nHeight );

    maGeometry.nX		= pEvent->x;
    maGeometry.nY		= pEvent->y;
    maGeometry.nWidth	= pEvent->width;
    maGeometry.nHeight	= pEvent->height;
    updateScreenNumber();

	// update children's position
	RestackChildren();

    if( bSized && ! bMoved )
        CallCallback( SALEVENT_RESIZE, NULL );
    else if( bMoved && ! bSized )
        CallCallback( SALEVENT_MOVE, NULL );
    else if( bMoved && bSized )
        CallCallback( SALEVENT_MOVERESIZE, NULL );

	return 1;
}

IMPL_LINK( X11SalFrame, HandleAlwaysOnTopRaise, void*, EMPTYARG )
{
    if( bMapped_ )
        ToTop( 0 );
    return 0;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleReparentEvent( XReparentEvent *pEvent )
{
	Display 	   *pDisplay   = pEvent->display;
	XLIB_Window 	hWM_Parent;
	XLIB_Window 	hRoot, *Children, hDummy;
	unsigned int	nChildren;
	sal_Bool			bNone = pDisplay_->GetProperties()
							& PROPERTY_SUPPORT_WM_Parent_Pixmap_None;
    sal_Bool            bAccessParentWindow = ! (pDisplay_->GetProperties()
							& PROPERTY_FEATURE_TrustedSolaris);

	static const char* pDisableStackingCheck = getenv( "SAL_DISABLE_STACKING_CHECK" );

    GetDisplay()->GetXLib()->PushXErrorLevel( true );

    /*
     *  #89186# don't rely on the new parent from the event.
     *  the event may be "out of date", that is the window manager
     *  window may not exist anymore. This can happen if someone
     *  shows a frame and hides it again quickly (not that that would
     *  be very sensible)
     */
    hWM_Parent = GetShellWindow();
    do
    {
        Children = NULL;
        XQueryTree( pDisplay,
                    hWM_Parent,
                    &hRoot,
                    &hDummy,
                    &Children,
                    &nChildren );
        if( GetDisplay()->GetXLib()->HasXErrorOccured() )
        {
            hWM_Parent = GetShellWindow();
            break;
        }
         /* #107048# this sometimes happens if a Show(sal_True) is
         *  immediately followed by Show(sal_False) (which is braindead anyway)
         */
        if(  hDummy == hWM_Parent )
            hDummy = hRoot;
        if( hDummy != hRoot )
        {
            hWM_Parent = hDummy;
            if( bAccessParentWindow && bNone )
                XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None );
        }
        if( Children )
            XFree( Children );
    } while( hDummy != hRoot );

	if( GetStackingWindow() == None
        && hWM_Parent != hPresentationWindow
        && hWM_Parent != GetShellWindow()
        && ( ! pDisableStackingCheck || ! *pDisableStackingCheck )
        )
	{
		mhStackingWindow = hWM_Parent;
		if (bAccessParentWindow)
            XSelectInput( pDisplay, GetStackingWindow(), StructureNotifyMask );
	}

	if( 	hWM_Parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() )
            || 	hWM_Parent == GetForeignParent()
            || 	pEvent->parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() )
            || ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) )
	{
		// Reparenting before Destroy
        aPresentationReparentList.remove( GetStackingWindow() );
		mhStackingWindow = None;
        GetDisplay()->GetXLib()->PopXErrorLevel();
		return 0;
	}

    /*
     *  evil hack to show decorated windows on top
     *  of override redirect presentation windows:
     *  reparent the window manager window to the presentation window
     *  does not work with non-reparenting WMs
     *  in future this should not be necessary anymore with
     *  _NET_WM_STATE_FULLSCREEN available
     */
    if( hPresentationWindow != None
        && hPresentationWindow != GetWindow()
        && GetStackingWindow() != None
        && GetStackingWindow() != GetDisplay()->GetRootWindow( m_nScreen )
        )
    {
        int x = 0, y = 0;
        XLIB_Window aChild;
        XTranslateCoordinates( GetXDisplay(),
                               GetStackingWindow(),
                               GetDisplay()->GetRootWindow( m_nScreen ),
                               0, 0,
                               &x, &y,
                               &aChild
                               );
        XReparentWindow( GetXDisplay(),
                         GetStackingWindow(),
                         hPresentationWindow,
                         x, y
                         );
        aPresentationReparentList.push_back( GetStackingWindow() );
    }

    int nLeft = 0, nTop = 0;
	XTranslateCoordinates( GetXDisplay(),
                           GetShellWindow(),
                           hWM_Parent,
                           0, 0,
                           &nLeft,
                           &nTop,
                           &hDummy );
    maGeometry.nLeftDecoration	= nLeft > 0 ? nLeft-1 : 0;
    maGeometry.nTopDecoration	= nTop  > 0 ? nTop-1  : 0;

    /*
     *  decorations are not symmetric,
     *  so need real geometries here
     *  (this will fail with virtual roots ?)
     */
    GetDisplay()->GetXLib()->ResetXErrorOccured();
    int xp, yp, x, y;
    unsigned int wp, w, hp, h, bw, d;
    XGetGeometry( GetXDisplay(),
                  GetShellWindow(),
                  &hRoot,
                  &x, &y, &w, &h, &bw, &d );
    XGetGeometry( GetXDisplay(),
                  hWM_Parent,
                  &hRoot,
                  &xp, &yp, &wp, &hp, &bw, &d );
    bool bResized = false;
    if( ! GetDisplay()->GetXLib()->HasXErrorOccured() )
    {
        maGeometry.nRightDecoration 	= wp - w - maGeometry.nLeftDecoration;
        maGeometry.nBottomDecoration	= hp - h - maGeometry.nTopDecoration;
        /*
         *  note: this works because hWM_Parent is direct child of root,
         *  not necessarily parent of GetShellWindow()
         */
        maGeometry.nX		= xp + nLeft;
        maGeometry.nY		= yp + nTop;
        bResized = w != maGeometry.nWidth || h != maGeometry.nHeight;
        maGeometry.nWidth	= w;
        maGeometry.nHeight = h;
    }


    // limit width and height if we are too large: #47757
    // olwm and fvwm need this, it doesn't harm the rest

    // #i81311# do this only for sizable frames
    if( (nStyle_ & SAL_FRAME_STYLE_SIZEABLE) != 0 )
    {
        Size aScreenSize = GetDisplay()->GetScreenSize( m_nScreen );
        int nScreenWidth  = aScreenSize.Width();
        int nScreenHeight = aScreenSize.Height();
        int nFrameWidth   = maGeometry.nWidth + maGeometry.nLeftDecoration + maGeometry.nRightDecoration;
        int nFrameHeight  = maGeometry.nHeight + maGeometry.nTopDecoration  + maGeometry.nBottomDecoration;
    
        if ((nFrameWidth > nScreenWidth) || (nFrameHeight > nScreenHeight))
        {
            Size aSize(maGeometry.nWidth, maGeometry.nHeight);
    
            if (nFrameWidth  > nScreenWidth)
                aSize.Width()  = nScreenWidth  - maGeometry.nRightDecoration - maGeometry.nLeftDecoration;
            if (nFrameHeight > nScreenHeight)
                aSize.Height() = nScreenHeight - maGeometry.nBottomDecoration - maGeometry.nTopDecoration;
    
            SetSize( aSize );
            bResized = false;
        }
    }
    if( bResized )
        CallCallback( SALEVENT_RESIZE, NULL );

    GetDisplay()->GetXLib()->PopXErrorLevel();

	return 1;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleColormapEvent( XColormapEvent* )
{
	return 0;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleStateEvent( XPropertyEvent *pEvent )
{
	Atom		  actual_type;
	int 		  actual_format;
	unsigned long nitems, bytes_after;
	unsigned char *prop = NULL;

	if( 0 != XGetWindowProperty( GetXDisplay(),
								 GetShellWindow(),
								 pEvent->atom,			// property
								 0, 					// long_offset (32bit)
								 2, 					// long_length (32bit)
								 False, 				// delete
								 pEvent->atom,			// req_type
								 &actual_type,
								 &actual_format,
								 &nitems,
								 &bytes_after,
								 &prop )
		|| ! prop
		)
		return 0;

	DBG_ASSERT( actual_type = pEvent->atom
				&& 32 == actual_format
				&&	2 == nitems
				&&	0 == bytes_after, "HandleStateEvent" );

	if( *(unsigned long*)prop == NormalState )
		nShowState_ = SHOWSTATE_NORMAL;
	else if( *(unsigned long*)prop == IconicState )
		nShowState_ = SHOWSTATE_MINIMIZED;

	XFree( prop );
	return 1;
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent )
{
    const WMAdaptor& rWMAdaptor( *pDisplay_->getWMAdaptor() );

#if !defined(__synchronous_extinput__)
	if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_EXTTEXTEVENT ) )
	{
		HandleExtTextEvent (pEvent);
		return 1;
	}
#endif
	else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_QUITEVENT ) )
	{
		stderr0( "X11SalFrame::Dispatch Quit\n" );
		Close(); // ???
		return 1;
	}
	else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) )
    {
        if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::NET_WM_PING ) )
            rWMAdaptor.answerPing( this, pEvent );
        else if( ! ( nStyle_ & SAL_FRAME_STYLE_PLUG )
              && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION))
             )
        {
            if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) )
            {
                Close();
                return 1;
            }
            else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) )
            {
                // do nothing, we set the input focus in ToTop() if necessary
    #if OSL_DEBUG_LEVEL > 1
                fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n",
                         (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ?
                         "ownerdraw" : "NON OWNERDRAW" );
    #endif
            }
            else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) )
            {
                bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" );
                
                if( ! bSession )
                {
                    if( this == s_pSaveYourselfFrame )
                    {
                        ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
                        const char* argv[2];
                        argv[0] = "/bin/sh";
                        argv[1] = const_cast<char*>(aExec.GetBuffer());
    #if OSL_DEBUG_LEVEL > 1
                        fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] );
    #endif
                        XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 );
                    }
                    else
                        // can only happen in race between WM and window closing
                        XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 );
                }
                else
                {
                    // save open documents; would be good for non Dtwm, too,
                    // but there is no real Shutdown message in the ancient
                    // SM protocol; on Dtwm SaveYourself really means Shutdown, too.
                    IceSalSession::handleOldX11SaveYourself( this );
                }
            }
        }
    }
    else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::XEMBED ) &&
             pEvent->window == GetWindow() )
    {
        if( pEvent->data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE
            pEvent->data.l[1] == 2 )  // XEMBED_WINDOW_DEACTIVATE
        {
            XFocusChangeEvent aEvent;
            aEvent.type         = (pEvent->data.l[1] == 1 ? FocusIn : FocusOut);
            aEvent.serial       = pEvent->serial;
            aEvent.send_event   = True;
            aEvent.display      = pEvent->display;
            aEvent.window       = pEvent->window;
            aEvent.mode         = NotifyNormal;
            aEvent.detail       = NotifyDetailNone;
            HandleFocusEvent( &aEvent );
        }
    }
	return 0;
}

void X11SalFrame::SaveYourselfDone( SalFrame* pSaveFrame )
{
    // session save was done, inform dtwm
    if( s_pSaveYourselfFrame && pSaveFrame )
    {
        ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
        const char* argv[2];
        argv[0] = "/bin/sh";
        argv[1] = const_cast<char*>(aExec.GetBuffer());
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] );
#endif
        XSetCommand( s_pSaveYourselfFrame->GetXDisplay(),
                     s_pSaveYourselfFrame->GetShellWindow(),
                     (char**)argv, 2 );
        if( pSaveFrame != s_pSaveYourselfFrame )
        {
            // check if it still exists
            const X11SalFrame* pFrame = NULL;
            const std::list< SalFrame* >& rFrames = static_cast<X11SalFrame*>(pSaveFrame)->GetDisplay()->getFrames();
            std::list< SalFrame* >::const_iterator it = rFrames.begin();
            while( it != rFrames.end() )
            {
                pFrame = static_cast< const X11SalFrame* >(*it);
                if( pFrame == pSaveFrame )
                    break;
                ++it; 
            }
            if( pFrame == pSaveFrame )
            {
                const WMAdaptor& rWMAdaptor( *pFrame->pDisplay_->getWMAdaptor() );
                XChangeProperty( pFrame->GetXDisplay(),
                                 pFrame->GetShellWindow(),
                                 rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 );
            }
        }
        s_pSaveYourselfFrame->ShutDown();
    }
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

extern "C"
{
Bool call_checkKeyReleaseForRepeat( Display* pDisplay, XEvent* pCheck, XPointer pX11SalFrame )
{
    return X11SalFrame::checkKeyReleaseForRepeat( pDisplay, pCheck, pX11SalFrame );
}
}

Bool X11SalFrame::checkKeyReleaseForRepeat( Display*, XEvent* pCheck, XPointer pX11SalFrame )
{
	X11SalFrame* pThis = (X11SalFrame*)pX11SalFrame;
	return
		pCheck->type			== XLIB_KeyPress &&
		pCheck->xkey.state		== pThis->nKeyState_ &&
		pCheck->xkey.keycode	== pThis->nKeyCode_ &&
		pCheck->xkey.time		== pThis->nReleaseTime_  ? True : False;
}

long X11SalFrame::Dispatch( XEvent *pEvent )
{
	long nRet = 0;

	if( -1 == nCaptured_ )
	{
		CaptureMouse( sal_True );
#ifdef DBG_UTIL
		if( -1 != nCaptured_ )
			pDisplay_->PrintEvent( "Captured", pEvent );
#endif
	}

	if( pEvent->xany.window == GetShellWindow() || pEvent->xany.window == GetWindow() )
	{
		switch( pEvent->type )
		{
			case XLIB_KeyPress:
				nKeyCode_	= pEvent->xkey.keycode;
				nKeyState_	= pEvent->xkey.state;
				nRet		= HandleKeyEvent( &pEvent->xkey );
				break;

			case KeyRelease:
				if( -1 == nCompose_ )
				{
					nReleaseTime_ = pEvent->xkey.time;
					XEvent aEvent;
					if( XCheckIfEvent( pEvent->xkey.display, &aEvent, call_checkKeyReleaseForRepeat, (XPointer)this ) )
						XPutBackEvent( pEvent->xkey.display, &aEvent );
					else
						nRet		= HandleKeyEvent( &pEvent->xkey );
				}
			break;

			case ButtonPress:
				// #74406# if we loose the focus in presentation mode
				// there are good chances that we never get it back
				// since the WM ignores us
 				if( IsOverrideRedirect() )
 				{
 					XSetInputFocus( GetXDisplay(), GetShellWindow(),
 							RevertToNone, CurrentTime );
 				}

			case ButtonRelease:
			case MotionNotify:
			case EnterNotify:
			case LeaveNotify:
				nRet = HandleMouseEvent( pEvent );
				break;

			case FocusIn:
			case FocusOut:
				nRet = HandleFocusEvent( &pEvent->xfocus );
				break;

			case Expose:
			case GraphicsExpose:
				nRet = HandleExposeEvent( pEvent );
				break;

			case MapNotify:
				if( pEvent->xmap.window == GetShellWindow() )
				{
                    if( nShowState_ == SHOWSTATE_HIDDEN )
                    {
                        /*
                         *  #95097# workaround for (at least) KWin 2.2.2
                         *  which will map windows that were once transient
                         *  even if they are withdrawn when the respective
                         *  document is mapped.
                         */
                        if( ! (nStyle_ & SAL_FRAME_STYLE_PLUG) )
                            XUnmapWindow( GetXDisplay(), GetShellWindow() );
                        break;
                    }
					bMapped_   = sal_True;
					bViewable_ = sal_True;
					nRet = sal_True;
					if ( mpInputContext != NULL )
						mpInputContext->Map( this );
                    CallCallback( SALEVENT_RESIZE, NULL );
                    if( pDisplay_->GetServerVendor() == vendor_hummingbird )
                    {
                        /*
                         *  With Exceed sometimes there does not seem to be
                         *  an Expose after the MapNotify.
                         *  so start a delayed paint here
                         */
                        maPaintRegion.Union( Rectangle( Point( 0, 0 ), Size( maGeometry.nWidth, maGeometry.nHeight ) ) );
                        XEvent aEvent;
                        aEvent.xexpose.type		= Expose;
                        aEvent.xexpose.display	= pDisplay_->GetDisplay();
                        aEvent.xexpose.x		= 0;
                        aEvent.xexpose.y		= 0;
                        aEvent.xexpose.width	= maGeometry.nWidth;
                        aEvent.xexpose.height	= maGeometry.nHeight;
                        aEvent.xexpose.count	= 0;
                        XSendEvent( pDisplay_->GetDisplay(),
                                    GetWindow(),
                                    True,
                                    ExposureMask,
                                    &aEvent );
                    }

                    bool bSetFocus = m_bSetFocusOnMap;
                    /*  #99570# another workaround for sawfish: if a transient window for the same parent is shown
                     *  sawfish does not set the focus to it. Applies only for click to focus mode.
                     */
                    if( ! (nStyle_ & SAL_FRAME_STYLE_FLOAT ) && mbInShow && GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Sawfish" ) )
                    {
                        // #101775# don't set the focus into the IME status window
                        // since this will lead to a parent loose-focus, close status,
                        // reget focus, open status, .... flicker loop
                        if ( (I18NStatus::get().getStatusFrame() != this) )
                            bSetFocus = true;
                    }

                    /*
                     *  sometimes a message box/dialogue is brought up when a frame is not mapped
                     *  the corresponding TRANSIENT_FOR hint is then set to the root window
                     *  so that the dialogue shows in all cases. Correct it here if the
                     *  frame is shown afterwards.
                     */
                    if( ! IsChildWindow()
                        && ! IsOverrideRedirect()
                        && ! IsFloatGrabWindow()
                        )
                    {
                        for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
                             it != maChildren.end(); ++it )
                        {
                            if( (*it)->mbTransientForRoot )
                                pDisplay_->getWMAdaptor()->changeReferenceFrame( *it, this );
                        }
                    }

                    if( hPresentationWindow != None && GetShellWindow() == hPresentationWindow )
                        XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent, CurrentTime );
                    /*  For unknown reasons Dtwm does respect the input_hint
                     *  set to False, but not when mapping the window. So
                     *  emulate the correct behaviour and set the focus back
                     *  to where it most probably should have been.
                     */
                    if( (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) &&
                        mpParent &&
                        GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Dtwm" )
                        )
                    {
                        XSetInputFocus( GetXDisplay(),
                                        mpParent->GetShellWindow(),
                                        RevertToParent,
                                        CurrentTime );
                        bSetFocus = false;
                    }
                    
                    if( bSetFocus )
                    {
                        XSetInputFocus( GetXDisplay(),
                                        GetShellWindow(),
                                        RevertToParent,
                                        CurrentTime );
                    }
                    

                    RestackChildren();
                    mbInShow = sal_False;
                    m_bSetFocusOnMap = false;
				}
				break;

			case UnmapNotify:
				if( pEvent->xunmap.window == GetShellWindow() )
				{
					bMapped_   = sal_False;
					bViewable_ = sal_False;
					nRet = sal_True;
					if ( mpInputContext != NULL )
						mpInputContext->Unmap( this );
					CallCallback( SALEVENT_RESIZE, NULL );
				}
				break;

			case ConfigureNotify:
				if( pEvent->xconfigure.window == GetShellWindow()
                    || pEvent->xconfigure.window == GetWindow() )
					nRet = HandleSizeEvent( &pEvent->xconfigure );
				break;

			case VisibilityNotify:
				nVisibility_ = pEvent->xvisibility.state;
				nRet = sal_True;
                if( bAlwaysOnTop_
                    && bMapped_
                    && ! GetDisplay()->getWMAdaptor()->isAlwaysOnTopOK()
                    && nVisibility_ != VisibilityUnobscured )
                    maAlwaysOnTopRaiseTimer.Start();
            break;

			case ReparentNotify:
				nRet = HandleReparentEvent( &pEvent->xreparent );
				break;

			case MappingNotify:
				if( MappingPointer != pEvent->xmapping.request )
					nRet = CallCallback( SALEVENT_KEYBOARDCHANGED, 0 );
				break;

			case ColormapNotify:
				nRet = HandleColormapEvent( &pEvent->xcolormap );
				break;

			case PropertyNotify:
			{
				if( pEvent->xproperty.atom == pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_STATE ) )
					nRet = HandleStateEvent( &pEvent->xproperty );
				else
					nRet = pDisplay_->getWMAdaptor()->handlePropertyNotify( this, &pEvent->xproperty );
				break;
			}

			case ClientMessage:
				nRet = HandleClientMessage( &pEvent->xclient );
				break;
		}
	}
	else
	{
		switch( pEvent->type )
		{
 			case FocusIn:
 			case FocusOut:
                if( ( nStyle_ & SAL_FRAME_STYLE_PLUG )
                    && ( pEvent->xfocus.window == GetShellWindow()
                         || pEvent->xfocus.window == GetForeignParent() )
                    )
                {
                    nRet = HandleFocusEvent( &pEvent->xfocus );
                }
 				break;

			case ConfigureNotify:
				if( pEvent->xconfigure.window == GetForeignParent() ||
					pEvent->xconfigure.window == GetShellWindow() )
					nRet = HandleSizeEvent( &pEvent->xconfigure );

				if( pEvent->xconfigure.window == GetStackingWindow() )
                    nRet = HandleSizeEvent( &pEvent->xconfigure );

				RestackChildren();
				break;
		}
	}

	return nRet;
}

void X11SalFrame::ResetClipRegion()
{
    delete [] m_pClipRectangles;
    m_pClipRectangles = NULL;
    m_nCurClipRect = m_nMaxClipRect = 0;
    
	const int	dest_kind	= ShapeBounding;
	const int	op			= ShapeSet;
	const int	ordering	= YSorted;

	XWindowAttributes win_attrib;
	XRectangle		  win_size;

	XLIB_Window aShapeWindow = mhShellWindow;

	XGetWindowAttributes ( GetDisplay()->GetDisplay(),
						   aShapeWindow,
						   &win_attrib );

	win_size.x		= 0;
	win_size.y		= 0;
	win_size.width	= win_attrib.width;
	win_size.height = win_attrib.height;

	XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
							  aShapeWindow,
							  dest_kind,
							  0, 0, 			// x_off, y_off
							  &win_size,		// list of rectangles
							  1,				// number of rectangles
							  op, ordering );
}

void X11SalFrame::BeginSetClipRegion( sal_uLong nRects )
{
    if( m_pClipRectangles )
        delete [] m_pClipRectangles;
    if( nRects )
        m_pClipRectangles = new XRectangle[nRects];
    else
        m_pClipRectangles = NULL;
    m_nMaxClipRect = static_cast<int>(nRects);
    m_nCurClipRect = 0;
}

void X11SalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
{
    if( m_pClipRectangles && m_nCurClipRect < m_nMaxClipRect )
    {
        m_pClipRectangles[m_nCurClipRect].x      = nX;
        m_pClipRectangles[m_nCurClipRect].y      = nY;
        m_pClipRectangles[m_nCurClipRect].width  = nWidth;
        m_pClipRectangles[m_nCurClipRect].height = nHeight;
        m_nCurClipRect++;
    }
}

void X11SalFrame::EndSetClipRegion()
{
	const int	dest_kind	= ShapeBounding;
	const int	ordering	= YSorted;
	const int	op = ShapeSet;

	XLIB_Window aShapeWindow = mhShellWindow;
	XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
							  aShapeWindow,
							  dest_kind,
							  0, 0, // x_off, y_off
							  m_pClipRectangles,
							  m_nCurClipRect,
							  op, ordering );

}

