diff options
-rw-r--r-- | vcl/unx/inc/saldisp.hxx | 52 | ||||
-rw-r--r-- | vcl/unx/inc/salframe.h | 16 | ||||
-rw-r--r-- | vcl/unx/inc/wmadaptor.hxx | 190 | ||||
-rw-r--r-- | vcl/unx/source/app/makefile.mk | 7 | ||||
-rw-r--r-- | vcl/unx/source/app/saldisp.cxx | 30 | ||||
-rw-r--r-- | vcl/unx/source/app/wmadaptor.cxx | 751 | ||||
-rw-r--r-- | vcl/unx/source/window/salframe.cxx | 217 |
7 files changed, 1056 insertions, 207 deletions
diff --git a/vcl/unx/inc/saldisp.hxx b/vcl/unx/inc/saldisp.hxx index 21579f5148f8..8a48bee14cb4 100644 --- a/vcl/unx/inc/saldisp.hxx +++ b/vcl/unx/inc/saldisp.hxx @@ -2,9 +2,9 @@ * * $RCSfile: saldisp.hxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: pl $ $Date: 2001-07-26 15:45:26 $ + * last change: $Author: pl $ $Date: 2001-08-08 19:09:03 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -65,7 +65,6 @@ // -=-= exports =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= struct SalAppXResource; class SalDisplay; -class SalICCCM; class SalColormap; class SalColormapRef; class SalTrueColorConverter; @@ -95,6 +94,8 @@ class SalFrameData; class ColorMask; class SalSystemData; +namespace vcl_sal { class WMAdaptor; } + #ifndef _XSHM_H_ struct XShmSegmentInfo; #endif @@ -163,46 +164,6 @@ enum SalWM { olwm, // Open Look pmwm, // SCO otherwm }; -// -=-= SalICCCM =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -class SalICCCM -{ - STDAPI( SalICCCM ) - -public: - Atom aWM_Protocols_; // Window manager - Atom aWM_State_; - Atom aWM_DeleteWindow_; - Atom aWM_SaveYourself_; - Atom aWM_Command_; - - Atom aQuitEvent_; // client message events - Atom aUserEvent_; - #if !defined(__synchronous_extinput__) - Atom aExtTextEvent_; - #endif - - inline int IsQuitEvent( Atom a ) const - { return aQuitEvent_ == a; } - inline int IsUserEvent( Atom a ) const - { return aUserEvent_ == a; } - #if !defined(__synchronous_extinput__) - inline int IsExtTextEvent( Atom a ) const - { return aExtTextEvent_ == a; } - #endif - inline int IsWM_State( Atom a ) const - { return aWM_State_ == a; } - inline int IsWM_DeleteWindow( Atom a ) const - { return aWM_DeleteWindow_ == a; } - inline int IsWM_Protocols( Atom a ) const - { return aWM_Protocols_ == a; } - inline int IsWM_SaveYourself( Atom a ) const - { return aWM_SaveYourself_ == a; } - inline int IsWM_Command( Atom a ) const - { return aWM_Command_ == a; } - - SalICCCM( SalDisplay *pDisplay ); -}; - // -=-= SalRGB -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // MSB/Bigendian Sicht (SalColor == RGB, r=0xFF0000, g=0xFF00, b=0xFF) @@ -367,7 +328,6 @@ class SalDisplay SalSystemData *mpSalSystemData; // the one to get create and destroy notify events - SalICCCM *pICCCM_; // Atoms Display *pDisp_; // X Display Screen *pScreen_; // XDefaultScreenOfDisplay int nScreen_; // XDefaultScreen @@ -429,6 +389,8 @@ class SalDisplay SalImageList SharedImages_; + ::vcl_sal::WMAdaptor* m_pWMAdaptor; + void DestroyFontCache(); long Dispatch( XEvent *pEvent ); @@ -509,7 +471,6 @@ public: inline void SetServerVendor() { meServerVendor = sal_GetServerVendor(pDisp_); } inline BOOL IsDisplay() const { return !!pXLib_; } - inline SalICCCM &GetICCCM() const { return *pICCCM_; } inline GC GetMonoGC() const { return pMonoGC_; } inline GC GetCopyGC() const { return pCopyGC_; } inline GC GetAndInvertedGC() const { return pAndInvertedGC_; } @@ -540,6 +501,7 @@ public: inline void SetKbdExtension(SalI18N_KeyboardExtension *pKbdExtension) { mpKbdExtension = pKbdExtension; } const char* GetKeyboardName( BOOL bRefresh = FALSE ); + ::vcl_sal::WMAdaptor* getWMAdaptor() const { return m_pWMAdaptor; } }; // -=-= inlines =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/vcl/unx/inc/salframe.h b/vcl/unx/inc/salframe.h index 5bc78e9e5779..3bad98b19484 100644 --- a/vcl/unx/inc/salframe.h +++ b/vcl/unx/inc/salframe.h @@ -2,9 +2,9 @@ * * $RCSfile: salframe.h,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: cp $ $Date: 2001-07-12 09:11:28 $ + * last change: $Author: pl $ $Date: 2001-08-08 19:09:03 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -96,6 +96,7 @@ class SalGraphics; class SalFrame; class SalColormap; class SalI18N_InputContext; +namespace vcl_sal { class WMAdaptor; } class SalFrameDelData { @@ -119,6 +120,7 @@ DECLARE_LIST( SalFrameList, SalFrame *); class SalFrameData { friend class SalFrame; + friend class ::vcl_sal::WMAdaptor; friend SalFrame* SalInstance::CreateFrame( SalFrame*, ULONG ); friend SalFrame* SalInstance::CreateChildFrame( SystemParentData*, ULONG ); @@ -179,6 +181,15 @@ class SalFrameData Rectangle maResizeBuffer; Rectangle maPaintRegion; + // data for WMAdaptor + int meWindowType; + int mnDecorationFlags; + bool mbMaximizedVert; + bool mbMaximizedHorz; + + // icon id + int mnIconID; + SystemChildData maSystemChildData; SalI18N_InputContext *mpInputContext; @@ -196,7 +207,6 @@ class SalFrameData void Minimize(); void Maximize(); void Restore(); - void ShowFullScreen( BOOL bFullScreen ); void RepositionFloatChildren(); void RepositionChildren(); diff --git a/vcl/unx/inc/wmadaptor.hxx b/vcl/unx/inc/wmadaptor.hxx new file mode 100644 index 000000000000..0e86b789de8b --- /dev/null +++ b/vcl/unx/inc/wmadaptor.hxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * $RCSfile: wmadaptor.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-08-08 19:09:03 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2001 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _VCL_WMADAPTOR_HXX_ +#define _VCL_WMADAPTOR_HXX_ + +#ifndef _TL_STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _SV_GEN_HXX +#include <tools/gen.hxx> +#endif +#ifndef _PREX_H +#include <prex.h> +#include <X11/Xlib.h> +#include <postx.h> +#endif +#include <vector> + +class SalDisplay; +class SalFrame; + +namespace vcl_sal { + +class WMAdaptor +{ +public: + enum WMAtom { + UTF8_STRING, + NET_SUPPORTED, + NET_SUPPORTING_WM_CHECK, + NET_WM_NAME, + NET_WM_ICON_NAME, + NET_WM_STATE, + NET_WM_STATE_MAXIMIZED_HORZ, + NET_WM_STATE_MAXIMIZED_VERT, + NET_WM_STATE_MODAL, + NET_WM_STATE_SHADED, + NET_WM_STATE_SKIP_PAGER, + NET_WM_STATE_SKIP_TASKBAR, + NET_WM_STATE_STAYS_ON_TOP, + NET_WM_STATE_STICKY, + NET_WM_WINDOW_TYPE, + NET_WM_WINDOW_TYPE_DESKTOP, + NET_WM_WINDOW_TYPE_DIALOG, + NET_WM_WINDOW_TYPE_DOCK, + NET_WM_WINDOW_TYPE_MENU, + NET_WM_WINDOW_TYPE_NORMAL, + NET_WM_WINDOW_TYPE_TOOLBAR, + NET_NUMBER_OF_DESKTOPS, + NET_WORKAREA, + WM_STATE, + MOTIF_WM_HINTS, + WM_PROTOCOLS, + WM_DELETE_WINDOW, + WM_SAVE_YOURSELF, + WM_COMMAND, + SAL_QUITEVENT, + SAL_USEREVENT, + SAL_EXTTEXTEVENT, + NetAtomMax + }; + + /* + * flags for frame decoration + */ + static const int decoration_Title = 0x00000001; + static const int decoration_Border = 0x00000002; + static const int decoration_Resize = 0x00000004; + static const int decoration_MinimizeBtn = 0x00000008; + static const int decoration_MaximizeBtn = 0x00000010; + static const int decoration_CloseBtn = 0x00000020; + static const int decoration_All = 0x10000000; + + /* + * window type + */ + enum WMWindowType + { + windowType_Normal, + windowType_ModalDialogue, + windowType_ModelessDialogue, + windowType_OverrideRedirect + }; + +private: + SalDisplay* m_pSalDisplay; // Display to use + Display* m_pDisplay; // X Display of SalDisplay + bool m_bNetWM; // true: _NET supporting WM is available + String m_aWMName; + Atom m_aWMAtoms[ NetAtomMax]; + int m_nDesktops; + bool m_bEqualWorkAreas; + ::std::vector< Rectangle > + m_aWMWorkAreas; + + void setNetWMState( SalFrame* pFrame ) const; +public: + WMAdaptor( SalDisplay * ); + ~WMAdaptor(); + + + /* + * sets WM_NAME and _NET_WM_NAME + */ + void setWMName( SalFrame* pFrame, const String& rWMName ) const; + + /* + * maximizes frame, if _NET is present and _NET_WM_STATE supported, + * then this is done via request to WM + * maximization can be toggled in either direction + * to get the original position and size + * use maximizeFrame( pFrame, false, false ) + */ + void maximizeFrame( SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const; + + /* + * set hints what decoration is needed; + * must be called before showing the frame + */ + void setFrameTypeAndDecoration( SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, SalFrame* pTransientFrame = NULL ) const; + + /* + * gets a WM atom + */ + Atom getAtom( WMAtom eAtom ) const + { return m_aWMAtoms[ eAtom ]; } +}; + +} // namespace + +#endif diff --git a/vcl/unx/source/app/makefile.mk b/vcl/unx/source/app/makefile.mk index 558954bb444c..371c3595a25e 100644 --- a/vcl/unx/source/app/makefile.mk +++ b/vcl/unx/source/app/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.4 $ +# $Revision: 1.5 $ # -# last change: $Author: rt $ $Date: 2001-05-18 14:07:13 $ +# last change: $Author: pl $ $Date: 2001-08-08 19:09:04 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -107,7 +107,8 @@ SLOFILES=\ $(SLO)$/soicon.obj \ $(SLO)$/sm.obj \ $(SLO)$/stacktrace.obj \ - $(SLO)$/keysymnames.obj + $(SLO)$/keysymnames.obj \ + $(SLO)$/wmadaptor.obj .IF "$(OS)$(CPU)" == "SOLARISS" .IF "$(COM)"!="GCC" diff --git a/vcl/unx/source/app/saldisp.cxx b/vcl/unx/source/app/saldisp.cxx index 0255f8d05b5c..d02b4c046269 100644 --- a/vcl/unx/source/app/saldisp.cxx +++ b/vcl/unx/source/app/saldisp.cxx @@ -2,9 +2,9 @@ * * $RCSfile: saldisp.cxx,v $ * - * $Revision: 1.21 $ + * $Revision: 1.22 $ * - * last change: $Author: pl $ $Date: 2001-07-26 15:45:26 $ + * last change: $Author: pl $ $Date: 2001-08-08 19:09:04 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -278,6 +278,9 @@ extern "C" { int gethostname(char*,int); } #ifndef _VCL_SM_HXX #include <sm.hxx> #endif +#ifndef _VCL_WMADAPTOR_HXX_ +#include <wmadaptor.hxx> +#endif #include <osl/socket.h> #include <rtl/ustring> @@ -682,7 +685,8 @@ BOOL SalDisplay::BestVisual( Display *pDisplay, // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SalDisplay::SalDisplay( Widget w ) : - mpFallbackFactory ( NULL ) + mpFallbackFactory ( NULL ), + m_pWMAdaptor( NULL ) { SalData *pSalData = GetSalData(); @@ -724,7 +728,8 @@ SalDisplay::SalDisplay( Widget w ) : SalDisplay::SalDisplay( Display *display, Visual *pVisual, Colormap aColMap ) : pDisp_( display ), - mpFallbackFactory ( NULL ) + mpFallbackFactory ( NULL ), + m_pWMAdaptor( NULL ) { SalData *pSalData = GetSalData(); XVisualInfo aXVI; @@ -757,6 +762,7 @@ SalDisplay::~SalDisplay( ) { SalData *pSalData = GetSalData(); + delete m_pWMAdaptor; SalBitmap::ImplDestroyCache(); DestroyFontCache(); @@ -811,13 +817,11 @@ SalDisplay::~SalDisplay( ) // free colormap before modifying pVisual_ xColor_.Clear(); - delete pICCCM_; delete pVisual_; if( pRootVisual_ != pVisual_ ) delete pRootVisual_; - pICCCM_ = (SalICCCM*)ILLEGAL_POINTER; pVisual_ = (SalVisual*)ILLEGAL_POINTER; pRootVisual_ = (SalVisual*)ILLEGAL_POINTER; @@ -891,7 +895,6 @@ void SalDisplay::Init( Colormap hXColmap, const XVisualInfo* pXVI ) (YieldFunc) DisplayQueue, (YieldFunc) DisplayYield ); - pICCCM_ = new SalICCCM( this ); pScreen_ = ScreenOfDisplay( pDisp_, nScreen_ ); hRootWindow_ = RootWindowOfScreen( pScreen_ ); @@ -1154,7 +1157,6 @@ void SalDisplay::Init( Colormap hXColmap, const XVisualInfo* pXVI ) } else { - pICCCM_ = NULL; pScreen_ = NULL; hRootWindow_ = None; pRootVisual_ = pVisual_; @@ -1325,6 +1327,7 @@ void SalDisplay::Init( Colormap hXColmap, const XVisualInfo* pXVI ) if( !XtWindow( hComposite_ ) ) XtRealizeWidget( hComposite_ ); } + m_pWMAdaptor = new ::vcl_sal::WMAdaptor( this ); #ifdef DBG_UTIL PrintInfo(); #endif @@ -3015,17 +3018,6 @@ void SalDisplay::PrintInfo() const } } -// -=-= SalICCCM -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -SalICCCM::SalICCCM( SalDisplay *pDisplay ) -{ - Display *display = pDisplay->GetDisplay(); - - for( int i = 0; i < capacityof( AtomStrings ); i++ ) - (&aWM_Protocols_)[i] = XInternAtom( display, AtomStrings[i], False ); -} - // -=-= SalVisual -=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= SalVisual::SalVisual( const XVisualInfo* pXVI ) diff --git a/vcl/unx/source/app/wmadaptor.cxx b/vcl/unx/source/app/wmadaptor.cxx new file mode 100644 index 000000000000..d7a3329a62ba --- /dev/null +++ b/vcl/unx/source/app/wmadaptor.cxx @@ -0,0 +1,751 @@ +/************************************************************************* + * + * $RCSfile: wmadaptor.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: pl $ $Date: 2001-08-08 19:09:04 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2001 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <stdlib.h> +#ifdef SOLARIS +#include <alloca.h> +#endif + +#ifndef _VCL_WMADAPTOR_HXX_ +#include <wmadaptor.hxx> +#endif +#ifndef _SV_SALDISP_HXX +#include <saldisp.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _OSL_THREAD_H_ +#include <osl/thread.h> +#endif + +#include <prex.h> +#include <X11/X.h> +#include <postx.h> + +#ifdef DEBUG +#include <stdio.h> +#endif + +using namespace vcl_sal; + +struct WMAdaptorProtocol +{ + const char* pProtocol; + int nProtocol; +}; + + +/* + * table must be sorted ascending in strings + * since it is use with bsearch + */ +static const WMAdaptorProtocol aProtocolTab[] = +{ + { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME }, + { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS }, + { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE }, + { "_NET_WM_STATE_MAXIMIZED_HORIZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ }, // common bug in e.g. older kwin and sawfish implementations + { "_NET_WM_STATE_MAXIMIZED_HORZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ }, + { "_NET_WM_STATE_MAXIMIZED_VERT", WMAdaptor::NET_WM_STATE_MAXIMIZED_VERT }, + { "_NET_WM_STATE_MODAL", WMAdaptor::NET_WM_STATE_MODAL }, + { "_NET_WM_STATE_SHADED", WMAdaptor::NET_WM_STATE_SHADED }, + { "_NET_WM_STATE_SKIP_PAGER", WMAdaptor::NET_WM_STATE_SKIP_PAGER }, + { "_NET_WM_STATE_SKIP_TASKBAR", WMAdaptor::NET_WM_STATE_SKIP_TASKBAR }, + { "_NET_WM_STATE_STAYS_ON_TOP", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP }, + { "_NET_WM_STATE_STICKY", WMAdaptor::NET_WM_STATE_STICKY }, + { "_NET_WM_WINDOW_TYPE", WMAdaptor::NET_WM_WINDOW_TYPE }, + { "_NET_WM_WINDOW_TYPE_DESKTOP", WMAdaptor::NET_WM_WINDOW_TYPE_DESKTOP }, + { "_NET_WM_WINDOW_TYPE_DIALOG", WMAdaptor::NET_WM_WINDOW_TYPE_DIALOG }, + { "_NET_WM_WINDOW_TYPE_DOCK", WMAdaptor::NET_WM_WINDOW_TYPE_DOCK }, + { "_NET_WM_WINDOW_TYPE_MENU", WMAdaptor::NET_WM_WINDOW_TYPE_MENU }, + { "_NET_WM_WINDOW_TYPE_NORMAL", WMAdaptor::NET_WM_WINDOW_TYPE_NORMAL }, + { "_NET_WM_WINDOW_TYPE_TOOLBAR", WMAdaptor::NET_WM_WINDOW_TYPE_TOOLBAR }, + { "_NET_WORKAREA", WMAdaptor::NET_WORKAREA } +}; + +/* + * table containing atoms to get anyway + */ + +static const WMAdaptorProtocol aAtomTab[] = +{ + { "WM_STATE", WMAdaptor::WM_STATE }, + { "_MOTIF_WM_HINTS", WMAdaptor::MOTIF_WM_HINTS }, + { "WM_PROTOCOLS", WMAdaptor::WM_PROTOCOLS }, + { "WM_DELETE_WINDOW", WMAdaptor::WM_DELETE_WINDOW }, + { "WM_SAVE_YOURSELF", WMAdaptor::WM_SAVE_YOURSELF }, + { "WM_COMMAND", WMAdaptor::WM_COMMAND }, + { "SAL_QUITEVENT", WMAdaptor::SAL_QUITEVENT }, + { "SAL_USEREVENT", WMAdaptor::SAL_USEREVENT }, + { "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT } +}; + +extern "C" static int compareProtocol( const void* pLeft, const void* pRight ) +{ + return strcmp( ((const WMAdaptorProtocol*)pLeft)->pProtocol, ((const WMAdaptorProtocol*)pRight)->pProtocol ); +} + +/* + * WMAdaptor constructor + */ + +WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) : + m_pSalDisplay( pDisplay ), + m_bNetWM( false ) +{ + Atom aRealType = None; + int nFormat = 8; + unsigned long nItems = 0; + unsigned long nBytesLeft = 0; + unsigned char* pProperty = NULL; + + // default desktops + m_nDesktops = 1; + m_aWMWorkAreas = ::std::vector< Rectangle > + ( 1, Rectangle( Point( 0, 0 ), m_pSalDisplay->GetScreenSize() ) ); + m_bEqualWorkAreas = true; + + memset( m_aWMAtoms, 0, sizeof( m_aWMAtoms ) ); + m_pDisplay = m_pSalDisplay->GetDisplay(); + + // get basic atoms + for( int i = 0; i < sizeof( aAtomTab )/sizeof( aAtomTab[0] ); i++ ) + m_aWMAtoms[ aAtomTab[i].nProtocol ] = XInternAtom( m_pDisplay, aAtomTab[i].pProtocol, False ); + + // check for NetWM + m_aWMAtoms[ NET_SUPPORTED ] = XInternAtom( m_pDisplay, "_NET_SUPPORTED", True ); + m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ] = XInternAtom( m_pDisplay, "_NET_SUPPORTING_WM_CHECK", True ); + m_aWMAtoms[ NET_WM_NAME ] = XInternAtom( m_pDisplay, "_NET_WM_NAME", True ); + if( m_aWMAtoms[ NET_SUPPORTED ] && m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ] && m_aWMAtoms[ NET_WM_NAME ] ) + { + XLIB_Window aWMChild = None; + if( XGetWindowProperty( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ], + 0, 1, + False, + XA_WINDOW, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && aRealType == XA_WINDOW + && nFormat == 32 + && nItems != 0 + ) + { + aWMChild = *(XLIB_Window*)pProperty; + XFree( pProperty ); + pProperty = NULL; + XLIB_Window aCheckWindow = None; + BOOL bIgnore = m_pSalDisplay->GetXLib()->GetIgnoreXErrors(); + m_pSalDisplay->GetXLib()->SetIgnoreXErrors( TRUE ); + if( XGetWindowProperty( m_pDisplay, + aWMChild, + m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ], + 0, 1, + False, + XA_WINDOW, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && aRealType == XA_WINDOW + && nFormat == 32 + && nItems != 0 + && ! m_pSalDisplay->GetXLib()->WasXError() + ) + { + aCheckWindow = *(XLIB_Window*)pProperty; + XFree( pProperty ); + pProperty = NULL; + if( aCheckWindow == aWMChild ) + { + m_bNetWM = true; + // get name of WM + m_aWMAtoms[ UTF8_STRING ] = XInternAtom( m_pDisplay, "UTF8_STRING", False ); + if( XGetWindowProperty( m_pDisplay, + aWMChild, + m_aWMAtoms[ NET_WM_NAME ], + 0, 256, + False, + m_aWMAtoms[ UTF8_STRING ], + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && aRealType == m_aWMAtoms[ UTF8_STRING ] + && nFormat == 8 + && nItems != 0 + ) + { + m_aWMName = String( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 ); + XFree( pProperty ); + pProperty = NULL; + } + } + } + m_pSalDisplay->GetXLib()->SetIgnoreXErrors( bIgnore ); + } + } +#ifdef DEBUG + fprintf( stderr, "WM %s NET_WM\n", m_bNetWM ? "supports" : "does not support" ); + if( m_bNetWM ) + { + fprintf( stderr, "Window Manager's name is \"%s\"\n", + ByteString( m_aWMName, RTL_TEXTENCODING_ISO_8859_1 ).GetBuffer() ); + } +#endif + if( m_bNetWM + && XGetWindowProperty( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + m_aWMAtoms[ NET_SUPPORTED ], + 0, 0, + False, + XA_ATOM, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + && aRealType == XA_ATOM + && nFormat == 32 + ) + { + if( pProperty ) + { + XFree( pProperty ); + pProperty = NULL; + } + // collect supported protocols + if( XGetWindowProperty( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + m_aWMAtoms[ NET_SUPPORTED ], + 0, nBytesLeft/4, + False, + XA_ATOM, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 ) + { + Atom* pAtoms = (Atom*)pProperty; + char** pAtomNames = (char**)alloca( sizeof(char*)*nItems ); + if( XGetAtomNames( m_pDisplay, pAtoms, nItems, pAtomNames ) ) + { +#ifdef DEBUG + fprintf( stderr, "supported protocols:\n" ); +#endif + for( int i = 0; i < nItems; i++ ) + { + int nProtocol = -1; + WMAdaptorProtocol aSearch; + aSearch.pProtocol = pAtomNames[i]; + WMAdaptorProtocol* pMatch = (WMAdaptorProtocol*) + bsearch( &aSearch, + aProtocolTab, + sizeof( aProtocolTab )/sizeof( aProtocolTab[0] ), + sizeof( struct WMAdaptorProtocol ), + compareProtocol ); + if( pMatch ) + { + nProtocol = pMatch->nProtocol; + m_aWMAtoms[ nProtocol ] = pAtoms[ i ]; + } +#ifdef DEBUG + fprintf( stderr, " %s%s\n", pAtomNames[i], nProtocol != -1 ? "" : " (unsupported)" ); +#endif + + XFree( pAtomNames[i] ); + } + } + XFree( pProperty ); + pProperty = NULL; + } + + // get number of desktops + if( m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ] + && XGetWindowProperty( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ], + 0, 1, + False, + XA_CARDINAL, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty ) == 0 + ) + { + m_nDesktops = *(sal_uInt32*)pProperty; + XFree( pProperty ); + pProperty = NULL; + // get work areas + if( m_aWMAtoms[ NET_WORKAREA ] + && XGetWindowProperty( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + m_aWMAtoms[ NET_WORKAREA ], + 0, 4*m_nDesktops, + False, + XA_CARDINAL, + &aRealType, + &nFormat, + &nItems, + &nBytesLeft, + &pProperty + ) == 0 + && nItems == 4*m_nDesktops + ) + { + sal_uInt32* pValues = (sal_uInt32*)pProperty; + for( int i = 0; i < m_nDesktops; i++ ) + { + Rectangle aWorkArea( + Point( pValues[4*i], + pValues[4*i+1] ), + Size( pValues[4*i+2], + pValues[4*i+3] ) + ); + m_aWMWorkAreas[i] = aWorkArea; + if( aWorkArea != m_aWMWorkAreas[0] ) + m_bEqualWorkAreas = false; +#ifdef DEBUG + fprintf( stderr, "workarea %d: %dx%d+%d+%d\n", + i, + m_aWMWorkAreas[i].GetWidth(), + m_aWMWorkAreas[i].GetHeight(), + m_aWMWorkAreas[i].Left(), + m_aWMWorkAreas[i].Top() ); +#endif + } + } + else + { +#ifdef DEBUG + fprintf( stderr, "%d workareas for %d desktops !\n", nItems/4, m_nDesktops ); +#endif + if( pProperty ) + { + XFree(pProperty); + pProperty = NULL; + } + } + } + + } +} + +/* + * WMAdaptor destructor + */ + +WMAdaptor::~WMAdaptor() +{ +} + +/* + * WMAdaptor::setWMName + * sets WM_NAME + * _NET_WM_NAME + * WM_ICON_NAME + * _NET_WM_ICON_NAME + */ +void WMAdaptor::setWMName( SalFrame* pFrame, const String& rWMName ) const +{ + ByteString aTitle( rWMName, osl_getThreadTextEncoding() ); + + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + XA_WM_NAME, + XA_STRING, + 8, + PropModeReplace, + (unsigned char*)aTitle.GetBuffer(), + aTitle.Len() ); + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + XA_WM_ICON_NAME, + XA_STRING, + 8, + PropModeReplace, + (unsigned char*)aTitle.GetBuffer(), + aTitle.Len() ); + if( m_bNetWM ) + { + aTitle = ByteString( rWMName, RTL_TEXTENCODING_UTF8 ); + if( m_aWMAtoms[ NET_WM_NAME ] ) + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_aWMAtoms[ NET_WM_NAME ], + m_aWMAtoms[ UTF8_STRING ], + 8, + PropModeReplace, + (unsigned char*)aTitle.GetBuffer(), + aTitle.Len()+1 ); + if( m_aWMAtoms[ NET_WM_ICON_NAME ] ) + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_aWMAtoms[ NET_WM_ICON_NAME ], + m_aWMAtoms[ UTF8_STRING ], + 8, + PropModeReplace, + (unsigned char*)aTitle.GetBuffer(), + aTitle.Len()+1 ); + // The +1 copies the terminating null byte. Although + // the spec says, this should not be necessary + // at least the kwin implementation seems to depend + // on the null byte + } +} + +/* + * WMAdaptor::setNetWMState + * sets _NET_WM_STATE + */ +void WMAdaptor::setNetWMState( SalFrame* pFrame ) const +{ + if( m_bNetWM + && m_aWMAtoms[ NET_WM_STATE ] ) + { + Atom aStateAtoms[ 4 ]; + int nStateAtoms = 0; + + // set NET_WM_STATE_MODAL + if( m_aWMAtoms[ NET_WM_STATE_MODAL ] + && pFrame->maFrameData.meWindowType == windowType_ModalDialogue ) + { + aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MODAL ]; + aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ]; + } + if( pFrame->maFrameData.mbMaximizedVert + && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] ) + aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ]; + if( pFrame->maFrameData.mbMaximizedHorz + && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] ) + aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ]; + if( nStateAtoms ) + { + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_aWMAtoms[ NET_WM_STATE ], + XA_ATOM, + 32, + PropModeReplace, + (unsigned char*)aStateAtoms, + nStateAtoms + ); + } + if( ! ( pFrame->maFrameData.nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) ) + { + // SetPosSize necessary to set width/height, min/max w/h + Rectangle aPosSize = m_aWMWorkAreas[0]; + /* + * if( ! m_bEqualWorkAreas ) + * get current desktop here + */ + pFrame->maFrameData.SetPosSize( aPosSize ); + } + } +} + +/* + * WMAdaptor::setFrameDecoration + * sets _MOTIF_WM_HINTS + * _NET_WM_WINDOW_TYPE + * _NET_WM_STATE + * WM_TRANSIENT_FOR + */ + +void WMAdaptor::setFrameTypeAndDecoration( SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, SalFrame* pReferenceFrame ) const +{ + pFrame->maFrameData.meWindowType = eType; + pFrame->maFrameData.mnDecorationFlags = nDecorationFlags; + + // first set mwm hints + struct _mwmhints { + unsigned long flags, func, deco; + long input_mode; + unsigned long status; + } aHint; + + aHint.flags = 7; /* flags for functions, decoration and input mode */ + aHint.deco = 0; + aHint.func = 1L << 2; + + // evaluate decoration flags + if( nDecorationFlags & decoration_All ) + aHint.deco = 1, aHint.func = 1; + else + { + if( nDecorationFlags & decoration_Title ) + aHint.deco |= 1L << 3; + if( nDecorationFlags & decoration_Border ) + aHint.deco |= 1L << 1; + if( nDecorationFlags & decoration_Resize ) + aHint.deco |= 1L << 2, aHint.func |= 1L << 1; + if( nDecorationFlags & decoration_MinimizeBtn ) + aHint.deco |= 1L << 5, aHint.func |= 1L << 3; + if( nDecorationFlags & decoration_MaximizeBtn ) + aHint.deco |= 1L << 6, aHint.func |= 1L << 4; + if( nDecorationFlags & decoration_CloseBtn ) + aHint.deco |= 1L << 4, aHint.func |= 1L << 5; + } + // evaluate window type + switch( eType ) + { + case windowType_ModalDialogue: + aHint.input_mode = 1; + break; + default: + aHint.input_mode = 0; + break; + } + + // set the hint + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_aWMAtoms[ MOTIF_WM_HINTS ], + m_aWMAtoms[ MOTIF_WM_HINTS ], + 32, + PropModeReplace, + (unsigned char*)&aHint, + 5 ); + + if( m_bNetWM ) + { + setNetWMState( pFrame ); + + // set NET_WM_WINDOW_TYPE + if( m_aWMAtoms[ NET_WM_WINDOW_TYPE ] ) + { + WMAtom eWMType; + switch( eType ) + { + case windowType_ModalDialogue: + eWMType = NET_WM_WINDOW_TYPE_DIALOG; + break; + default: + eWMType = NET_WM_WINDOW_TYPE_NORMAL; + break; + } + XChangeProperty( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_aWMAtoms[ NET_WM_WINDOW_TYPE ], + XA_ATOM, + 32, + PropModeReplace, + (unsigned char*)&m_aWMAtoms[ eWMType ], + 1 ); + } + if( eType == windowType_ModalDialogue && ! pReferenceFrame ) + XSetTransientForHint( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + m_pSalDisplay->GetRootWindow() ); + } + + // set transientFor hint + if( pReferenceFrame ) + XSetTransientForHint( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + pReferenceFrame->maFrameData.GetShellWindow() ); +} + +/* + * WMAdaptor::maximizeFrame + * changes _NET_WM_STATE by sending a client message + */ + +void WMAdaptor::maximizeFrame( SalFrame* pFrame, bool bHorizontal, bool bVertical ) const +{ + pFrame->maFrameData.mbMaximizedVert = bVertical; + pFrame->maFrameData.mbMaximizedHorz = bHorizontal; + + if( m_bNetWM + && m_aWMAtoms[ NET_WM_STATE ] + && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] + && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] + && ( pFrame->maFrameData.nStyle_ & ~SAL_FRAME_STYLE_DEFAULT ) + ) + { + if( pFrame->maFrameData.bMapped_ ) + { + // window already mapped, send WM a message + XEvent aEvent; + aEvent.type = ClientMessage; + aEvent.xclient.display = m_pDisplay; + aEvent.xclient.window = pFrame->maFrameData.GetShellWindow(); + aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ]; + aEvent.xclient.format = 32; + aEvent.xclient.data.l[0] = bHorizontal ? 1 : 0; + aEvent.xclient.data.l[1] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ]; + aEvent.xclient.data.l[2] = bHorizontal == bVertical ? m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] : 0; + aEvent.xclient.data.l[3] = 0; + aEvent.xclient.data.l[4] = 0; + XSendEvent( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &aEvent + ); + if( bHorizontal != bVertical ) + { + aEvent.xclient.data.l[0]= bVertical ? 1 : 0; + aEvent.xclient.data.l[1]= m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ]; + aEvent.xclient.data.l[2]= 0; + XSendEvent( m_pDisplay, + m_pSalDisplay->GetRootWindow(), + False, + SubstructureNotifyMask | SubstructureRedirectMask, + &aEvent + ); + } + } + else + { + // window not mapped yet, set _NET_WM_STATE directly + setNetWMState( pFrame ); + } + if( !bHorizontal && !bVertical ) + pFrame->maFrameData.aRestoreFullScreen_ = Rectangle(); + else if( pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ) + pFrame->maFrameData.aRestoreFullScreen_ = pFrame->maFrameData.aPosSize_; + } + else + { + // since the WM won't let us, do it the ugly way + if( bHorizontal || bVertical ) + { + const Size& aScreenSize( m_pSalDisplay->GetScreenSize() ); + Rectangle aTarget( Point( 0, 0 ), aScreenSize ); + if( ! bHorizontal ) + { + aTarget.SetSize( + Size( + pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ? + pFrame->maFrameData.aPosSize_.GetWidth() : + pFrame->maFrameData.aRestoreFullScreen_.GetWidth(), + aTarget.GetHeight() + ) + ); + aTarget.Left() = + pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ? + pFrame->maFrameData.aPosSize_.Left() : + pFrame->maFrameData.aRestoreFullScreen_.Left(); + } + else if( ! bVertical ) + { + aTarget.SetSize( + Size( + aTarget.GetWidth(), + pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ? + pFrame->maFrameData.aPosSize_.GetHeight() : + pFrame->maFrameData.aRestoreFullScreen_.GetHeight() + ) + ); + aTarget.Top() = + pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ? + pFrame->maFrameData.aPosSize_.Top() : + pFrame->maFrameData.aRestoreFullScreen_.Top(); + } + if( pFrame->maFrameData.aRestoreFullScreen_.IsEmpty() ) + pFrame->maFrameData.aRestoreFullScreen_ = pFrame->maFrameData.aPosSize_; + delete pFrame->maFrameData.pFreeGraphics_; + pFrame->maFrameData.pFreeGraphics_ = NULL; + + if( pFrame->maFrameData.bMapped_ ) + { + pFrame->Show( TRUE ); + XSetInputFocus( m_pDisplay, + pFrame->maFrameData.GetShellWindow(), + RevertToNone, + CurrentTime + ); + } + pFrame->maFrameData.SetPosSize( aTarget ); + pFrame->maFrameData.nWidth_ = aTarget.GetWidth(); + pFrame->maFrameData.nHeight_ = aTarget.GetHeight(); + XRaiseWindow( m_pDisplay, + pFrame->maFrameData.GetShellWindow() + ); + if( pFrame->maFrameData.GetStackingWindow() ) + XRaiseWindow( m_pDisplay, + pFrame->maFrameData.GetStackingWindow() + ); + pFrame->maFrameData.Call( SALEVENT_RESIZE, NULL ); + } + else + { + delete pFrame->maFrameData.pFreeGraphics_; + pFrame->maFrameData.pFreeGraphics_ = NULL; + + pFrame->maFrameData.SetPosSize( pFrame->maFrameData.aRestoreFullScreen_ ); + pFrame->maFrameData.aRestoreFullScreen_ = Rectangle(); + pFrame->maFrameData.nWidth_ = pFrame->maFrameData.aPosSize_.GetWidth(); + pFrame->maFrameData.nHeight_ = pFrame->maFrameData.aPosSize_.GetHeight(); + } + } +} diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx index 0872f912023c..7118daa31c8f 100644 --- a/vcl/unx/source/window/salframe.cxx +++ b/vcl/unx/source/window/salframe.cxx @@ -2,9 +2,9 @@ * * $RCSfile: salframe.cxx,v $ * - * $Revision: 1.55 $ + * $Revision: 1.56 $ * - * last change: $Author: ssa $ $Date: 2001-08-07 09:39:27 $ + * last change: $Author: pl $ $Date: 2001-08-08 19:09:04 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -114,6 +114,9 @@ #ifndef _SV_SETTINGS_HXX #include <settings.hxx> #endif +#ifndef _VCL_WMADAPTOR_HXX_ +#include <wmadaptor.hxx> +#endif #ifdef USE_PSPRINT #ifndef _PSPRINT_PRINTERINFOMANAGER_HXX_ #include <psprint/printerinfomanager.hxx> @@ -129,6 +132,8 @@ #include "i18n_keysym.hxx" #endif +using namespace vcl_sal; + // -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #define SHOWSTATE_UNKNOWN -1 #define SHOWSTATE_MINIMIZED 0 @@ -408,7 +413,7 @@ void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) } else { - x = 10; // leave some space for dcoration + x = 10; // leave some space for decoration y = 20; } } @@ -429,9 +434,12 @@ void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) XtSetArg( aArgs[nArgs], XtNwidth, w ); nArgs++; XtSetArg( aArgs[nArgs], XtNheight, h ); nArgs++; XtSetArg( aArgs[nArgs], XtNallowShellResize, True ); nArgs++; - + XtSetArg( aArgs[nArgs], XtNwinGravity, StaticGravity ); nArgs++; if( mpParent ) - XtSetArg( aArgs[nArgs], XtNtransientFor, mpParent->maFrameData.GetShellWidget() ), nArgs++; + { + XtSetArg( aArgs[nArgs], XtNsaveUnder, True ); nArgs++; + } + #ifdef DEBUG fprintf( stderr, "nStyle = 0x%x\n", nStyle_ ); #endif @@ -443,34 +451,10 @@ void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) XtSetArg( aArgs[nArgs], XtNoverrideRedirect, True ); nArgs++; } - // Motif sometimes gets stuck on transientShell if the parent was constructed - // with SystemParentData ( and is therefore not a real top level - // window anymore ) - /* - * #81918# some WMs (dtwm e.g.) will not map a transient window - * if the parent is iconified. This is normally good behaviour, - * but if a frame is created while the parent is already iconified - * it will usually be an error box or a query (like e.g. the - * save changes? dialogue. In these cases it is better to get - * the users attention. Additionally since on many WMs transient - * leads to minimum decoration (without title) it is better - * to have full decoration for these dialogues, so create a - * frame with iconified parent as a normal application shell - */ - - if( mpParent && - ! mpParent->maFrameData.hForeignParent_ && - mpParent->maFrameData.nShowState_ != SHOWSTATE_MINIMIZED - ) - hShell_ = XtAppCreateShell( "", "VCLSalFrame", - transientShellWidgetClass, - GetXDisplay(), - aArgs, nArgs ); - else - hShell_ = XtAppCreateShell( "", "VCLSalFrame", - applicationShellWidgetClass, - GetXDisplay(), - aArgs, nArgs ); + hShell_ = XtAppCreateShell( "", "VCLSalFrame", + applicationShellWidgetClass, + GetXDisplay(), + aArgs, nArgs ); // X-Window erzeugen XtSetMappedWhenManaged( hShell_, FALSE ); @@ -483,28 +467,13 @@ void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) NULL ); XtRealizeWidget( hComposite_ ); - XWMHints *pHints = XGetWMHints( GetXDisplay(), - pDisplay_->GetWindow() ); - - if( pHints - && pHints->flags & IconMaskHint - && pHints->flags & IconPixmapHint ) - { - Hints.flags |= IconMaskHint|IconPixmapHint; - Hints.icon_pixmap = pHints->icon_pixmap; - Hints.icon_mask = pHints->icon_mask; - XFree( pHints ); - } - else + // default icon + if( SelectAppIconPixmap( pDisplay_, mpParent ? mpParent->maFrameData.mnIconID : 1, 32, + Hints.icon_pixmap, Hints.icon_mask )) { - // default icon - if( SelectAppIconPixmap( pDisplay_, 1, 32, - Hints.icon_pixmap, Hints.icon_mask )) - { - Hints.flags |= IconPixmapHint; - if( Hints.icon_mask ) - Hints.flags |= IconMaskHint; - } + Hints.flags |= IconPixmapHint; + if( Hints.icon_mask ) + Hints.flags |= IconMaskHint; } Hints.flags |= WindowGroupHint; @@ -529,12 +498,36 @@ void SalFrameData::Init( USHORT nSalFrameStyle, SystemParentData* pParentData ) Atom a[4]; int n = 0; - a[n++] = pDisplay_->GetICCCM().aWM_DeleteWindow_; - a[n++] = pDisplay_->GetICCCM().aWM_SaveYourself_; + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW ); + a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF ); XSetWMProtocols( GetXDisplay(), XtWindow( hShell_ ), a, n ); } + int nDecoFlags = WMAdaptor::decoration_All; + if( nStyle_ & (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE) + != (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE) ) + { + nDecoFlags = WMAdaptor::decoration_Border; + if( ! mpParent ) + nDecoFlags |= WMAdaptor::decoration_MinimizeBtn; + if( nStyle_ & SAL_FRAME_STYLE_CLOSEABLE ) + nDecoFlags |= WMAdaptor::decoration_CloseBtn; + if( nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) + nDecoFlags |= WMAdaptor::decoration_MaximizeBtn | WMAdaptor::decoration_Resize; + if( nStyle_ & SAL_FRAME_STYLE_MOVEABLE ) + nDecoFlags |= WMAdaptor::decoration_Title; + } + + pDisplay_->getWMAdaptor()-> + setFrameTypeAndDecoration( + pFrame_, + mpParent ? + WMAdaptor::windowType_ModalDialogue + : WMAdaptor::windowType_Normal, + nDecoFlags, + mpParent ); + // Pointer pFrame_->SetPointer( POINTER_ARROW ); @@ -599,6 +592,13 @@ inline SalFrameData::SalFrameData( SalFrame *pFrame ) maResizeTimer.SetTimeout( 50 ); mpDeleteData = NULL; + + meWindowType = WMAdaptor::windowType_Normal; + mnDecorationFlags = WMAdaptor::decoration_All; + mbMaximizedVert = false; + mbMaximizedHorz = false; + + mnIconID = 0; // ICON_DEFAULT } SalFrame::SalFrame() : maFrameData( this ) {} @@ -727,6 +727,8 @@ void SalFrame::SetIcon( USHORT nIcon ) if ( !( maFrameData.nStyle_ & SAL_FRAME_STYLE_CHILD ) && !( maFrameData.nStyle_ & SAL_FRAME_STYLE_FLOAT ) ) { + maFrameData.mnIconID = nIcon; + XIconSize *pIconSize; int nSizes; int iconSize = 32; @@ -1366,56 +1368,13 @@ void SalFrameData::Restore() // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void SalFrameData::ShowFullScreen( BOOL bFullScreen ) +void SalFrame::ShowFullScreen( BOOL bFullScreen ) { - if( aRestoreFullScreen_.IsEmpty() == !bFullScreen ) + if( maFrameData.aRestoreFullScreen_.IsEmpty() == !bFullScreen ) return; - - const Size &aScreenSize( pDisplay_->GetScreenSize() ); - - if( bFullScreen ) - { - aRestoreFullScreen_ = aPosSize_; - - delete pFreeGraphics_; - pFreeGraphics_ = NULL; - - if( bMapped_ ) - { - pFrame_->Show( TRUE ); - XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ), - RevertToNone, CurrentTime ); - } - - XMoveResizeWindow( GetXDisplay(), GetShellWindow(), 0, 0, aScreenSize.Width(), aScreenSize.Height() ); - XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, aScreenSize.Width(), aScreenSize.Height() ); - - aPosSize_ = Rectangle( Point( 0, 0 ), aScreenSize ); - nWidth_ = aPosSize_.GetWidth(); - nHeight_ = aPosSize_.GetHeight(); - - XRaiseWindow( GetXDisplay(), GetShellWindow() ); - if( GetStackingWindow() ) - XRaiseWindow( GetXDisplay(), GetStackingWindow() ); - - Call( SALEVENT_RESIZE, NULL ); - } - else - { - delete pFreeGraphics_; - pFreeGraphics_ = NULL; - - SetPosSize( aRestoreFullScreen_ ); - // SetPosSize does Call( SALEVENT_RESIZE ); - aRestoreFullScreen_ = Rectangle(); - nWidth_ = aPosSize_.GetWidth(); - nHeight_ = aPosSize_.GetHeight(); - } + maFrameData.pDisplay_->getWMAdaptor()->maximizeFrame( this, bFullScreen, bFullScreen ); } -void SalFrame::ShowFullScreen( BOOL bFullScreen ) -{ maFrameData.ShowFullScreen( bFullScreen ); } - /* --------------------------------------------------------------------- the xautolock pseudo screen saver needs special treatment since it doesn't cooperate with XxxxScreenSaver settings @@ -1563,17 +1522,17 @@ void SalFrameData::PostExtTextEvent (sal_uInt16 nExtTextEventType, void *pExtTextEvent) { XLIB_Window nFocusWindow = GetWindow(); - Atom nEventAtom = GetDisplay()->GetICCCM().aExtTextEvent_; + Atom nEventAtom = GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::SAL_EXTTEXTEVENT ); sal_uInt32 pEventData[5]; - #if __SIZEOFLONG > 4 +#if __SIZEOFLONG > 4 pEventData[0] = (sal_uInt32)((long)pExtTextEvent & 0xffffffff); pEventData[1] = (sal_uInt32)((long)pExtTextEvent >> 32); - #else +#else pEventData[0] = (sal_uInt32)((long)pExtTextEvent); pEventData[1] = NULL; - #endif +#endif pEventData[2] = (sal_uInt32)nExtTextEventType; pEventData[3] = NULL; pEventData[4] = NULL; @@ -1623,7 +1582,7 @@ SalFrameData::HandleExtTextEvent (XClientMessageEvent *pEvent) // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= BOOL SalFrame::PostEvent( void *pData ) { - _GetDisplay()->SendEvent( _GetDisplay()->GetICCCM().aUserEvent_, + _GetDisplay()->SendEvent( _GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::SAL_USEREVENT ), pData, maFrameData.GetWindow() ); return TRUE; @@ -1633,22 +1592,7 @@ BOOL SalFrame::PostEvent( void *pData ) // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= void SalFrame::SetTitle( const XubString& rTitle ) { - ByteString aByteTitle( rTitle, osl_getThreadTextEncoding() ); - - char* pTitle = (char*)aByteTitle.GetBuffer(); - XTextProperty aTitle; - - if( !XStringListToTextProperty( &pTitle, 1, &aTitle ) ) - { - fprintf( stderr, "SalFrame::SetTitle !XStringListToTextProperty(%s)\n", - pTitle ); - return; - } - - XSetWMName ( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle ); - XSetWMIconName( _GetXDisplay(), maFrameData.GetShellWindow(), &aTitle ); - - XFree( aTitle.value ); + _GetDisplay()->getWMAdaptor()->setWMName( this, rTitle ); } // ----------------------------------------------------------------------- @@ -2335,7 +2279,8 @@ long SalFrameData::HandleExposeEvent( XEvent *pEvent ) // focus is probably lost, so reget it XSetInputFocus( GetXDisplay(), XtWindow( hShell_ ), RevertToNone, CurrentTime ); - maPaintRegion.Union( Rectangle( Point(aRect.x, aRect.y), Size(aRect.width, aRect.height) ) ); + // 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 || maResizeTimer.IsActive() ) // wait for last expose rectangle return 1; @@ -2683,9 +2628,9 @@ long SalFrameData::HandleStateEvent( XPropertyEvent *pEvent ) // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= long SalFrameData::HandleClientMessage( XClientMessageEvent *pEvent ) { - SalICCCM &rICCCM = pDisplay_->GetICCCM(); + const WMAdaptor& rWMAdaptor( *pDisplay_->getWMAdaptor() ); - if( rICCCM.IsUserEvent( pEvent->message_type ) ) + if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_USEREVENT ) ) { #if __SIZEOFLONG > 4 void* pData = (void*) @@ -2696,28 +2641,28 @@ long SalFrameData::HandleClientMessage( XClientMessageEvent *pEvent ) Call( SALEVENT_USEREVENT, pData ); return 1; } - #if !defined(__synchronous_extinput__) - if( rICCCM.IsExtTextEvent( pEvent->message_type ) ) +#if !defined(__synchronous_extinput__) + if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_EXTTEXTEVENT ) ) { HandleExtTextEvent (pEvent); return 1; } - #endif - else if( rICCCM.IsQuitEvent( pEvent->message_type ) ) +#endif + else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_QUITEVENT ) ) { stderr0( "SalFrameData::Dispatch Quit\n" ); Close(); // ??? return 1; } - else if( rICCCM.IsWM_Protocols( pEvent->message_type ) ) + else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) ) { - if( rICCCM.IsWM_DeleteWindow( pEvent->data.l[0] ) ) + if( pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) ) { stderr0( "SalFrameData::Dispatch DeleteWindow\n" ); Close(); return 1; } - else if( rICCCM.IsWM_SaveYourself( pEvent->data.l[0] ) ) + else if( pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) ) { SalFrame* pLast = GetSalData()->pFirstFrame_; while( pLast->maFrameData.pNextFrame_ ) @@ -2731,7 +2676,7 @@ long SalFrameData::HandleClientMessage( XClientMessageEvent *pEvent ) XSetCommand( GetXDisplay(), XtWindow( hShell_ ), argv, 2 ); } else - XDeleteProperty( GetXDisplay(), XtWindow( hShell_ ), rICCCM.aWM_Command_ ); + XDeleteProperty( GetXDisplay(), XtWindow( hShell_ ), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ) ); } } return 0; @@ -2877,9 +2822,7 @@ long SalFrameData::Dispatch( XEvent *pEvent ) case PropertyNotify: { - SalICCCM &rICCCM = pDisplay_->GetICCCM(); - - if( rICCCM.IsWM_State( pEvent->xproperty.atom ) ) + if( pEvent->xproperty.atom == pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_STATE ) ) nRet = HandleStateEvent( &pEvent->xproperty ); else nRet = 1; |