summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/unx/inc/saldisp.hxx52
-rw-r--r--vcl/unx/inc/salframe.h16
-rw-r--r--vcl/unx/inc/wmadaptor.hxx190
-rw-r--r--vcl/unx/source/app/makefile.mk7
-rw-r--r--vcl/unx/source/app/saldisp.cxx30
-rw-r--r--vcl/unx/source/app/wmadaptor.cxx751
-rw-r--r--vcl/unx/source/window/salframe.cxx217
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;