LCOV - code coverage report
Current view: top level - vcl/unx/generic/app - wmadaptor.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 954 0.0 %
Date: 2014-04-14 Functions: 0 54 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <string.h>
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : 
      24             : #include "sal/alloca.h"
      25             : #include "rtl/locale.h"
      26             : 
      27             : #include "osl/thread.h"
      28             : #include "osl/process.h"
      29             : #include <sal/macros.h>
      30             : #include "vcl/configsettings.hxx"
      31             : 
      32             : #include "unx/wmadaptor.hxx"
      33             : #include "unx/saldisp.hxx"
      34             : #include "unx/saldata.hxx"
      35             : #include "unx/salframe.h"
      36             : 
      37             : #include "salgdi.hxx"
      38             : 
      39             : #include <prex.h>
      40             : #include <X11/X.h>
      41             : #include <X11/Xatom.h>
      42             : #include <X11/Xresource.h>
      43             : #include <postx.h>
      44             : 
      45             : namespace vcl_sal {
      46             : 
      47             : class NetWMAdaptor : public WMAdaptor
      48             : {
      49             :     void setNetWMState( X11SalFrame* pFrame ) const;
      50             :     void initAtoms();
      51             :     virtual bool isValid() const SAL_OVERRIDE;
      52             : public:
      53             :     NetWMAdaptor( SalDisplay* );
      54             :     virtual ~NetWMAdaptor();
      55             : 
      56             :     virtual void setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const SAL_OVERRIDE;
      57             :     virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const SAL_OVERRIDE;
      58             :     virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const SAL_OVERRIDE;
      59             :     virtual void setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pTransientFrame = NULL ) const SAL_OVERRIDE;
      60             :     virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const SAL_OVERRIDE;
      61             :     virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const SAL_OVERRIDE;
      62             :     virtual void showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const SAL_OVERRIDE;
      63             :     virtual void frameIsMapping( X11SalFrame* pFrame ) const SAL_OVERRIDE;
      64             :     virtual void setFrameStruts( X11SalFrame* pFrame,
      65             :                                  int left, int right, int top, int bottom,
      66             :                                  int left_start_y, int left_end_y,
      67             :                                  int right_start_y, int right_end_y,
      68             :                                  int top_start_x, int top_end_x,
      69             :                                  int bottom_start_x, int bottom_end_x ) const SAL_OVERRIDE;
      70             :     virtual void setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const SAL_OVERRIDE;
      71             : };
      72             : 
      73             : class GnomeWMAdaptor : public WMAdaptor
      74             : {
      75             :     bool m_bValid;
      76             : 
      77             :     void setGnomeWMState( X11SalFrame* pFrame ) const;
      78             :     void initAtoms();
      79             :     virtual bool isValid() const SAL_OVERRIDE;
      80             : public:
      81             :     GnomeWMAdaptor( SalDisplay * );
      82             :     virtual ~GnomeWMAdaptor();
      83             : 
      84             :     virtual void maximizeFrame( X11SalFrame* pFrame, bool bHorizontal = true, bool bVertical = true ) const SAL_OVERRIDE;
      85             :     virtual void shade( X11SalFrame* pFrame, bool bToShaded ) const SAL_OVERRIDE;
      86             :     virtual void enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const SAL_OVERRIDE;
      87             :     virtual int handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const SAL_OVERRIDE;
      88             : };
      89             : 
      90             : }
      91             : 
      92             : using namespace vcl_sal;
      93             : 
      94             : struct WMAdaptorProtocol
      95             : {
      96             :     const char* pProtocol;
      97             :     int             nProtocol;
      98             : };
      99             : 
     100             : /*
     101             :  *  table must be sorted ascending in strings
     102             :  *  since it is use with bsearch
     103             :  */
     104             : static const WMAdaptorProtocol aProtocolTab[] =
     105             : {
     106             :     { "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", WMAdaptor::KDE_NET_WM_WINDOW_TYPE_OVERRIDE },
     107             :     { "_NET_CURRENT_DESKTOP", WMAdaptor::NET_CURRENT_DESKTOP },
     108             :     { "_NET_NUMBER_OF_DESKTOPS", WMAdaptor::NET_NUMBER_OF_DESKTOPS },
     109             :     { "_NET_WM_DESKTOP", WMAdaptor::NET_WM_DESKTOP },
     110             :     { "_NET_WM_ICON", WMAdaptor::NET_WM_ICON },
     111             :     { "_NET_WM_ICON_NAME", WMAdaptor::NET_WM_ICON_NAME },
     112             :     { "_NET_WM_PING", WMAdaptor::NET_WM_PING },
     113             :     { "_NET_WM_STATE", WMAdaptor::NET_WM_STATE },
     114             :     { "_NET_WM_STATE_ABOVE", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP },
     115             :     { "_NET_WM_STATE_FULLSCREEN", WMAdaptor::NET_WM_STATE_FULLSCREEN },
     116             :     { "_NET_WM_STATE_MAXIMIZED_HORIZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ }, // common bug in e.g. older kwin and sawfish implementations
     117             :     { "_NET_WM_STATE_MAXIMIZED_HORZ", WMAdaptor::NET_WM_STATE_MAXIMIZED_HORZ },
     118             :     { "_NET_WM_STATE_MAXIMIZED_VERT", WMAdaptor::NET_WM_STATE_MAXIMIZED_VERT },
     119             :     { "_NET_WM_STATE_MODAL", WMAdaptor::NET_WM_STATE_MODAL },
     120             :     { "_NET_WM_STATE_SHADED", WMAdaptor::NET_WM_STATE_SHADED },
     121             :     { "_NET_WM_STATE_SKIP_PAGER", WMAdaptor::NET_WM_STATE_SKIP_PAGER },
     122             :     { "_NET_WM_STATE_SKIP_TASKBAR", WMAdaptor::NET_WM_STATE_SKIP_TASKBAR },
     123             :     { "_NET_WM_STATE_STAYS_ON_TOP", WMAdaptor::NET_WM_STATE_STAYS_ON_TOP },
     124             :     { "_NET_WM_STATE_STICKY", WMAdaptor::NET_WM_STATE_STICKY },
     125             :     { "_NET_WM_STRUT", WMAdaptor::NET_WM_STRUT },
     126             :     { "_NET_WM_STRUT_PARTIAL", WMAdaptor::NET_WM_STRUT_PARTIAL },
     127             :     { "_NET_WM_WINDOW_TYPE", WMAdaptor::NET_WM_WINDOW_TYPE },
     128             :     { "_NET_WM_WINDOW_TYPE_DESKTOP", WMAdaptor::NET_WM_WINDOW_TYPE_DESKTOP },
     129             :     { "_NET_WM_WINDOW_TYPE_DIALOG", WMAdaptor::NET_WM_WINDOW_TYPE_DIALOG },
     130             :     { "_NET_WM_WINDOW_TYPE_DOCK", WMAdaptor::NET_WM_WINDOW_TYPE_DOCK },
     131             :     { "_NET_WM_WINDOW_TYPE_MENU", WMAdaptor::NET_WM_WINDOW_TYPE_MENU },
     132             :     { "_NET_WM_WINDOW_TYPE_NORMAL", WMAdaptor::NET_WM_WINDOW_TYPE_NORMAL },
     133             :     { "_NET_WM_WINDOW_TYPE_SPLASH", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH },
     134             :     { "_NET_WM_WINDOW_TYPE_SPLASHSCREEN", WMAdaptor::NET_WM_WINDOW_TYPE_SPLASH }, // bug in Metacity 2.4.1
     135             :     { "_NET_WM_WINDOW_TYPE_TOOLBAR", WMAdaptor::NET_WM_WINDOW_TYPE_TOOLBAR },
     136             :     { "_NET_WM_WINDOW_TYPE_UTILITY", WMAdaptor::NET_WM_WINDOW_TYPE_UTILITY },
     137             :     { "_NET_WORKAREA", WMAdaptor::NET_WORKAREA },
     138             :     { "_WIN_APP_STATE", WMAdaptor::WIN_APP_STATE },
     139             :     { "_WIN_CLIENT_LIST", WMAdaptor::WIN_CLIENT_LIST },
     140             :     { "_WIN_EXPANDED_SIZE", WMAdaptor::WIN_EXPANDED_SIZE },
     141             :     { "_WIN_HINTS", WMAdaptor::WIN_HINTS },
     142             :     { "_WIN_ICONS", WMAdaptor::WIN_ICONS },
     143             :     { "_WIN_LAYER", WMAdaptor::WIN_LAYER },
     144             :     { "_WIN_STATE", WMAdaptor::WIN_STATE },
     145             :     { "_WIN_WORKSPACE", WMAdaptor::WIN_WORKSPACE },
     146             :     { "_WIN_WORKSPACE_COUNT", WMAdaptor::WIN_WORKSPACE_COUNT }
     147             : };
     148             : 
     149             : /*
     150             :  *  table containing atoms to get anyway
     151             :  */
     152             : 
     153             : static const WMAdaptorProtocol aAtomTab[] =
     154             : {
     155             :     { "WM_STATE", WMAdaptor::WM_STATE },
     156             :     { "_MOTIF_WM_HINTS", WMAdaptor::MOTIF_WM_HINTS },
     157             :     { "WM_PROTOCOLS", WMAdaptor::WM_PROTOCOLS },
     158             :     { "WM_DELETE_WINDOW", WMAdaptor::WM_DELETE_WINDOW },
     159             :     { "WM_TAKE_FOCUS", WMAdaptor::WM_TAKE_FOCUS },
     160             :     { "WM_COMMAND", WMAdaptor::WM_COMMAND },
     161             :     { "WM_CLIENT_LEADER", WMAdaptor::WM_CLIENT_LEADER },
     162             :     { "WM_LOCALE_NAME", WMAdaptor::WM_LOCALE_NAME },
     163             :     { "WM_TRANSIENT_FOR", WMAdaptor::WM_TRANSIENT_FOR },
     164             :     { "SAL_QUITEVENT", WMAdaptor::SAL_QUITEVENT },
     165             :     { "SAL_USEREVENT", WMAdaptor::SAL_USEREVENT },
     166             :     { "SAL_EXTTEXTEVENT", WMAdaptor::SAL_EXTTEXTEVENT },
     167             :     { "SAL_GETTIMEEVENT", WMAdaptor::SAL_GETTIMEEVENT },
     168             :     { "VCL_SYSTEM_SETTINGS", WMAdaptor::VCL_SYSTEM_SETTINGS },
     169             :     { "_XSETTINGS_SETTINGS", WMAdaptor::XSETTINGS },
     170             :     { "_XEMBED", WMAdaptor::XEMBED },
     171             :     { "_XEMBED_INFO", WMAdaptor::XEMBED_INFO },
     172             :     { "_NET_WM_USER_TIME", WMAdaptor::NET_WM_USER_TIME },
     173             :     { "_NET_WM_PID", WMAdaptor::NET_WM_PID }
     174             : };
     175             : 
     176             : extern "C" {
     177           0 : static int compareProtocol( const void* pLeft, const void* pRight )
     178             : {
     179           0 :     return strcmp( ((const WMAdaptorProtocol*)pLeft)->pProtocol, ((const WMAdaptorProtocol*)pRight)->pProtocol );
     180             : }
     181             : }
     182             : 
     183           0 : WMAdaptor* WMAdaptor::createWMAdaptor( SalDisplay* pSalDisplay )
     184             : {
     185           0 :     WMAdaptor*          pAdaptor    = NULL;
     186             : 
     187             :     // try a NetWM
     188           0 :     pAdaptor = new NetWMAdaptor( pSalDisplay );
     189           0 :     if( ! pAdaptor->isValid() )
     190           0 :         delete pAdaptor, pAdaptor = NULL;
     191             : #if OSL_DEBUG_LEVEL > 1
     192             :     else
     193             :         fprintf( stderr, "WM supports extended WM hints\n" );
     194             : #endif
     195             : 
     196             :     // try a GnomeWM
     197           0 :     if( ! pAdaptor )
     198             :     {
     199           0 :         pAdaptor = new GnomeWMAdaptor( pSalDisplay );
     200           0 :         if( ! pAdaptor->isValid() )
     201           0 :             delete pAdaptor, pAdaptor = NULL;
     202             : #if OSL_DEBUG_LEVEL > 1
     203             :         else
     204             :             fprintf( stderr, "WM supports GNOME WM hints\n" );
     205             : #endif
     206             :     }
     207             : 
     208           0 :     if( ! pAdaptor )
     209           0 :         pAdaptor = new WMAdaptor( pSalDisplay );
     210             : 
     211             : #if OSL_DEBUG_LEVEL > 1
     212             :     fprintf(stderr, "Window Manager's name is \"%s\"\n",
     213             :         OUStringToOString(pAdaptor->getWindowManagerName(),
     214             :         RTL_TEXTENCODING_UTF8).getStr());
     215             : #endif
     216           0 :     return pAdaptor;
     217             : }
     218             : 
     219             : /*
     220             :  *  WMAdaptor constructor
     221             :  */
     222             : 
     223           0 : WMAdaptor::WMAdaptor( SalDisplay* pDisplay ) :
     224             :         m_pSalDisplay( pDisplay ),
     225             :         m_bTransientBehaviour( true ),
     226             :         m_bEnableAlwaysOnTopWorks( false ),
     227             :         m_bLegacyPartialFullscreen( false ),
     228             :         m_nWinGravity( StaticGravity ),
     229             :         m_nInitWinGravity( StaticGravity ),
     230             :         m_bWMshouldSwitchWorkspace( true ),
     231           0 :         m_bWMshouldSwitchWorkspaceInit( false )
     232             : {
     233           0 :     Atom                aRealType   = None;
     234           0 :     int                 nFormat     = 8;
     235           0 :     unsigned long       nItems      = 0;
     236           0 :     unsigned long       nBytesLeft  = 0;
     237           0 :     unsigned char*  pProperty   = NULL;
     238             : 
     239             :     // default desktops
     240           0 :     m_nDesktops = 1;
     241           0 :     m_aWMWorkAreas = ::std::vector< Rectangle >
     242           0 :         ( 1, Rectangle( Point(), m_pSalDisplay->GetScreenSize( m_pSalDisplay->GetDefaultXScreen() ) ) );
     243           0 :     m_bEqualWorkAreas = true;
     244             : 
     245           0 :     memset( m_aWMAtoms, 0, sizeof( m_aWMAtoms ) );
     246           0 :     m_pDisplay = m_pSalDisplay->GetDisplay();
     247             : 
     248           0 :     initAtoms();
     249           0 :     getNetWmName(); // try to discover e.g. Sawfish
     250             : 
     251           0 :     if( m_aWMName.isEmpty() )
     252             :     {
     253             :         // check for ReflectionX wm (as it needs a workaround in Windows mode
     254           0 :         Atom aRwmRunning = XInternAtom( m_pDisplay, "RWM_RUNNING", True );
     255           0 :         if( aRwmRunning != None &&
     256             :             XGetWindowProperty( m_pDisplay,
     257             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     258             :                                 aRwmRunning,
     259             :                                 0, 32,
     260             :                                 False,
     261             :                                 aRwmRunning,
     262             :                                 &aRealType,
     263             :                                 &nFormat,
     264             :                                 &nItems,
     265             :                                 &nBytesLeft,
     266           0 :                                 &pProperty ) == 0 )
     267             :         {
     268           0 :             if( aRealType == aRwmRunning )
     269           0 :                 m_aWMName = "ReflectionX";
     270           0 :             XFree( pProperty );
     271             :         }
     272           0 :         else if( (aRwmRunning = XInternAtom( m_pDisplay, "_WRQ_WM_RUNNING", True )) != None &&
     273             :             XGetWindowProperty( m_pDisplay,
     274             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     275             :                                 aRwmRunning,
     276             :                                 0, 32,
     277             :                                 False,
     278             :                                 XA_STRING,
     279             :                                 &aRealType,
     280             :                                 &nFormat,
     281             :                                 &nItems,
     282             :                                 &nBytesLeft,
     283           0 :                                 &pProperty ) == 0 )
     284             :         {
     285           0 :             if( aRealType == XA_STRING )
     286           0 :                 m_aWMName = "ReflectionX Windows";
     287           0 :             XFree( pProperty );
     288             :         }
     289             :     }
     290           0 :     if( m_aWMName.isEmpty() )
     291             :     {
     292           0 :         Atom aTTAPlatform = XInternAtom( m_pDisplay, "TTA_CLIENT_PLATFORM", True );
     293           0 :         if( aTTAPlatform != None &&
     294             :             XGetWindowProperty( m_pDisplay,
     295             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     296             :                                 aTTAPlatform,
     297             :                                 0, 32,
     298             :                                 False,
     299             :                                 XA_STRING,
     300             :                                 &aRealType,
     301             :                                 &nFormat,
     302             :                                 &nItems,
     303             :                                 &nBytesLeft,
     304           0 :                                 &pProperty ) == 0 )
     305             :         {
     306           0 :             if( aRealType == XA_STRING )
     307             :             {
     308           0 :                 m_aWMName = "Tarantella";
     309             :                 // #i62319# pretend that AlwaysOnTop works since
     310             :                 // the alwaysontop workaround in salframe.cxx results
     311             :                 // in a raise/lower loop on a Windows tarantella client
     312             :                 // FIXME: this property contains an identification string that
     313             :                 // in theory should be good enough to recognize running on a
     314             :                 // Windows client; however this string does not seem to be
     315             :                 // documented as well as the property itself.
     316           0 :                 m_bEnableAlwaysOnTopWorks = true;
     317             :             }
     318           0 :             XFree( pProperty );
     319             :         }
     320             :     }
     321           0 : }
     322             : 
     323             : /*
     324             :  *  WMAdaptor destructor
     325             :  */
     326             : 
     327           0 : WMAdaptor::~WMAdaptor()
     328             : {
     329           0 : }
     330             : 
     331             : /*
     332             :  *  NetWMAdaptor constructor
     333             :  */
     334             : 
     335           0 : NetWMAdaptor::NetWMAdaptor( SalDisplay* pSalDisplay ) :
     336           0 :         WMAdaptor( pSalDisplay )
     337             : {
     338             :     // currently all _NET WMs do transient like expected
     339           0 :     m_bTransientBehaviour = true;
     340             : 
     341           0 :     Atom                aRealType   = None;
     342           0 :     int                 nFormat     = 8;
     343           0 :     unsigned long       nItems      = 0;
     344           0 :     unsigned long       nBytesLeft  = 0;
     345           0 :     unsigned char*  pProperty   = NULL;
     346             : 
     347           0 :     initAtoms();
     348             : 
     349             :     // check for NetWM
     350           0 :     bool bNetWM = getNetWmName();
     351           0 :     if( bNetWM
     352           0 :         && XGetWindowProperty( m_pDisplay,
     353             :                                m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     354             :                                m_aWMAtoms[ NET_SUPPORTED ],
     355             :                                0, 0,
     356             :                                False,
     357             :                                XA_ATOM,
     358             :                                &aRealType,
     359             :                                &nFormat,
     360             :                                &nItems,
     361             :                                &nBytesLeft,
     362           0 :                                &pProperty ) == 0
     363           0 :         && aRealType == XA_ATOM
     364           0 :         && nFormat == 32
     365             :         )
     366             :     {
     367           0 :         if( pProperty )
     368             :         {
     369           0 :             XFree( pProperty );
     370           0 :             pProperty = NULL;
     371             :         }
     372             :         // collect supported protocols
     373           0 :         if( XGetWindowProperty( m_pDisplay,
     374             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     375             :                                 m_aWMAtoms[ NET_SUPPORTED ],
     376           0 :                                 0, nBytesLeft/4,
     377             :                                 False,
     378             :                                 XA_ATOM,
     379             :                                 &aRealType,
     380             :                                 &nFormat,
     381             :                                 &nItems,
     382             :                                 &nBytesLeft,
     383           0 :                                 &pProperty ) == 0
     384           0 :             && nItems
     385             :             )
     386             :         {
     387           0 :             Atom* pAtoms = (Atom*)pProperty;
     388           0 :             char** pAtomNames = (char**)alloca( sizeof(char*)*nItems );
     389           0 :             if( XGetAtomNames( m_pDisplay, pAtoms, nItems, pAtomNames ) )
     390             :             {
     391             : #if OSL_DEBUG_LEVEL > 1
     392             :                 fprintf( stderr, "supported protocols:\n" );
     393             : #endif
     394           0 :                 for( unsigned int i = 0; i < nItems; i++ )
     395             :                 {
     396             :                     // #i80971# protect against invalid atoms
     397           0 :                     if( pAtomNames[i] == NULL )
     398           0 :                         continue;
     399             : 
     400             :                     WMAdaptorProtocol aSearch;
     401           0 :                     aSearch.pProtocol = pAtomNames[i];
     402             :                     WMAdaptorProtocol* pMatch = (WMAdaptorProtocol*)
     403             :                         bsearch( &aSearch,
     404             :                                  aProtocolTab,
     405             :                                  SAL_N_ELEMENTS( aProtocolTab ),
     406             :                                  sizeof( struct WMAdaptorProtocol ),
     407           0 :                                  compareProtocol );
     408           0 :                     if( pMatch )
     409             :                     {
     410           0 :                         m_aWMAtoms[ pMatch->nProtocol ] = pAtoms[ i ];
     411           0 :                         if( pMatch->nProtocol == NET_WM_STATE_STAYS_ON_TOP )
     412           0 :                             m_bEnableAlwaysOnTopWorks = true;
     413             :                     }
     414             : #if OSL_DEBUG_LEVEL > 1
     415             :                     fprintf( stderr, "  %s%s\n", pAtomNames[i], ((pMatch)&&(pMatch->nProtocol != -1)) ? "" : " (unsupported)" );
     416             : #endif
     417           0 :                     XFree( pAtomNames[i] );
     418             :                 }
     419             :             }
     420           0 :             XFree( pProperty );
     421           0 :             pProperty = NULL;
     422             :         }
     423           0 :         else if( pProperty )
     424             :         {
     425           0 :             XFree( pProperty );
     426           0 :             pProperty = NULL;
     427             :         }
     428             : 
     429             :         // get number of desktops
     430           0 :         if( m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ]
     431           0 :             && XGetWindowProperty( m_pDisplay,
     432             :                                    m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     433             :                                    m_aWMAtoms[ NET_NUMBER_OF_DESKTOPS ],
     434             :                                    0, 1,
     435             :                                    False,
     436             :                                    XA_CARDINAL,
     437             :                                    &aRealType,
     438             :                                    &nFormat,
     439             :                                    &nItems,
     440             :                                    &nBytesLeft,
     441           0 :                                    &pProperty ) == 0
     442           0 :             && pProperty
     443             :             )
     444             :         {
     445           0 :             m_nDesktops = *(long*)pProperty;
     446           0 :             XFree( pProperty );
     447           0 :             pProperty = NULL;
     448             :             // get work areas
     449           0 :             if( m_aWMAtoms[ NET_WORKAREA ]
     450           0 :                 && XGetWindowProperty( m_pDisplay,
     451             :                                        m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     452             :                                        m_aWMAtoms[ NET_WORKAREA ],
     453           0 :                                        0, 4*m_nDesktops,
     454             :                                        False,
     455             :                                        XA_CARDINAL,
     456             :                                        &aRealType,
     457             :                                        &nFormat,
     458             :                                        &nItems,
     459             :                                        &nBytesLeft,
     460             :                                        &pProperty
     461           0 :                                        ) == 0
     462           0 :                 && nItems == 4*(unsigned)m_nDesktops
     463             :                 )
     464             :             {
     465           0 :                 m_aWMWorkAreas = ::std::vector< Rectangle > ( m_nDesktops );
     466           0 :                 long* pValues = (long*)pProperty;
     467           0 :                 for( int i = 0; i < m_nDesktops; i++ )
     468             :                 {
     469           0 :                     Point aPoint( pValues[4*i],
     470           0 :                                   pValues[4*i+1] );
     471           0 :                     Size aSize( pValues[4*i+2],
     472           0 :                                 pValues[4*i+3] );
     473           0 :                     Rectangle aWorkArea( aPoint, aSize );
     474           0 :                     m_aWMWorkAreas[i] = aWorkArea;
     475           0 :                     if( aWorkArea != m_aWMWorkAreas[0] )
     476           0 :                         m_bEqualWorkAreas = false;
     477             : #if OSL_DEBUG_LEVEL > 1
     478             :                     fprintf( stderr, "workarea %d: %ldx%ld+%ld+%ld\n",
     479             :                              i,
     480             :                              m_aWMWorkAreas[i].GetWidth(),
     481             :                              m_aWMWorkAreas[i].GetHeight(),
     482             :                              m_aWMWorkAreas[i].Left(),
     483             :                              m_aWMWorkAreas[i].Top() );
     484             : #endif
     485             :                 }
     486           0 :                 XFree( pProperty );
     487             :             }
     488             :             else
     489             :             {
     490             : #if OSL_DEBUG_LEVEL > 1
     491             :                 fprintf( stderr, "%ld workareas for %d desktops !\n", nItems/4, m_nDesktops );
     492             : #endif
     493           0 :                 if( pProperty )
     494             :                 {
     495           0 :                     XFree(pProperty);
     496           0 :                     pProperty = NULL;
     497             :                 }
     498             :             }
     499             :         }
     500           0 :         else if( pProperty )
     501             :         {
     502           0 :             XFree( pProperty );
     503           0 :             pProperty = NULL;
     504             :         }
     505             :     }
     506           0 :     else if( pProperty )
     507             :     {
     508           0 :         XFree( pProperty );
     509           0 :         pProperty = NULL;
     510             :     }
     511           0 : }
     512             : 
     513             : /*
     514             :  *  NetWMAdaptor destructor
     515             :  */
     516           0 : NetWMAdaptor::~NetWMAdaptor()
     517             : {
     518           0 : }
     519             : 
     520             : /*
     521             :  *  GnomeWMAdaptor constructor
     522             :  */
     523             : 
     524           0 : GnomeWMAdaptor::GnomeWMAdaptor( SalDisplay* pSalDisplay ) :
     525             :         WMAdaptor( pSalDisplay ),
     526           0 :         m_bValid( false )
     527             : {
     528             :     // currently all Gnome WMs do transient like expected
     529           0 :     m_bTransientBehaviour = true;
     530             : 
     531           0 :     Atom                aRealType   = None;
     532           0 :     int                 nFormat     = 8;
     533           0 :     unsigned long       nItems      = 0;
     534           0 :     unsigned long       nBytesLeft  = 0;
     535           0 :     unsigned char*  pProperty   = NULL;
     536             : 
     537           0 :     initAtoms();
     538             : 
     539             :     // check for GnomeWM
     540           0 :     if( m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ] && m_aWMAtoms[ WIN_PROTOCOLS ] )
     541             :     {
     542           0 :         XLIB_Window         aWMChild    = None;
     543           0 :         if( XGetWindowProperty( m_pDisplay,
     544             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     545             :                                 m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ],
     546             :                                 0, 1,
     547             :                                 False,
     548             :                                 XA_CARDINAL,
     549             :                                 &aRealType,
     550             :                                 &nFormat,
     551             :                                 &nItems,
     552             :                                 &nBytesLeft,
     553           0 :                                 &pProperty ) == 0
     554           0 :             && aRealType == XA_CARDINAL
     555           0 :             && nFormat == 32
     556           0 :             && nItems != 0
     557             :             )
     558             :         {
     559           0 :             aWMChild = *(XLIB_Window*)pProperty;
     560           0 :             XFree( pProperty );
     561           0 :             pProperty = NULL;
     562           0 :             XLIB_Window aCheckWindow = None;
     563           0 :             GetGenericData()->ErrorTrapPush();
     564           0 :             if( XGetWindowProperty( m_pDisplay,
     565             :                                     aWMChild,
     566             :                                     m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ],
     567             :                                     0, 1,
     568             :                                     False,
     569             :                                     XA_CARDINAL,
     570             :                                     &aRealType,
     571             :                                     &nFormat,
     572             :                                     &nItems,
     573             :                                     &nBytesLeft,
     574           0 :                                     &pProperty ) == 0
     575           0 :                 && aRealType == XA_CARDINAL
     576           0 :                 && nFormat == 32
     577           0 :                 && nItems != 0 )
     578             :             {
     579           0 :                 if (! GetGenericData()->ErrorTrapPop( false ) )
     580             :                 {
     581           0 :                     GetGenericData()->ErrorTrapPush();
     582             : 
     583           0 :                     aCheckWindow =  *(XLIB_Window*)pProperty;
     584           0 :                     XFree( pProperty );
     585           0 :                     pProperty = NULL;
     586           0 :                     if( aCheckWindow == aWMChild )
     587             :                     {
     588           0 :                         m_bValid = true;
     589             :                         /*
     590             :                          *  get name of WM
     591             :                          *  this is NOT part of the GNOME WM hints, but e.g. Sawfish
     592             :                          *  already supports this part of the extended WM hints
     593             :                          */
     594           0 :                         m_aWMAtoms[ UTF8_STRING ] = XInternAtom( m_pDisplay, "UTF8_STRING", False );
     595           0 :                         getNetWmName();
     596             :                     }
     597             :                 }
     598             :                 else
     599           0 :                     GetGenericData()->ErrorTrapPush();
     600             :             }
     601           0 :             GetGenericData()->ErrorTrapPop();
     602             :         }
     603           0 :         else if( pProperty )
     604             :         {
     605           0 :             XFree( pProperty );
     606           0 :             pProperty = NULL;
     607             :         }
     608             :     }
     609           0 :     if( m_bValid
     610           0 :         && XGetWindowProperty( m_pDisplay,
     611             :                                m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     612             :                                m_aWMAtoms[ WIN_PROTOCOLS ],
     613             :                                0, 0,
     614             :                                False,
     615             :                                XA_ATOM,
     616             :                                &aRealType,
     617             :                                &nFormat,
     618             :                                &nItems,
     619             :                                &nBytesLeft,
     620           0 :                                &pProperty ) == 0
     621           0 :         && aRealType == XA_ATOM
     622           0 :         && nFormat == 32
     623             :         )
     624             :     {
     625           0 :         if( pProperty )
     626             :         {
     627           0 :             XFree( pProperty );
     628           0 :             pProperty = NULL;
     629             :         }
     630             :         // collect supported protocols
     631           0 :         if( XGetWindowProperty( m_pDisplay,
     632             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     633             :                                 m_aWMAtoms[ WIN_PROTOCOLS ],
     634           0 :                                 0, nBytesLeft/4,
     635             :                                 False,
     636             :                                 XA_ATOM,
     637             :                                 &aRealType,
     638             :                                 &nFormat,
     639             :                                 &nItems,
     640             :                                 &nBytesLeft,
     641           0 :                                 &pProperty ) == 0
     642           0 :             && pProperty
     643             :             )
     644             :         {
     645           0 :             Atom* pAtoms = (Atom*)pProperty;
     646           0 :             char** pAtomNames = (char**)alloca( sizeof(char*)*nItems );
     647           0 :             if( XGetAtomNames( m_pDisplay, pAtoms, nItems, pAtomNames ) )
     648             :             {
     649             : #if OSL_DEBUG_LEVEL > 1
     650             :                 fprintf( stderr, "supported protocols:\n" );
     651             : #endif
     652           0 :                 for( unsigned int i = 0; i < nItems; i++ )
     653             :                 {
     654             :                     // #i80971# protect against invalid atoms
     655           0 :                     if( pAtomNames[i] == NULL )
     656           0 :                         continue;
     657             : 
     658             :                     WMAdaptorProtocol aSearch;
     659           0 :                     aSearch.pProtocol = pAtomNames[i];
     660             :                     WMAdaptorProtocol* pMatch = (WMAdaptorProtocol*)
     661             :                         bsearch( &aSearch,
     662             :                                  aProtocolTab,
     663             :                                  SAL_N_ELEMENTS( aProtocolTab ),
     664             :                                  sizeof( struct WMAdaptorProtocol ),
     665           0 :                                  compareProtocol );
     666           0 :                     if( pMatch )
     667             :                     {
     668           0 :                         m_aWMAtoms[ pMatch->nProtocol ] = pAtoms[ i ];
     669           0 :                         if( pMatch->nProtocol == WIN_LAYER )
     670           0 :                             m_bEnableAlwaysOnTopWorks = true;
     671             :                     }
     672           0 :                     if( strncmp( "_ICEWM_TRAY", pAtomNames[i], 11 ) == 0 )
     673             :                     {
     674           0 :                         m_aWMName = "IceWM";
     675           0 :                         m_nWinGravity = NorthWestGravity;
     676           0 :                         m_nInitWinGravity = NorthWestGravity;
     677             :                     }
     678             : #if OSL_DEBUG_LEVEL > 1
     679             :                     fprintf( stderr, "  %s%s\n", pAtomNames[i], ((pMatch) && (pMatch->nProtocol != -1)) ? "" : " (unsupported)" );
     680             : #endif
     681           0 :                     XFree( pAtomNames[i] );
     682             :                 }
     683             :             }
     684           0 :             XFree( pProperty );
     685           0 :             pProperty = NULL;
     686             :         }
     687           0 :         else if( pProperty )
     688             :         {
     689           0 :             XFree( pProperty );
     690           0 :             pProperty = NULL;
     691             :         }
     692             : 
     693             :         // get number of desktops
     694           0 :         if( m_aWMAtoms[ WIN_WORKSPACE_COUNT ]
     695           0 :             && XGetWindowProperty( m_pDisplay,
     696             :                                    m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     697             :                                    m_aWMAtoms[ WIN_WORKSPACE_COUNT ],
     698             :                                    0, 1,
     699             :                                    False,
     700             :                                    XA_CARDINAL,
     701             :                                    &aRealType,
     702             :                                    &nFormat,
     703             :                                    &nItems,
     704             :                                    &nBytesLeft,
     705           0 :                                    &pProperty ) == 0
     706           0 :             && pProperty
     707             :             )
     708             :         {
     709           0 :             m_nDesktops = *(long*)pProperty;
     710           0 :             XFree( pProperty );
     711           0 :             pProperty = NULL;
     712             :         }
     713           0 :         else if( pProperty )
     714             :         {
     715           0 :             XFree( pProperty );
     716           0 :             pProperty = NULL;
     717             :         }
     718             :     }
     719           0 :     else if( pProperty )
     720             :     {
     721           0 :         XFree( pProperty );
     722           0 :         pProperty = NULL;
     723             :     }
     724           0 : }
     725             : 
     726             : /*
     727             :  *  GnomeWMAdaptor destructor
     728             :  */
     729           0 : GnomeWMAdaptor::~GnomeWMAdaptor()
     730             : {
     731           0 : }
     732             : 
     733             : /*
     734             :  *  getNetWmName()
     735             :  */
     736           0 : bool WMAdaptor::getNetWmName()
     737             : {
     738           0 :     Atom                aRealType   = None;
     739           0 :     int                 nFormat     = 8;
     740           0 :     unsigned long       nItems      = 0;
     741           0 :     unsigned long       nBytesLeft  = 0;
     742           0 :     unsigned char*  pProperty   = NULL;
     743           0 :     bool                bNetWM      = false;
     744             : 
     745           0 :     if( m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ] && m_aWMAtoms[ NET_WM_NAME ] )
     746             :     {
     747           0 :         XLIB_Window         aWMChild = None;
     748           0 :         if( XGetWindowProperty( m_pDisplay,
     749             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
     750             :                                 m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ],
     751             :                                 0, 1,
     752             :                                 False,
     753             :                                 XA_WINDOW,
     754             :                                 &aRealType,
     755             :                                 &nFormat,
     756             :                                 &nItems,
     757             :                                 &nBytesLeft,
     758           0 :                                 &pProperty ) == 0
     759           0 :             && aRealType == XA_WINDOW
     760           0 :             && nFormat == 32
     761           0 :             && nItems != 0
     762             :             )
     763             :         {
     764           0 :             aWMChild = *(XLIB_Window*)pProperty;
     765           0 :             XFree( pProperty );
     766           0 :             pProperty = NULL;
     767           0 :             XLIB_Window aCheckWindow = None;
     768           0 :             GetGenericData()->ErrorTrapPush();
     769           0 :             if( XGetWindowProperty( m_pDisplay,
     770             :                                     aWMChild,
     771             :                                     m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ],
     772             :                                     0, 1,
     773             :                                     False,
     774             :                                     XA_WINDOW,
     775             :                                     &aRealType,
     776             :                                     &nFormat,
     777             :                                     &nItems,
     778             :                                     &nBytesLeft,
     779           0 :                                     &pProperty ) == 0
     780           0 :                 && aRealType == XA_WINDOW
     781           0 :                 && nFormat == 32
     782           0 :                 && nItems != 0 )
     783             :                 {
     784           0 :                     if ( ! GetGenericData()->ErrorTrapPop( false ) )
     785             :                     {
     786           0 :                         GetGenericData()->ErrorTrapPush();
     787           0 :                         aCheckWindow =  *(XLIB_Window*)pProperty;
     788           0 :                         XFree( pProperty );
     789           0 :                         pProperty = NULL;
     790           0 :                         if( aCheckWindow == aWMChild )
     791             :                         {
     792           0 :                             bNetWM = true;
     793             :                             // get name of WM
     794           0 :                             m_aWMAtoms[ UTF8_STRING ] = XInternAtom( m_pDisplay, "UTF8_STRING", False );
     795           0 :                             if( XGetWindowProperty( m_pDisplay,
     796             :                                                     aWMChild,
     797             :                                                     m_aWMAtoms[ NET_WM_NAME ],
     798             :                                                     0, 256,
     799             :                                                     False,
     800             :                                                     AnyPropertyType, /* m_aWMAtoms[ UTF8_STRING ],*/
     801             :                                                     &aRealType,
     802             :                                                     &nFormat,
     803             :                                                     &nItems,
     804             :                                                     &nBytesLeft,
     805           0 :                                                     &pProperty ) == 0
     806           0 :                                 && nItems != 0
     807             :                                 )
     808             :                             {
     809           0 :                                 if (aRealType == m_aWMAtoms[ UTF8_STRING ])
     810           0 :                                     m_aWMName = OUString( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 );
     811           0 :                                 else if (aRealType == XA_STRING)
     812           0 :                                     m_aWMName = OUString( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_ISO_8859_1 );
     813             : 
     814           0 :                                 XFree( pProperty );
     815           0 :                                 pProperty = NULL;
     816             :                             }
     817           0 :                             else if( pProperty )
     818             :                             {
     819           0 :                                 XFree( pProperty );
     820           0 :                                 pProperty = NULL;
     821             :                             }
     822             : 
     823             :                             // if this is metacity, check for version to enable a legacy workaround
     824           0 :                             if( m_aWMName.equalsAscii( "Metacity" ) )
     825             :                             {
     826           0 :                                 int nVersionMajor = 0, nVersionMinor = 0;
     827           0 :                                 Atom nVersionAtom = XInternAtom( m_pDisplay, "_METACITY_VERSION", True );
     828           0 :                                 if( nVersionAtom )
     829             :                                 {
     830           0 :                                     if( XGetWindowProperty( m_pDisplay,
     831             :                                                             aWMChild,
     832             :                                                             nVersionAtom,
     833             :                                                             0, 256,
     834             :                                                             False,
     835             :                                                             m_aWMAtoms[ UTF8_STRING ],
     836             :                                                             &aRealType,
     837             :                                                             &nFormat,
     838             :                                                             &nItems,
     839             :                                                             &nBytesLeft,
     840           0 :                                                             &pProperty ) == 0
     841           0 :                                         && nItems != 0
     842             :                                         )
     843             :                                     {
     844           0 :                                         OUString aMetaVersion( (sal_Char*)pProperty, nItems, RTL_TEXTENCODING_UTF8 );
     845           0 :                                         nVersionMajor = aMetaVersion.getToken(0, '.').toInt32();
     846           0 :                                         nVersionMinor = aMetaVersion.getToken(1, '.').toInt32();
     847             :                                     }
     848           0 :                                     if( pProperty )
     849             :                                     {
     850           0 :                                         XFree( pProperty );
     851           0 :                                         pProperty = NULL;
     852             :                                     }
     853             :                                 }
     854           0 :                                 if( nVersionMajor < 2 || (nVersionMajor == 2 && nVersionMinor < 12) )
     855           0 :                                     m_bLegacyPartialFullscreen = true;
     856             :                             }
     857             :                         }
     858             :                     }
     859             :                     else
     860             :                     {
     861           0 :                         if( pProperty )
     862             :                         {
     863           0 :                             XFree( pProperty );
     864           0 :                             pProperty = NULL;
     865             :                         }
     866           0 :                         GetGenericData()->ErrorTrapPush();
     867             :                     }
     868             :                 }
     869             : 
     870           0 :             GetGenericData()->ErrorTrapPop();
     871             :         }
     872           0 :         else if( pProperty )
     873             :         {
     874           0 :             XFree( pProperty );
     875           0 :             pProperty = NULL;
     876             :         }
     877             :     }
     878           0 :     return bNetWM;
     879             : }
     880             : 
     881           0 : bool WMAdaptor::getWMshouldSwitchWorkspace() const
     882             : {
     883           0 :     if( ! m_bWMshouldSwitchWorkspaceInit )
     884             :     {
     885           0 :         WMAdaptor * pWMA = const_cast<WMAdaptor*>(this);
     886             : 
     887           0 :         pWMA->m_bWMshouldSwitchWorkspace = true;
     888           0 :         vcl::SettingsConfigItem* pItem = vcl::SettingsConfigItem::get();
     889             :         OUString aSetting( pItem->getValue( OUString( "WM" ),
     890           0 :                                                  OUString( "ShouldSwitchWorkspace" ) ) );
     891           0 :         if( aSetting.isEmpty() )
     892             :         {
     893           0 :             if( m_aWMName.equalsAscii( "awesome" ) )
     894             :             {
     895           0 :                 pWMA->m_bWMshouldSwitchWorkspace = false;
     896             :             }
     897             :         }
     898             :         else
     899           0 :             pWMA->m_bWMshouldSwitchWorkspace = aSetting.toBoolean();
     900           0 :         pWMA->m_bWMshouldSwitchWorkspaceInit = true;
     901             :     }
     902           0 :     return m_bWMshouldSwitchWorkspace;
     903             : }
     904             : 
     905             : /*
     906             :  *  WMAdaptor::isValid()
     907             :  */
     908           0 : bool WMAdaptor::isValid() const
     909             : {
     910           0 :     return true;
     911             : }
     912             : 
     913             : /*
     914             :  *  NetWMAdaptor::isValid()
     915             :  */
     916           0 : bool NetWMAdaptor::isValid() const
     917             : {
     918             :     // some necessary sanity checks; there are WMs out there
     919             :     // which implement some of the WM hints spec without
     920             :     // real functionality
     921             :     return
     922           0 :         m_aWMAtoms[ NET_SUPPORTED ]
     923           0 :         && m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ]
     924           0 :         && m_aWMAtoms[ NET_WM_NAME ]
     925           0 :         && m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ]
     926           0 :         && m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ]
     927             :         ;
     928             : }
     929             : 
     930             : /*
     931             :  *  GnomeWMAdaptor::isValid()
     932             :  */
     933           0 : bool GnomeWMAdaptor::isValid() const
     934             : {
     935           0 :     return m_bValid;
     936             : }
     937             : 
     938             : /*
     939             :  *  WMAdaptor::initAtoms
     940             :  */
     941             : 
     942           0 : void WMAdaptor::initAtoms()
     943             : {
     944             :     // get basic atoms
     945           0 :     for( unsigned int i = 0; i < SAL_N_ELEMENTS( aAtomTab ); i++ )
     946           0 :         m_aWMAtoms[ aAtomTab[i].nProtocol ] = XInternAtom( m_pDisplay, aAtomTab[i].pProtocol, False );
     947           0 :     m_aWMAtoms[ NET_SUPPORTING_WM_CHECK ]   = XInternAtom( m_pDisplay, "_NET_SUPPORTING_WM_CHECK", True );
     948           0 :     m_aWMAtoms[ NET_WM_NAME ]               = XInternAtom( m_pDisplay, "_NET_WM_NAME", True );
     949           0 : }
     950             : 
     951             : /*
     952             :  *  NetWMAdaptor::initAtoms
     953             :  */
     954             : 
     955           0 : void NetWMAdaptor::initAtoms()
     956             : {
     957           0 :     WMAdaptor::initAtoms();
     958             : 
     959           0 :     m_aWMAtoms[ NET_SUPPORTED ]             = XInternAtom( m_pDisplay, "_NET_SUPPORTED", True );
     960           0 : }
     961             : 
     962             : /*
     963             :  *  GnomeWMAdaptor::initAtoms
     964             :  */
     965             : 
     966           0 : void GnomeWMAdaptor::initAtoms()
     967             : {
     968           0 :     WMAdaptor::initAtoms();
     969             : 
     970           0 :     m_aWMAtoms[ WIN_PROTOCOLS ]             = XInternAtom( m_pDisplay, "_WIN_PROTOCOLS", True );
     971           0 :     m_aWMAtoms[ WIN_SUPPORTING_WM_CHECK ]   = XInternAtom( m_pDisplay, "_WIN_SUPPORTING_WM_CHECK", True );
     972           0 : }
     973             : 
     974             : /*
     975             :  *  WMAdaptor::setWMName
     976             :  *  sets WM_NAME
     977             :  *       WM_ICON_NAME
     978             :  */
     979             : 
     980           0 : void WMAdaptor::setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const
     981             : {
     982             :     OString aTitle(OUStringToOString(rWMName,
     983           0 :         osl_getThreadTextEncoding()));
     984             : 
     985           0 :     OString aWMLocale;
     986           0 :     rtl_Locale* pLocale = NULL;
     987           0 :     osl_getProcessLocale( &pLocale );
     988           0 :     if( pLocale )
     989             :     {
     990           0 :         OUString aLocaleString( LanguageTag( *pLocale).getGlibcLocaleString( OUString()));
     991           0 :         aWMLocale = OUStringToOString( aLocaleString, RTL_TEXTENCODING_ISO_8859_1 );
     992             :     }
     993             :     else
     994             :     {
     995           0 :         static const char* pLang = getenv( "LANG" );
     996           0 :         aWMLocale = pLang ? pLang : "C";
     997             :     }
     998             : 
     999             :     static bool bTrustXmb = true;
    1000             :     #ifdef SOLARIS
    1001             :     /* #i64273# there are some weird cases when using IIIMP on Solaris
    1002             :     *  where for unknown reasons XmbTextListToTextProperty results in
    1003             :     *  garbage. Test one string once to ensure safety.
    1004             :     *
    1005             :     *  FIXME: This must be a bug in xiiimp.so.2 somewhere. However
    1006             :     *  it was not possible to recreate this in a small sample program.
    1007             :     *  This reeks of memory corruption somehow.
    1008             :     */
    1009             :     static bool bOnce = true;
    1010             :     if( bOnce )
    1011             :     {
    1012             :         bOnce = false;
    1013             :         XTextProperty aTestProp = { NULL, None, 0, 0 };
    1014             :         const char *pText = "trustme";
    1015             :         char* pT = const_cast<char*>(pText);
    1016             :         XmbTextListToTextProperty( m_pDisplay,
    1017             :                                    &pT,
    1018             :                                    1,
    1019             :                                    XStdICCTextStyle,
    1020             :                                    &aTestProp );
    1021             :         bTrustXmb = (aTestProp.nitems == 7)                     &&
    1022             :                     (aTestProp.value != NULL )                  &&
    1023             :                     (strncmp( (char*)aTestProp.value, pText, 7 ) == 0) &&
    1024             :                     (aTestProp.encoding == XA_STRING);
    1025             :         if( aTestProp.value )
    1026             :             XFree( aTestProp.value );
    1027             :         #if OSL_DEBUG_LEVEL > 1
    1028             :         fprintf( stderr, "%s\n",
    1029             :                  bTrustXmb ?
    1030             :                  "XmbTextListToTextProperty seems to work" :
    1031             :                  "XmbTextListToTextProperty does not seem to work" );
    1032             :         #endif
    1033             :     }
    1034             :     #endif
    1035             : 
    1036           0 :     char* pT = const_cast<char*>(aTitle.getStr());
    1037           0 :     XTextProperty aProp = { NULL, None, 0, 0 };
    1038           0 :     if( bTrustXmb )
    1039             :     {
    1040             :         XmbTextListToTextProperty( m_pDisplay,
    1041             :                                    &pT,
    1042             :                                    1,
    1043             :                                    XStdICCTextStyle,
    1044           0 :                                    &aProp );
    1045             :     }
    1046             : 
    1047           0 :     unsigned char* pData = aProp.nitems ? aProp.value : (unsigned char*)aTitle.getStr();
    1048           0 :     Atom nType = aProp.nitems ? aProp.encoding : XA_STRING;
    1049           0 :     int nFormat = aProp.nitems ? aProp.format : 8;
    1050           0 :     int nBytes = aProp.nitems ? aProp.nitems : aTitle.getLength();
    1051           0 :     const SystemEnvData* pEnv = pFrame->GetSystemData();
    1052             :     XChangeProperty( m_pDisplay,
    1053             :                      (XLIB_Window)pEnv->aShellWindow,
    1054             :                      XA_WM_NAME,
    1055             :                      nType,
    1056             :                      nFormat,
    1057             :                      PropModeReplace,
    1058             :                      pData,
    1059           0 :                      nBytes );
    1060             :     XChangeProperty( m_pDisplay,
    1061             :                      (XLIB_Window)pEnv->aShellWindow,
    1062             :                      XA_WM_ICON_NAME,
    1063             :                      nType,
    1064             :                      nFormat,
    1065             :                      PropModeReplace,
    1066             :                      pData,
    1067           0 :                      nBytes );
    1068             :     XChangeProperty( m_pDisplay,
    1069             :                      (XLIB_Window)pEnv->aShellWindow,
    1070           0 :                      m_aWMAtoms[ WM_LOCALE_NAME ],
    1071             :                      XA_STRING,
    1072             :                      8,
    1073             :                      PropModeReplace,
    1074           0 :                      (unsigned char*)aWMLocale.getStr(),
    1075           0 :                      aWMLocale.getLength() );
    1076           0 :     if (aProp.value != NULL)
    1077           0 :         XFree( aProp.value );
    1078           0 : }
    1079             : 
    1080             : /*
    1081             :  *  NetWMAdaptor::setWMName
    1082             :  *  sets WM_NAME
    1083             :  *       _NET_WM_NAME
    1084             :  *       WM_ICON_NAME
    1085             :  *       _NET_WM_ICON_NAME
    1086             :  */
    1087           0 : void NetWMAdaptor::setWMName( X11SalFrame* pFrame, const OUString& rWMName ) const
    1088             : {
    1089           0 :     WMAdaptor::setWMName( pFrame, rWMName );
    1090             : 
    1091           0 :     OString aTitle(OUStringToOString(rWMName, RTL_TEXTENCODING_UTF8));
    1092           0 :     const SystemEnvData* pEnv = pFrame->GetSystemData();
    1093           0 :     if( m_aWMAtoms[ NET_WM_NAME ] )
    1094             :         XChangeProperty( m_pDisplay,
    1095             :                          (XLIB_Window)pEnv->aShellWindow,
    1096           0 :                          m_aWMAtoms[ NET_WM_NAME ],
    1097           0 :                          m_aWMAtoms[ UTF8_STRING ],
    1098             :                          8,
    1099             :                          PropModeReplace,
    1100           0 :                          (unsigned char*)aTitle.getStr(),
    1101           0 :                          aTitle.getLength() );
    1102           0 :     if( m_aWMAtoms[ NET_WM_ICON_NAME ] )
    1103             :         XChangeProperty( m_pDisplay,
    1104             :                          (XLIB_Window)pEnv->aShellWindow,
    1105           0 :                          m_aWMAtoms[ NET_WM_ICON_NAME ],
    1106           0 :                          m_aWMAtoms[ UTF8_STRING ],
    1107             :                          8,
    1108             :                          PropModeReplace,
    1109           0 :                          (unsigned char*)aTitle.getStr(),
    1110           0 :                          aTitle.getLength() );
    1111           0 : }
    1112             : 
    1113             : /*
    1114             :  *  NetWMAdaptor::setNetWMState
    1115             :  *  sets _NET_WM_STATE
    1116             :  */
    1117           0 : void NetWMAdaptor::setNetWMState( X11SalFrame* pFrame ) const
    1118             : {
    1119           0 :     if( m_aWMAtoms[ NET_WM_STATE ] )
    1120             :     {
    1121             :         Atom aStateAtoms[ 10 ];
    1122           0 :         int nStateAtoms = 0;
    1123             : 
    1124             :         // set NET_WM_STATE_MODAL
    1125           0 :         if( m_aWMAtoms[ NET_WM_STATE_MODAL ]
    1126           0 :             && pFrame->meWindowType == windowType_ModalDialogue )
    1127             :         {
    1128           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MODAL ];
    1129             :             /*
    1130             :              *  #90998# NET_WM_STATE_SKIP_TASKBAR set on a frame will
    1131             :              *  cause kwin not to give it the focus on map request
    1132             :              *  this seems to be a bug in kwin
    1133             :              *  aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ];
    1134             :              */
    1135             :         }
    1136           0 :         if( pFrame->mbMaximizedVert
    1137           0 :             && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] )
    1138           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ];
    1139           0 :         if( pFrame->mbMaximizedHorz
    1140           0 :             && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] )
    1141           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ];
    1142           0 :         if( pFrame->bAlwaysOnTop_ && m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ] )
    1143           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ];
    1144           0 :         if( pFrame->mbShaded && m_aWMAtoms[ NET_WM_STATE_SHADED ] )
    1145           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SHADED ];
    1146           0 :         if( pFrame->mbFullScreen && m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] )
    1147           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ];
    1148           0 :         if( pFrame->meWindowType == windowType_Utility && m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ] )
    1149           0 :             aStateAtoms[ nStateAtoms++ ] = m_aWMAtoms[ NET_WM_STATE_SKIP_TASKBAR ];
    1150             : 
    1151           0 :         if( nStateAtoms )
    1152             :         {
    1153             :             XChangeProperty( m_pDisplay,
    1154             :                              pFrame->GetShellWindow(),
    1155           0 :                              m_aWMAtoms[ NET_WM_STATE ],
    1156             :                              XA_ATOM,
    1157             :                              32,
    1158             :                              PropModeReplace,
    1159             :                              (unsigned char*)aStateAtoms,
    1160             :                              nStateAtoms
    1161           0 :                              );
    1162             :         }
    1163             :         else
    1164             :             XDeleteProperty( m_pDisplay,
    1165             :                              pFrame->GetShellWindow(),
    1166           0 :                              m_aWMAtoms[ NET_WM_STATE ] );
    1167           0 :         if( pFrame->mbMaximizedHorz
    1168           0 :            && pFrame->mbMaximizedVert
    1169           0 :            && ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
    1170             :         {
    1171             :             /*
    1172             :              *  for maximizing use NorthWestGravity (including decoration)
    1173             :              */
    1174             :             XSizeHints  hints;
    1175             :             long        supplied;
    1176           0 :             bool bHint = false;
    1177           0 :             if( XGetWMNormalHints( m_pDisplay,
    1178             :                                    pFrame->GetShellWindow(),
    1179             :                                    &hints,
    1180           0 :                                    &supplied ) )
    1181             :             {
    1182           0 :                 bHint = true;
    1183           0 :                 hints.flags |= PWinGravity;
    1184           0 :                 hints.win_gravity = NorthWestGravity;
    1185             :                 XSetWMNormalHints( m_pDisplay,
    1186             :                                    pFrame->GetShellWindow(),
    1187           0 :                                    &hints );
    1188           0 :                 XSync( m_pDisplay, False );
    1189             :             }
    1190             : 
    1191             :             // SetPosSize necessary to set width/height, min/max w/h
    1192           0 :             sal_Int32 nCurrent = 0;
    1193             :             /*
    1194             :              *  get current desktop here if work areas have different size
    1195             :              *  (does this happen on any platform ?)
    1196             :              */
    1197           0 :             if( ! m_bEqualWorkAreas )
    1198             :             {
    1199           0 :                 nCurrent = getCurrentWorkArea();
    1200           0 :                 if( nCurrent < 0 )
    1201           0 :                     nCurrent = 0;
    1202             :             }
    1203           0 :             Rectangle aPosSize = m_aWMWorkAreas[nCurrent];
    1204           0 :             const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
    1205           0 :             aPosSize = Rectangle( Point( aPosSize.Left() + rGeom.nLeftDecoration,
    1206           0 :                                          aPosSize.Top()  + rGeom.nTopDecoration ),
    1207           0 :                                   Size( aPosSize.GetWidth()
    1208           0 :                                         - rGeom.nLeftDecoration
    1209           0 :                                         - rGeom.nRightDecoration,
    1210           0 :                                         aPosSize.GetHeight()
    1211           0 :                                         - rGeom.nTopDecoration
    1212           0 :                                         - rGeom.nBottomDecoration )
    1213           0 :                                   );
    1214           0 :             pFrame->SetPosSize( aPosSize );
    1215             : 
    1216             :             /*
    1217             :              *  reset gravity hint to static gravity
    1218             :              *  (this should not move window according to ICCCM)
    1219             :              */
    1220           0 :             if( bHint && pFrame->nShowState_ != SHOWSTATE_UNKNOWN )
    1221             :             {
    1222           0 :                 hints.win_gravity = StaticGravity;
    1223             :                 XSetWMNormalHints( m_pDisplay,
    1224             :                                    pFrame->GetShellWindow(),
    1225           0 :                                    &hints );
    1226             :             }
    1227             :         }
    1228             :     }
    1229           0 : }
    1230             : 
    1231             : /*
    1232             :  *  GnomeWMAdaptor::setNetWMState
    1233             :  *  sets _WIN_STATE
    1234             :  */
    1235           0 : void GnomeWMAdaptor::setGnomeWMState( X11SalFrame* pFrame ) const
    1236             : {
    1237           0 :     if( m_aWMAtoms[ WIN_STATE ] )
    1238             :     {
    1239           0 :         sal_uInt32 nWinWMState = 0;
    1240             : 
    1241           0 :         if( pFrame->mbMaximizedVert )
    1242           0 :             nWinWMState |= 1 << 2;
    1243           0 :         if( pFrame->mbMaximizedHorz )
    1244           0 :             nWinWMState |= 1 << 3;
    1245           0 :         if( pFrame->mbShaded )
    1246           0 :             nWinWMState |= 1 << 5;
    1247             : 
    1248             :         XChangeProperty( m_pDisplay,
    1249             :                          pFrame->GetShellWindow(),
    1250           0 :                          m_aWMAtoms[ WIN_STATE ],
    1251             :                          XA_CARDINAL,
    1252             :                          32,
    1253             :                          PropModeReplace,
    1254             :                          (unsigned char*)&nWinWMState,
    1255             :                          1
    1256           0 :                          );
    1257           0 :         if( pFrame->mbMaximizedHorz
    1258           0 :            && pFrame->mbMaximizedVert
    1259           0 :            && ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
    1260             :         {
    1261             :             /*
    1262             :              *  for maximizing use NorthWestGravity (including decoration)
    1263             :              */
    1264             :             XSizeHints  hints;
    1265             :             long        supplied;
    1266           0 :             bool bHint = false;
    1267           0 :             if( XGetWMNormalHints( m_pDisplay,
    1268             :                                    pFrame->GetShellWindow(),
    1269             :                                    &hints,
    1270           0 :                                    &supplied ) )
    1271             :             {
    1272           0 :                 bHint = true;
    1273           0 :                 hints.flags |= PWinGravity;
    1274           0 :                 hints.win_gravity = NorthWestGravity;
    1275             :                 XSetWMNormalHints( m_pDisplay,
    1276             :                                    pFrame->GetShellWindow(),
    1277           0 :                                    &hints );
    1278           0 :                 XSync( m_pDisplay, False );
    1279             :             }
    1280             : 
    1281             :             // SetPosSize necessary to set width/height, min/max w/h
    1282           0 :             sal_Int32 nCurrent = 0;
    1283             :             /*
    1284             :              *  get current desktop here if work areas have different size
    1285             :              *  (does this happen on any platform ?)
    1286             :              */
    1287           0 :             if( ! m_bEqualWorkAreas )
    1288             :             {
    1289           0 :                 nCurrent = getCurrentWorkArea();
    1290           0 :                 if( nCurrent < 0 )
    1291           0 :                     nCurrent = 0;
    1292             :             }
    1293           0 :             Rectangle aPosSize = m_aWMWorkAreas[nCurrent];
    1294           0 :             const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
    1295           0 :             aPosSize = Rectangle( Point( aPosSize.Left() + rGeom.nLeftDecoration,
    1296           0 :                                          aPosSize.Top()  + rGeom.nTopDecoration ),
    1297           0 :                                   Size( aPosSize.GetWidth()
    1298           0 :                                         - rGeom.nLeftDecoration
    1299           0 :                                         - rGeom.nRightDecoration,
    1300           0 :                                         aPosSize.GetHeight()
    1301           0 :                                         - rGeom.nTopDecoration
    1302           0 :                                         - rGeom.nBottomDecoration )
    1303           0 :                                   );
    1304           0 :             pFrame->SetPosSize( aPosSize );
    1305             : 
    1306             :             /*
    1307             :              *  reset gravity hint to static gravity
    1308             :              *  (this should not move window according to ICCCM)
    1309             :              */
    1310           0 :             if( bHint && pFrame->nShowState_ != SHOWSTATE_UNKNOWN )
    1311             :             {
    1312           0 :                 hints.win_gravity = StaticGravity;
    1313             :                 XSetWMNormalHints( m_pDisplay,
    1314             :                                    pFrame->GetShellWindow(),
    1315           0 :                                    &hints );
    1316             :             }
    1317             :         }
    1318             :     }
    1319           0 : }
    1320             : 
    1321             : /*
    1322             :  *  WMAdaptor::setFrameDecoration
    1323             :  *  sets _MOTIF_WM_HINTS
    1324             :  *       WM_TRANSIENT_FOR
    1325             :  */
    1326             : 
    1327           0 : void WMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pReferenceFrame ) const
    1328             : {
    1329           0 :     pFrame->meWindowType        = eType;
    1330           0 :     pFrame->mnDecorationFlags   = nDecorationFlags;
    1331             : 
    1332           0 :     if( ! pFrame->mbFullScreen )
    1333             :     {
    1334             :         // set mwm hints
    1335             :         struct _mwmhints {
    1336             :             unsigned long flags, func, deco;
    1337             :             long input_mode;
    1338             :             unsigned long status;
    1339             :         } aHint;
    1340             : 
    1341           0 :         aHint.flags = 15; /* flags for functions, decoration, input mode and status */
    1342           0 :         aHint.deco = 0;
    1343           0 :         aHint.func = 1L << 2;
    1344           0 :         aHint.status = 0;
    1345           0 :         aHint.input_mode = 0;
    1346             : 
    1347             :         // evaluate decoration flags
    1348           0 :         if( nDecorationFlags & decoration_All )
    1349           0 :             aHint.deco = 1, aHint.func = 1;
    1350             :         else
    1351             :         {
    1352           0 :             if( nDecorationFlags & decoration_Title )
    1353           0 :                 aHint.deco |= 1L << 3;
    1354           0 :             if( nDecorationFlags & decoration_Border )
    1355           0 :                 aHint.deco |= 1L << 1;
    1356           0 :             if( nDecorationFlags & decoration_Resize )
    1357           0 :                 aHint.deco |= 1L << 2, aHint.func |= 1L << 1;
    1358           0 :             if( nDecorationFlags & decoration_MinimizeBtn )
    1359           0 :                 aHint.deco |= 1L << 5, aHint.func |= 1L << 3;
    1360           0 :             if( nDecorationFlags & decoration_MaximizeBtn )
    1361           0 :                 aHint.deco |= 1L << 6, aHint.func |= 1L << 4;
    1362           0 :             if( nDecorationFlags & decoration_CloseBtn )
    1363           0 :                 aHint.deco |= 1L << 4, aHint.func |= 1L << 5;
    1364             :         }
    1365             :         // evaluate window type
    1366           0 :         switch( eType )
    1367             :         {
    1368             :             case windowType_ModalDialogue:
    1369           0 :                 aHint.input_mode = 1;
    1370           0 :                 break;
    1371             :             default:
    1372           0 :                 break;
    1373             :         }
    1374             : 
    1375             :         // set the hint
    1376             :         XChangeProperty( m_pDisplay,
    1377             :                          pFrame->GetShellWindow(),
    1378           0 :                          m_aWMAtoms[ MOTIF_WM_HINTS ],
    1379           0 :                          m_aWMAtoms[ MOTIF_WM_HINTS ],
    1380             :                          32,
    1381             :                          PropModeReplace,
    1382             :                          (unsigned char*)&aHint,
    1383           0 :                          5 );
    1384             :     }
    1385             : 
    1386             :     // set transientFor hint
    1387             :     /*  #91030# dtwm will not map a dialogue if the transient
    1388             :      *  window is iconified. This is deemed undesireable because
    1389             :      *  message boxes do not get mapped, so use the root as transient
    1390             :      *  instead.
    1391             :      */
    1392           0 :     if( pReferenceFrame )
    1393             :     {
    1394             :         XSetTransientForHint( m_pDisplay,
    1395             :                               pFrame->GetShellWindow(),
    1396             :                               pReferenceFrame->bMapped_ ?
    1397             :                               pReferenceFrame->GetShellWindow() :
    1398           0 :                               m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() )
    1399           0 :                               );
    1400           0 :         if( ! pReferenceFrame->bMapped_ )
    1401           0 :             pFrame->mbTransientForRoot = true;
    1402             :     }
    1403           0 : }
    1404             : 
    1405             : /*
    1406             :  *  NetWMAdaptor::setFrameDecoration
    1407             :  *  sets _MOTIF_WM_HINTS
    1408             :  *       _NET_WM_WINDOW_TYPE
    1409             :  *       _NET_WM_STATE
    1410             :  *       WM_TRANSIENT_FOR
    1411             :  */
    1412             : 
    1413           0 : void NetWMAdaptor::setFrameTypeAndDecoration( X11SalFrame* pFrame, WMWindowType eType, int nDecorationFlags, X11SalFrame* pReferenceFrame ) const
    1414             : {
    1415           0 :     WMAdaptor::setFrameTypeAndDecoration( pFrame, eType, nDecorationFlags, pReferenceFrame );
    1416             : 
    1417           0 :     setNetWMState( pFrame );
    1418             : 
    1419             :     // set NET_WM_WINDOW_TYPE
    1420           0 :     if( m_aWMAtoms[ NET_WM_WINDOW_TYPE ] )
    1421             :     {
    1422             :         Atom aWindowTypes[4];
    1423           0 :         int nWindowTypes = 0;
    1424           0 :         switch( eType )
    1425             :         {
    1426             :             case windowType_Utility:
    1427           0 :                 aWindowTypes[nWindowTypes++] =
    1428           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_UTILITY ] ?
    1429             :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_UTILITY ] :
    1430           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ];
    1431           0 :                 break;
    1432             :             case windowType_ModelessDialogue:
    1433             :             case windowType_ModalDialogue:
    1434           0 :                 aWindowTypes[nWindowTypes++] =
    1435           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_DIALOG ];
    1436           0 :                 break;
    1437             :             case windowType_Splash:
    1438           0 :                 aWindowTypes[nWindowTypes++] =
    1439           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_SPLASH ] ?
    1440             :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_SPLASH ] :
    1441           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ];
    1442           0 :                 break;
    1443             :             case windowType_Toolbar:
    1444           0 :                 if( m_aWMAtoms[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE ] )
    1445           0 :                     aWindowTypes[nWindowTypes++] = m_aWMAtoms[ KDE_NET_WM_WINDOW_TYPE_OVERRIDE ];
    1446           0 :                 aWindowTypes[nWindowTypes++] =
    1447           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_TOOLBAR ] ?
    1448             :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_TOOLBAR ] :
    1449           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL];
    1450           0 :                 break;
    1451             :             case windowType_Dock:
    1452           0 :                 aWindowTypes[nWindowTypes++] =
    1453           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_DOCK ] ?
    1454             :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_DOCK ] :
    1455           0 :                     m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL];
    1456           0 :                 break;
    1457             :             default:
    1458           0 :                 aWindowTypes[nWindowTypes++] = m_aWMAtoms[ NET_WM_WINDOW_TYPE_NORMAL ];
    1459           0 :                 break;
    1460             :         }
    1461             :         XChangeProperty( m_pDisplay,
    1462             :                          pFrame->GetShellWindow(),
    1463           0 :                          m_aWMAtoms[ NET_WM_WINDOW_TYPE ],
    1464             :                          XA_ATOM,
    1465             :                          32,
    1466             :                          PropModeReplace,
    1467             :                          (unsigned char*)aWindowTypes,
    1468           0 :                          nWindowTypes );
    1469             :     }
    1470           0 :     if( ( eType == windowType_ModalDialogue ||
    1471             :           eType == windowType_ModelessDialogue )
    1472           0 :         && ! pReferenceFrame )
    1473             :     {
    1474             :         XSetTransientForHint( m_pDisplay,
    1475             :                               pFrame->GetShellWindow(),
    1476           0 :                               m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ) );
    1477           0 :         pFrame->mbTransientForRoot = true;
    1478             :     }
    1479           0 : }
    1480             : 
    1481             : /*
    1482             :  *  WMAdaptor::maximizeFrame
    1483             :  */
    1484             : 
    1485           0 : void WMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
    1486             : {
    1487           0 :     pFrame->mbMaximizedVert = bVertical;
    1488           0 :     pFrame->mbMaximizedHorz = bHorizontal;
    1489             : 
    1490           0 :     const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
    1491             : 
    1492             :     // discard pending configure notifies for this frame
    1493           0 :     XSync( m_pDisplay, False );
    1494             :     XEvent aDiscard;
    1495           0 :     while( XCheckTypedWindowEvent( m_pDisplay,
    1496             :                                    pFrame->GetShellWindow(),
    1497             :                                    ConfigureNotify,
    1498           0 :                                    &aDiscard ) )
    1499             :         ;
    1500           0 :     while( XCheckTypedWindowEvent( m_pDisplay,
    1501             :                                    pFrame->GetWindow(),
    1502             :                                    ConfigureNotify,
    1503           0 :                                    &aDiscard ) )
    1504             :         ;
    1505             : 
    1506           0 :     if( bHorizontal || bVertical )
    1507             :     {
    1508           0 :         Size aScreenSize( m_pSalDisplay->GetScreenSize( pFrame->GetScreenNumber() ) );
    1509           0 :         Point aTL( rGeom.nLeftDecoration, rGeom.nTopDecoration );
    1510           0 :         if( m_pSalDisplay->IsXinerama() )
    1511             :         {
    1512           0 :             Point aMed( aTL.X() + rGeom.nWidth/2, aTL.Y() + rGeom.nHeight/2 );
    1513           0 :             const std::vector< Rectangle >& rScreens = m_pSalDisplay->GetXineramaScreens();
    1514           0 :             for( unsigned int i = 0; i < rScreens.size(); i++ )
    1515           0 :                 if( rScreens[i].IsInside( aMed ) )
    1516             :                 {
    1517           0 :                     aTL += rScreens[i].TopLeft();
    1518           0 :                     aScreenSize = rScreens[i].GetSize();
    1519           0 :                     break;
    1520             :                 }
    1521             :         }
    1522             :         Rectangle aTarget( aTL,
    1523           0 :                            Size( aScreenSize.Width() - rGeom.nLeftDecoration - rGeom.nTopDecoration,
    1524           0 :                                  aScreenSize.Height() - rGeom.nTopDecoration - rGeom.nBottomDecoration )
    1525           0 :                            );
    1526           0 :         if( ! bHorizontal )
    1527             :         {
    1528             :             aTarget.SetSize(
    1529             :                             Size(
    1530           0 :                                  pFrame->maRestorePosSize.IsEmpty() ?
    1531           0 :                                  rGeom.nWidth : pFrame->maRestorePosSize.GetWidth(),
    1532             :                                  aTarget.GetHeight()
    1533             :                                  )
    1534           0 :                             );
    1535           0 :             aTarget.Left() =
    1536           0 :                 pFrame->maRestorePosSize.IsEmpty() ?
    1537           0 :                 rGeom.nX : pFrame->maRestorePosSize.Left();
    1538             :         }
    1539           0 :         else if( ! bVertical )
    1540             :         {
    1541             :             aTarget.SetSize(
    1542             :                             Size(
    1543             :                                  aTarget.GetWidth(),
    1544           0 :                                  pFrame->maRestorePosSize.IsEmpty() ?
    1545           0 :                                  rGeom.nHeight : pFrame->maRestorePosSize.GetHeight()
    1546             :                                  )
    1547           0 :                             );
    1548           0 :             aTarget.Top() =
    1549           0 :                 pFrame->maRestorePosSize.IsEmpty() ?
    1550           0 :                 rGeom.nY : pFrame->maRestorePosSize.Top();
    1551             :         }
    1552             : 
    1553           0 :         Rectangle aRestore( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
    1554           0 :         if( pFrame->bMapped_ )
    1555             :         {
    1556             :             XSetInputFocus( m_pDisplay,
    1557             :                             pFrame->GetShellWindow(),
    1558             :                             RevertToNone,
    1559             :                             CurrentTime
    1560           0 :                             );
    1561             :         }
    1562             : 
    1563           0 :         if( pFrame->maRestorePosSize.IsEmpty() )
    1564           0 :             pFrame->maRestorePosSize = aRestore;
    1565             : 
    1566           0 :         pFrame->SetPosSize( aTarget );
    1567           0 :         pFrame->nWidth_     = aTarget.GetWidth();
    1568           0 :         pFrame->nHeight_    = aTarget.GetHeight();
    1569             :         XRaiseWindow( m_pDisplay,
    1570             :                       pFrame->GetShellWindow()
    1571           0 :                       );
    1572           0 :         if( pFrame->GetStackingWindow() )
    1573             :             XRaiseWindow( m_pDisplay,
    1574             :                           pFrame->GetStackingWindow()
    1575           0 :                           );
    1576             : 
    1577             :     }
    1578             :     else
    1579             :     {
    1580           0 :         pFrame->SetPosSize( pFrame->maRestorePosSize );
    1581           0 :         pFrame->maRestorePosSize = Rectangle();
    1582           0 :         pFrame->nWidth_             = rGeom.nWidth;
    1583           0 :         pFrame->nHeight_            = rGeom.nHeight;
    1584             :     }
    1585           0 : }
    1586             : 
    1587             : /*
    1588             :  *  NetWMAdaptor::maximizeFrame
    1589             :  *  changes _NET_WM_STATE by sending a client message
    1590             :  */
    1591             : 
    1592           0 : void NetWMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
    1593             : {
    1594           0 :     pFrame->mbMaximizedVert = bVertical;
    1595           0 :     pFrame->mbMaximizedHorz = bHorizontal;
    1596             : 
    1597           0 :     if( m_aWMAtoms[ NET_WM_STATE ]
    1598           0 :         && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ]
    1599           0 :         && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ]
    1600           0 :         && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
    1601             :         )
    1602             :     {
    1603           0 :         if( pFrame->bMapped_ )
    1604             :         {
    1605             :             // window already mapped, send WM a message
    1606             :             XEvent aEvent;
    1607           0 :             aEvent.type                 = ClientMessage;
    1608           0 :             aEvent.xclient.display      = m_pDisplay;
    1609           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    1610           0 :             aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
    1611           0 :             aEvent.xclient.format       = 32;
    1612           0 :             aEvent.xclient.data.l[0]    = bHorizontal ? 1 : 0;
    1613           0 :             aEvent.xclient.data.l[1]    = m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ];
    1614           0 :             aEvent.xclient.data.l[2]    = bHorizontal == bVertical ? m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] : 0;
    1615           0 :             aEvent.xclient.data.l[3]    = 0;
    1616           0 :             aEvent.xclient.data.l[4]    = 0;
    1617             :             XSendEvent( m_pDisplay,
    1618             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    1619             :                         False,
    1620             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    1621             :                         &aEvent
    1622           0 :                         );
    1623           0 :             if( bHorizontal != bVertical )
    1624             :             {
    1625           0 :                 aEvent.xclient.data.l[0]= bVertical ? 1 : 0;
    1626           0 :                 aEvent.xclient.data.l[1]= m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ];
    1627           0 :                 aEvent.xclient.data.l[2]= 0;
    1628             :                 XSendEvent( m_pDisplay,
    1629             :                             m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    1630             :                             False,
    1631             :                             SubstructureNotifyMask | SubstructureRedirectMask,
    1632             :                             &aEvent
    1633           0 :                             );
    1634             :             }
    1635             :         }
    1636             :         else
    1637             :         {
    1638             :             // window not mapped yet, set _NET_WM_STATE directly
    1639           0 :             setNetWMState( pFrame );
    1640             :         }
    1641           0 :         if( !bHorizontal && !bVertical )
    1642           0 :             pFrame->maRestorePosSize = Rectangle();
    1643           0 :         else if( pFrame->maRestorePosSize.IsEmpty() )
    1644             :         {
    1645           0 :             const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
    1646             :             pFrame->maRestorePosSize =
    1647           0 :                 Rectangle( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
    1648           0 :         }
    1649             :     }
    1650             :     else
    1651           0 :         WMAdaptor::maximizeFrame( pFrame, bHorizontal, bVertical );
    1652           0 : }
    1653             : 
    1654             : /*
    1655             :  *  GnomeWMAdaptor::maximizeFrame
    1656             :  *  changes _WIN_STATE by sending a client message
    1657             :  */
    1658             : 
    1659           0 : void GnomeWMAdaptor::maximizeFrame( X11SalFrame* pFrame, bool bHorizontal, bool bVertical ) const
    1660             : {
    1661           0 :     pFrame->mbMaximizedVert = bVertical;
    1662           0 :     pFrame->mbMaximizedHorz = bHorizontal;
    1663             : 
    1664           0 :     if( m_aWMAtoms[ WIN_STATE ]
    1665           0 :         && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
    1666             :         )
    1667             :     {
    1668           0 :         if( pFrame->bMapped_ )
    1669             :         {
    1670             :              // window already mapped, send WM a message
    1671             :             XEvent aEvent;
    1672           0 :             aEvent.type                 = ClientMessage;
    1673           0 :             aEvent.xclient.display      = m_pDisplay;
    1674           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    1675           0 :             aEvent.xclient.message_type = m_aWMAtoms[ WIN_STATE ];
    1676           0 :             aEvent.xclient.format       = 32;
    1677           0 :             aEvent.xclient.data.l[0]    = (1<<2)|(1<<3);
    1678             :             aEvent.xclient.data.l[1]    =
    1679             :                 (bVertical ? (1<<2) : 0)
    1680           0 :                 | (bHorizontal ? (1<<3) : 0);
    1681           0 :             aEvent.xclient.data.l[2]    = 0;
    1682           0 :             aEvent.xclient.data.l[3]    = 0;
    1683           0 :             aEvent.xclient.data.l[4]    = 0;
    1684             :             XSendEvent( m_pDisplay,
    1685             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    1686             :                         False,
    1687             :                         SubstructureNotifyMask,
    1688             :                         &aEvent
    1689           0 :                         );
    1690             :         }
    1691             :         else
    1692             :             // window not mapped yet, set _WIN_STATE directly
    1693           0 :             setGnomeWMState( pFrame );
    1694             : 
    1695           0 :         if( !bHorizontal && !bVertical )
    1696           0 :             pFrame->maRestorePosSize = Rectangle();
    1697           0 :         else if( pFrame->maRestorePosSize.IsEmpty() )
    1698             :         {
    1699           0 :             const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
    1700             :             pFrame->maRestorePosSize =
    1701           0 :                 Rectangle( Point( rGeom.nX, rGeom.nY ), Size( rGeom.nWidth, rGeom.nHeight ) );
    1702           0 :         }
    1703             :     }
    1704             :     else
    1705           0 :         WMAdaptor::maximizeFrame( pFrame, bHorizontal, bVertical );
    1706           0 : }
    1707             : 
    1708             : /*
    1709             :  *  WMAdaptor::enableAlwaysOnTop
    1710             :  */
    1711           0 : void WMAdaptor::enableAlwaysOnTop( X11SalFrame*, bool /*bEnable*/ ) const
    1712             : {
    1713           0 : }
    1714             : 
    1715             : /*
    1716             :  *  NetWMAdaptor::enableAlwaysOnTop
    1717             :  */
    1718           0 : void NetWMAdaptor::enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const
    1719             : {
    1720           0 :     pFrame->bAlwaysOnTop_ = bEnable;
    1721           0 :     if( m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ] )
    1722             :     {
    1723           0 :         if( pFrame->bMapped_ )
    1724             :         {
    1725             :             // window already mapped, send WM a message
    1726             :             XEvent aEvent;
    1727           0 :             aEvent.type                 = ClientMessage;
    1728           0 :             aEvent.xclient.display      = m_pDisplay;
    1729           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    1730           0 :             aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
    1731           0 :             aEvent.xclient.format       = 32;
    1732           0 :             aEvent.xclient.data.l[0]    = bEnable ? 1 : 0;
    1733           0 :             aEvent.xclient.data.l[1]    = m_aWMAtoms[ NET_WM_STATE_STAYS_ON_TOP ];
    1734           0 :             aEvent.xclient.data.l[2]    = 0;
    1735           0 :             aEvent.xclient.data.l[3]    = 0;
    1736           0 :             aEvent.xclient.data.l[4]    = 0;
    1737             :             XSendEvent( m_pDisplay,
    1738             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    1739             :                         False,
    1740             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    1741             :                         &aEvent
    1742           0 :                         );
    1743             :         }
    1744             :         else
    1745           0 :             setNetWMState( pFrame );
    1746             :     }
    1747           0 : }
    1748             : 
    1749             : /*
    1750             :  *  GnomeWMAdaptor::enableAlwaysOnTop
    1751             :  */
    1752           0 : void GnomeWMAdaptor::enableAlwaysOnTop( X11SalFrame* pFrame, bool bEnable ) const
    1753             : {
    1754           0 :     pFrame->bAlwaysOnTop_ = bEnable;
    1755           0 :     if( m_aWMAtoms[ WIN_LAYER ] )
    1756             :     {
    1757           0 :         if( pFrame->bMapped_ )
    1758             :         {
    1759             :             // window already mapped, send WM a message
    1760             :             XEvent aEvent;
    1761           0 :             aEvent.type                 = ClientMessage;
    1762           0 :             aEvent.xclient.display      = m_pDisplay;
    1763           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    1764           0 :             aEvent.xclient.message_type = m_aWMAtoms[ WIN_LAYER ];
    1765           0 :             aEvent.xclient.format       = 32;
    1766           0 :             aEvent.xclient.data.l[0]    = bEnable ? 6 : 4;
    1767           0 :             aEvent.xclient.data.l[1]    = 0;
    1768           0 :             aEvent.xclient.data.l[2]    = 0;
    1769           0 :             aEvent.xclient.data.l[3]    = 0;
    1770           0 :             aEvent.xclient.data.l[4]    = 0;
    1771             :             XSendEvent( m_pDisplay,
    1772             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    1773             :                         False,
    1774             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    1775             :                         &aEvent
    1776           0 :                         );
    1777             :         }
    1778             :         else
    1779             :         {
    1780           0 :             sal_uInt32 nNewLayer = bEnable ? 6 : 4;
    1781             :             XChangeProperty( m_pDisplay,
    1782             :                              pFrame->GetShellWindow(),
    1783           0 :                              m_aWMAtoms[ WIN_LAYER ],
    1784             :                              XA_CARDINAL,
    1785             :                              32,
    1786             :                              PropModeReplace,
    1787             :                              (unsigned char*)&nNewLayer,
    1788             :                              1
    1789           0 :                              );
    1790             :         }
    1791             :     }
    1792           0 : }
    1793             : 
    1794             : /*
    1795             :  *  WMAdaptor::changeReferenceFrame
    1796             :  */
    1797           0 : void WMAdaptor::changeReferenceFrame( X11SalFrame* pFrame, X11SalFrame* pReferenceFrame ) const
    1798             : {
    1799           0 :     if( ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG )
    1800           0 :         && ! pFrame->IsOverrideRedirect()
    1801           0 :         && ! pFrame->IsFloatGrabWindow()
    1802             :         )
    1803             :     {
    1804           0 :         XLIB_Window aTransient = pFrame->pDisplay_->GetRootWindow( pFrame->GetScreenNumber() );
    1805           0 :         pFrame->mbTransientForRoot = true;
    1806           0 :         if( pReferenceFrame )
    1807             :         {
    1808           0 :             aTransient = pReferenceFrame->GetShellWindow();
    1809           0 :             pFrame->mbTransientForRoot = false;
    1810             :         }
    1811             :         XSetTransientForHint( m_pDisplay,
    1812             :                               pFrame->GetShellWindow(),
    1813           0 :                               aTransient );
    1814             :     }
    1815           0 : }
    1816             : 
    1817             : /*
    1818             :  *  WMAdaptor::handlePropertyNotify
    1819             :  */
    1820           0 : int WMAdaptor::handlePropertyNotify( X11SalFrame*, XPropertyEvent* ) const
    1821             : {
    1822           0 :     return 0;
    1823             : }
    1824             : 
    1825             : /*
    1826             :  *  NetWMAdaptor::handlePropertyNotify
    1827             :  */
    1828           0 : int NetWMAdaptor::handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const
    1829             : {
    1830           0 :     int nHandled = 1;
    1831           0 :     if( pEvent->atom == m_aWMAtoms[ NET_WM_STATE ] )
    1832             :     {
    1833           0 :         pFrame->mbMaximizedHorz = pFrame->mbMaximizedVert = false;
    1834           0 :         pFrame->mbShaded = false;
    1835             : 
    1836           0 :         if( pEvent->state == PropertyNewValue )
    1837             :         {
    1838             :             Atom nType, *pStates;
    1839             :             int nFormat;
    1840             :             unsigned long nItems, nBytesLeft;
    1841           0 :             unsigned char* pData = NULL;
    1842           0 :             long nOffset = 0;
    1843           0 :             do
    1844             :             {
    1845             :                 XGetWindowProperty( m_pDisplay,
    1846             :                                     pEvent->window,
    1847           0 :                                     m_aWMAtoms[ NET_WM_STATE ],
    1848             :                                     nOffset, 64,
    1849             :                                     False,
    1850             :                                     XA_ATOM,
    1851             :                                     &nType,
    1852             :                                     &nFormat,
    1853             :                                     &nItems, &nBytesLeft,
    1854           0 :                                     &pData );
    1855           0 :                 if( pData )
    1856             :                 {
    1857           0 :                     if( nType == XA_ATOM && nFormat == 32 && nItems > 0 )
    1858             :                     {
    1859           0 :                         pStates = (Atom*)pData;
    1860           0 :                         for( unsigned long i = 0; i < nItems; i++ )
    1861             :                         {
    1862           0 :                             if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_VERT ] )
    1863           0 :                                 pFrame->mbMaximizedVert = true;
    1864           0 :                             else if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] && m_aWMAtoms[ NET_WM_STATE_MAXIMIZED_HORZ ] )
    1865           0 :                                 pFrame->mbMaximizedHorz = true;
    1866           0 :                             else if( pStates[i] == m_aWMAtoms[ NET_WM_STATE_SHADED ] && m_aWMAtoms[ NET_WM_STATE_SHADED ] )
    1867           0 :                                 pFrame->mbShaded = true;
    1868             :                         }
    1869             :                     }
    1870           0 :                     XFree( pData );
    1871           0 :                     pData = NULL;
    1872           0 :                     nOffset += nItems * nFormat / 32;
    1873             :                 }
    1874             :                 else
    1875           0 :                     break;
    1876           0 :             } while( nBytesLeft > 0 );
    1877             :         }
    1878             : 
    1879           0 :         if( ! (pFrame->mbMaximizedHorz || pFrame->mbMaximizedVert ) )
    1880           0 :             pFrame->maRestorePosSize = Rectangle();
    1881             :         else
    1882             :         {
    1883           0 :             const SalFrameGeometry& rGeom = pFrame->GetUnmirroredGeometry();
    1884             :             // the current geometry may already be changed by the corresponding
    1885             :             // ConfigureNotify, but this cannot be helped
    1886             :             pFrame->maRestorePosSize =
    1887             :                 Rectangle( Point( rGeom.nX, rGeom.nY ),
    1888           0 :                            Size( rGeom.nWidth, rGeom.nHeight ) );
    1889             :         }
    1890             :     }
    1891           0 :     else if( pEvent->atom == m_aWMAtoms[ NET_WM_DESKTOP ] )
    1892             :     {
    1893           0 :         pFrame->m_nWorkArea = getWindowWorkArea( pFrame->GetShellWindow() );
    1894             :     }
    1895             :     else
    1896           0 :         nHandled = 0;
    1897             : 
    1898           0 :     return nHandled;
    1899             : }
    1900             : 
    1901             : /*
    1902             :  *  GnomeWMAdaptor::handlePropertyNotify
    1903             :  */
    1904           0 : int GnomeWMAdaptor::handlePropertyNotify( X11SalFrame* pFrame, XPropertyEvent* pEvent ) const
    1905             : {
    1906           0 :     int nHandled = 1;
    1907           0 :     if( pEvent->atom == m_aWMAtoms[ WIN_STATE ] )
    1908             :     {
    1909           0 :         pFrame->mbMaximizedHorz = pFrame->mbMaximizedVert = false;
    1910           0 :         pFrame->mbShaded = false;
    1911             : 
    1912           0 :         if( pEvent->state == PropertyNewValue )
    1913             :         {
    1914             :             Atom nType;
    1915           0 :             int nFormat = 0;
    1916           0 :             unsigned long nItems = 0;
    1917           0 :             unsigned long nBytesLeft = 0;
    1918           0 :             unsigned char* pData = 0;
    1919             :             XGetWindowProperty( m_pDisplay,
    1920             :                                 pEvent->window,
    1921           0 :                                 m_aWMAtoms[ WIN_STATE ],
    1922             :                                 0, 1,
    1923             :                                 False,
    1924             :                                 XA_CARDINAL,
    1925             :                                 &nType,
    1926             :                                 &nFormat,
    1927             :                                 &nItems, &nBytesLeft,
    1928           0 :                                 &pData );
    1929           0 :             if( pData )
    1930             :             {
    1931           0 :                 if( nType == XA_CARDINAL && nFormat == 32 && nItems == 1 )
    1932             :                 {
    1933           0 :                     sal_uInt32 nWinState = *(sal_uInt32*)pData;
    1934           0 :                     if( nWinState & (1<<2) )
    1935           0 :                         pFrame->mbMaximizedVert = true;
    1936           0 :                     if( nWinState & (1<<3) )
    1937           0 :                         pFrame->mbMaximizedHorz = true;
    1938           0 :                     if( nWinState & (1<<5) )
    1939           0 :                         pFrame->mbShaded = true;
    1940             :                 }
    1941           0 :                 XFree( pData );
    1942             :             }
    1943             :         }
    1944             : 
    1945           0 :         if( ! (pFrame->mbMaximizedHorz || pFrame->mbMaximizedVert ) )
    1946           0 :             pFrame->maRestorePosSize = Rectangle();
    1947             :         else
    1948             :         {
    1949           0 :             const SalFrameGeometry& rGeom = pFrame->GetUnmirroredGeometry();
    1950             :             // the current geometry may already be changed by the corresponding
    1951             :             // ConfigureNotify, but this cannot be helped
    1952             :             pFrame->maRestorePosSize =
    1953             :                 Rectangle( Point( rGeom.nX, rGeom.nY ),
    1954           0 :                            Size( rGeom.nWidth, rGeom.nHeight ) );
    1955             :         }
    1956             :     }
    1957           0 :     else if( pEvent->atom == m_aWMAtoms[ NET_WM_DESKTOP ] )
    1958             :     {
    1959           0 :         pFrame->m_nWorkArea = getWindowWorkArea( pFrame->GetShellWindow() );
    1960             :     }
    1961             :     else
    1962           0 :         nHandled = 0;
    1963             : 
    1964           0 :     return nHandled;
    1965             : }
    1966             : 
    1967             : /*
    1968             :  * WMAdaptor::shade
    1969             :  */
    1970           0 : void WMAdaptor::shade( X11SalFrame*, bool /*bToShaded*/ ) const
    1971             : {
    1972           0 : }
    1973             : 
    1974             : /*
    1975             :  * NetWMAdaptor::shade
    1976             :  */
    1977           0 : void NetWMAdaptor::shade( X11SalFrame* pFrame, bool bToShaded ) const
    1978             : {
    1979           0 :     if( m_aWMAtoms[ NET_WM_STATE ]
    1980           0 :         && m_aWMAtoms[ NET_WM_STATE_SHADED ]
    1981           0 :         && ( pFrame->nStyle_ & ~SAL_FRAME_STYLE_DEFAULT )
    1982             :         )
    1983             :     {
    1984           0 :         pFrame->mbShaded = bToShaded;
    1985           0 :         if( pFrame->bMapped_ )
    1986             :         {
    1987             :             // window already mapped, send WM a message
    1988             :             XEvent aEvent;
    1989           0 :             aEvent.type                 = ClientMessage;
    1990           0 :             aEvent.xclient.display      = m_pDisplay;
    1991           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    1992           0 :             aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
    1993           0 :             aEvent.xclient.format       = 32;
    1994           0 :             aEvent.xclient.data.l[0]    = bToShaded ? 1 : 0;
    1995           0 :             aEvent.xclient.data.l[1]    = m_aWMAtoms[ NET_WM_STATE_SHADED ];
    1996           0 :             aEvent.xclient.data.l[2]    = 0;
    1997           0 :             aEvent.xclient.data.l[3]    = 0;
    1998           0 :             aEvent.xclient.data.l[4]    = 0;
    1999             :             XSendEvent( m_pDisplay,
    2000             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    2001             :                         False,
    2002             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    2003             :                         &aEvent
    2004           0 :                         );
    2005             :         }
    2006             :         else
    2007             :         {
    2008             :             // window not mapped yet, set _NET_WM_STATE directly
    2009           0 :             setNetWMState( pFrame );
    2010             :         }
    2011             :     }
    2012           0 : }
    2013             : 
    2014             : /*
    2015             :  *  GnomeWMAdaptor::shade
    2016             :  */
    2017           0 : void GnomeWMAdaptor::shade( X11SalFrame* pFrame, bool bToShaded ) const
    2018             : {
    2019           0 :     if( m_aWMAtoms[ WIN_STATE ] )
    2020             :     {
    2021           0 :         pFrame->mbShaded = bToShaded;
    2022           0 :         if( pFrame->bMapped_ )
    2023             :         {
    2024             :             // window already mapped, send WM a message
    2025             :             XEvent aEvent;
    2026           0 :             aEvent.type                 = ClientMessage;
    2027           0 :             aEvent.xclient.display      = m_pDisplay;
    2028           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    2029           0 :             aEvent.xclient.message_type = m_aWMAtoms[ WIN_STATE ];
    2030           0 :             aEvent.xclient.format       = 32;
    2031           0 :             aEvent.xclient.data.l[0]    = (1<<5);
    2032           0 :             aEvent.xclient.data.l[1]    = bToShaded ? (1<<5) : 0;
    2033           0 :             aEvent.xclient.data.l[2]    = 0;
    2034           0 :             aEvent.xclient.data.l[3]    = 0;
    2035           0 :             aEvent.xclient.data.l[4]    = 0;
    2036             :             XSendEvent( m_pDisplay,
    2037             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    2038             :                         False,
    2039             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    2040             :                         &aEvent
    2041           0 :                         );
    2042             :         }
    2043             :         else
    2044           0 :             setGnomeWMState( pFrame );
    2045             :     }
    2046           0 : }
    2047             : 
    2048             : /*
    2049             :  *  WMAdaptor::showFullScreen
    2050             :  */
    2051           0 : void WMAdaptor::showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const
    2052             : {
    2053           0 :     pFrame->mbFullScreen = bFullScreen;
    2054           0 :     maximizeFrame( pFrame, bFullScreen, bFullScreen );
    2055           0 : }
    2056             : 
    2057             : /*
    2058             :  *  NetWMAdaptor::showFullScreen
    2059             :  */
    2060           0 : void NetWMAdaptor::showFullScreen( X11SalFrame* pFrame, bool bFullScreen ) const
    2061             : {
    2062           0 :     if( m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ] )
    2063             :     {
    2064           0 :         pFrame->mbFullScreen = bFullScreen;
    2065           0 :         if( bFullScreen )
    2066             :         {
    2067           0 :             if( m_aWMAtoms[ MOTIF_WM_HINTS ] )
    2068             :             {
    2069             :                 XDeleteProperty( m_pDisplay,
    2070             :                                  pFrame->GetShellWindow(),
    2071           0 :                                 m_aWMAtoms[ MOTIF_WM_HINTS ] );
    2072             :             }
    2073             :         }
    2074           0 :         if( pFrame->bMapped_ )
    2075             :         {
    2076             :             // window already mapped, send WM a message
    2077             :             XEvent aEvent;
    2078           0 :             aEvent.type                 = ClientMessage;
    2079           0 :             aEvent.xclient.display      = m_pDisplay;
    2080           0 :             aEvent.xclient.window       = pFrame->GetShellWindow();
    2081           0 :             aEvent.xclient.message_type = m_aWMAtoms[ NET_WM_STATE ];
    2082           0 :             aEvent.xclient.format       = 32;
    2083           0 :             aEvent.xclient.data.l[0]    = bFullScreen ? 1 : 0;
    2084           0 :             aEvent.xclient.data.l[1]    = m_aWMAtoms[ NET_WM_STATE_FULLSCREEN ];
    2085           0 :             aEvent.xclient.data.l[2]    = 0;
    2086           0 :             aEvent.xclient.data.l[3]    = 0;
    2087           0 :             aEvent.xclient.data.l[4]    = 0;
    2088             :             XSendEvent( m_pDisplay,
    2089             :                         m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    2090             :                         False,
    2091             :                         SubstructureNotifyMask | SubstructureRedirectMask,
    2092             :                         &aEvent
    2093           0 :                         );
    2094             :         }
    2095             :         else
    2096             :         {
    2097             :             // window not mapped yet, set _NET_WM_STATE directly
    2098           0 :             setNetWMState( pFrame );
    2099             :         }
    2100             :         // #i42750# guess size before resize event shows up
    2101           0 :         if( bFullScreen )
    2102             :         {
    2103           0 :             if( m_pSalDisplay->IsXinerama() )
    2104             :             {
    2105             :                 XLIB_Window aRoot, aChild;
    2106           0 :                 int root_x = 0, root_y = 0, lx, ly;
    2107             :                 unsigned int mask;
    2108             :                 XQueryPointer( m_pDisplay,
    2109             :                 m_pSalDisplay->GetRootWindow( pFrame->GetScreenNumber() ),
    2110             :                 &aRoot, &aChild,
    2111           0 :                 &root_x, &root_y, &lx, &ly, &mask );
    2112           0 :                 const std::vector< Rectangle >& rScreens = m_pSalDisplay->GetXineramaScreens();
    2113           0 :                 Point aMousePoint( root_x, root_y );
    2114           0 :                 for( unsigned int i = 0; i < rScreens.size(); i++ )
    2115             :                 {
    2116           0 :                     if( rScreens[i].IsInside( aMousePoint ) )
    2117             :                     {
    2118           0 :                         pFrame->maGeometry.nX       = rScreens[i].Left();
    2119           0 :                         pFrame->maGeometry.nY       = rScreens[i].Top();
    2120           0 :                         pFrame->maGeometry.nWidth   = rScreens[i].GetWidth();
    2121           0 :                         pFrame->maGeometry.nHeight  = rScreens[i].GetHeight();
    2122           0 :                         break;
    2123             :                     }
    2124             :                 }
    2125             :             }
    2126             :             else
    2127             :             {
    2128           0 :                 Size aSize = m_pSalDisplay->GetScreenSize( pFrame->GetScreenNumber() );
    2129           0 :                 pFrame->maGeometry.nX       = 0;
    2130           0 :                 pFrame->maGeometry.nY       = 0;
    2131           0 :                 pFrame->maGeometry.nWidth   = aSize.Width();
    2132           0 :                 pFrame->maGeometry.nHeight  = aSize.Height();
    2133             :             }
    2134           0 :             pFrame->CallCallback( SALEVENT_MOVERESIZE, NULL );
    2135             :         }
    2136             :     }
    2137           0 :     else WMAdaptor::showFullScreen( pFrame, bFullScreen );
    2138           0 : }
    2139             : 
    2140             : /*
    2141             :  *  WMAdaptor::getCurrentWorkArea
    2142             :  */
    2143             : // FIXME: multiscreen case
    2144           0 : int WMAdaptor::getCurrentWorkArea() const
    2145             : {
    2146           0 :     int nCurrent = -1;
    2147           0 :     if( m_aWMAtoms[ NET_CURRENT_DESKTOP ] )
    2148             :     {
    2149           0 :         Atom                aRealType   = None;
    2150           0 :         int                 nFormat     = 8;
    2151           0 :         unsigned long       nItems      = 0;
    2152           0 :         unsigned long       nBytesLeft  = 0;
    2153           0 :         unsigned char*  pProperty   = NULL;
    2154           0 :         if( XGetWindowProperty( m_pDisplay,
    2155             :                                 m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
    2156           0 :                                 m_aWMAtoms[ NET_CURRENT_DESKTOP ],
    2157             :                                 0, 1,
    2158             :                                 False,
    2159             :                                 XA_CARDINAL,
    2160             :                                 &aRealType,
    2161             :                                 &nFormat,
    2162             :                                 &nItems,
    2163             :                                 &nBytesLeft,
    2164           0 :                                 &pProperty ) == 0
    2165           0 :                                 && pProperty
    2166             :         )
    2167             :         {
    2168           0 :             nCurrent = int(*(sal_Int32*)pProperty);
    2169           0 :             XFree( pProperty );
    2170             :         }
    2171           0 :         else if( pProperty )
    2172             :         {
    2173           0 :             XFree( pProperty );
    2174           0 :             pProperty = NULL;
    2175             :         }
    2176             :     }
    2177           0 :     return nCurrent;
    2178             : }
    2179             : 
    2180             : /*
    2181             :  *  WMAdaptor::getWindowWorkArea
    2182             :  */
    2183           0 : int WMAdaptor::getWindowWorkArea( XLIB_Window aWindow ) const
    2184             : {
    2185           0 :     int nCurrent = -1;
    2186           0 :     if( m_aWMAtoms[ NET_WM_DESKTOP ] )
    2187             :     {
    2188           0 :         Atom                aRealType   = None;
    2189           0 :         int                 nFormat     = 8;
    2190           0 :         unsigned long       nItems      = 0;
    2191           0 :         unsigned long       nBytesLeft  = 0;
    2192           0 :         unsigned char*  pProperty   = NULL;
    2193           0 :         if( XGetWindowProperty( m_pDisplay,
    2194             :                                 aWindow,
    2195           0 :                                 m_aWMAtoms[ NET_WM_DESKTOP ],
    2196             :                                 0, 1,
    2197             :                                 False,
    2198             :                                 XA_CARDINAL,
    2199             :                                 &aRealType,
    2200             :                                 &nFormat,
    2201             :                                 &nItems,
    2202             :                                 &nBytesLeft,
    2203           0 :                                 &pProperty ) == 0
    2204           0 :                                 && pProperty
    2205             :         )
    2206             :         {
    2207           0 :             nCurrent = int(*(sal_Int32*)pProperty);
    2208           0 :             XFree( pProperty );
    2209             :         }
    2210           0 :         else if( pProperty )
    2211             :         {
    2212           0 :             XFree( pProperty );
    2213           0 :             pProperty = NULL;
    2214             :         }
    2215             :     }
    2216           0 :     return nCurrent;
    2217             : }
    2218             : 
    2219             : /*
    2220             :  *  WMAdaptor::getCurrentWorkArea
    2221             :  */
    2222             : // fixme: multi screen case
    2223           0 : void WMAdaptor::switchToWorkArea( int nWorkArea, bool bConsiderWM ) const
    2224             : {
    2225           0 :     if( bConsiderWM && ! getWMshouldSwitchWorkspace() )
    2226           0 :         return;
    2227             : 
    2228           0 :     if( m_aWMAtoms[ NET_CURRENT_DESKTOP ] )
    2229             :     {
    2230             :         XEvent aEvent;
    2231           0 :         aEvent.type                 = ClientMessage;
    2232           0 :         aEvent.xclient.display      = m_pDisplay;
    2233           0 :         aEvent.xclient.window       = m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() );
    2234           0 :         aEvent.xclient.message_type = m_aWMAtoms[ NET_CURRENT_DESKTOP ];
    2235           0 :         aEvent.xclient.format       = 32;
    2236           0 :         aEvent.xclient.data.l[0]    = nWorkArea;
    2237           0 :         aEvent.xclient.data.l[1]    = 0;
    2238           0 :         aEvent.xclient.data.l[2]    = 0;
    2239           0 :         aEvent.xclient.data.l[3]    = 0;
    2240           0 :         aEvent.xclient.data.l[4]    = 0;
    2241             :         XSendEvent( m_pDisplay,
    2242             :                     m_pSalDisplay->GetRootWindow( m_pSalDisplay->GetDefaultXScreen() ),
    2243             :                     False,
    2244             :                     SubstructureNotifyMask | SubstructureRedirectMask,
    2245             :                     &aEvent
    2246           0 :                     );
    2247             :     }
    2248             : }
    2249             : 
    2250             : /*
    2251             :  * WMAdaptor::frameIsMapping
    2252             :  */
    2253           0 : void WMAdaptor::frameIsMapping( X11SalFrame* ) const
    2254             : {
    2255           0 : }
    2256             : 
    2257             : /*
    2258             :  * NetWMAdaptor::frameIsMapping
    2259             :  */
    2260           0 : void NetWMAdaptor::frameIsMapping( X11SalFrame* pFrame ) const
    2261             : {
    2262           0 :     setNetWMState( pFrame );
    2263           0 : }
    2264             : 
    2265             : /*
    2266             :  * WMAdaptor::setFrameStruts
    2267             :  */
    2268           0 : void WMAdaptor::setFrameStruts( X11SalFrame*,
    2269             :                                 int, int, int, int,
    2270             :                                 int, int, int, int,
    2271             :                                 int, int, int, int ) const
    2272             : {
    2273           0 : }
    2274             : 
    2275             : /*
    2276             :  * NetWMAdaptor::setFrameStruts
    2277             :  */
    2278           0 : void NetWMAdaptor::setFrameStruts( X11SalFrame* pFrame,
    2279             :                                    int left, int right, int top, int bottom,
    2280             :                                    int left_start_y, int left_end_y,
    2281             :                                    int right_start_y, int right_end_y,
    2282             :                                    int top_start_x, int top_end_x,
    2283             :                                    int bottom_start_x, int bottom_end_x ) const
    2284             : {
    2285             :     long nData[12];
    2286           0 :     nData[0] = left;
    2287           0 :     nData[1] = right;
    2288           0 :     nData[2] = top;
    2289           0 :     nData[3] = bottom;
    2290           0 :     nData[4] = left_start_y;
    2291           0 :     nData[5] = left_end_y;
    2292           0 :     nData[6] = right_start_y;
    2293           0 :     nData[7] = right_end_y;
    2294           0 :     nData[8] = top_start_x;
    2295           0 :     nData[9] = top_end_x;
    2296           0 :     nData[10]= bottom_start_x;
    2297           0 :     nData[11]= bottom_end_x;
    2298           0 :     Atom aProperty = None;
    2299           0 :     int nSetData = 0;
    2300             : 
    2301           0 :     if( m_aWMAtoms[NET_WM_STRUT_PARTIAL] )
    2302             :     {
    2303           0 :         aProperty = m_aWMAtoms[NET_WM_STRUT_PARTIAL];
    2304           0 :         nSetData = 12;
    2305             :     }
    2306           0 :     else if( m_aWMAtoms[NET_WM_STRUT] )
    2307             :     {
    2308           0 :         aProperty = m_aWMAtoms[NET_WM_STRUT];
    2309           0 :         nSetData = 4;
    2310             :     }
    2311           0 :     if( nSetData )
    2312             :     {
    2313             :             XChangeProperty( m_pDisplay,
    2314             :                              pFrame->GetShellWindow(),
    2315             :                              aProperty,
    2316             :                              XA_CARDINAL,
    2317             :                              32,
    2318             :                              PropModeReplace,
    2319             :                              (unsigned char*)&nData,
    2320             :                              nSetData
    2321           0 :                              );
    2322             :     }
    2323           0 : }
    2324             : 
    2325             : /*
    2326             :  * WMAdaptor::setUserTime
    2327             :  */
    2328           0 : void WMAdaptor::setUserTime( X11SalFrame*, long ) const
    2329             : {
    2330           0 : }
    2331             : 
    2332             : /*
    2333             :  * NetWMAdaptor::setUserTime
    2334             :  */
    2335           0 : void NetWMAdaptor::setUserTime( X11SalFrame* i_pFrame, long i_nUserTime ) const
    2336             : {
    2337           0 :     if( m_aWMAtoms[NET_WM_USER_TIME] )
    2338             :     {
    2339             :         XChangeProperty( m_pDisplay,
    2340             :                          i_pFrame->GetShellWindow(),
    2341           0 :                          m_aWMAtoms[NET_WM_USER_TIME],
    2342             :                          XA_CARDINAL,
    2343             :                          32,
    2344             :                          PropModeReplace,
    2345             :                          (unsigned char*)&i_nUserTime,
    2346             :                          1
    2347           0 :                          );
    2348             :     }
    2349           0 : }
    2350             : 
    2351             : /*
    2352             :  * WMAdaptor::setPID
    2353             :  */
    2354           0 : void WMAdaptor::setPID( X11SalFrame* i_pFrame ) const
    2355             : {
    2356           0 :     if( m_aWMAtoms[NET_WM_PID] )
    2357             :     {
    2358           0 :         long nPID = (long)getpid();
    2359             :         XChangeProperty( m_pDisplay,
    2360             :                          i_pFrame->GetShellWindow(),
    2361           0 :                          m_aWMAtoms[NET_WM_PID],
    2362             :                          XA_CARDINAL,
    2363             :                          32,
    2364             :                          PropModeReplace,
    2365             :                          (unsigned char*)&nPID,
    2366             :                          1
    2367           0 :                          );
    2368             :     }
    2369           0 : }
    2370             : 
    2371             : /*
    2372             : * WMAdaptor::setClientMachine
    2373             : */
    2374           0 : void WMAdaptor::setClientMachine( X11SalFrame* i_pFrame ) const
    2375             : {
    2376           0 :     OString aWmClient( OUStringToOString( GetGenericData()->GetHostname(), RTL_TEXTENCODING_ASCII_US ) );
    2377           0 :     XTextProperty aClientProp = { (unsigned char*)aWmClient.getStr(), XA_STRING, 8, sal::static_int_cast<unsigned long>( aWmClient.getLength() ) };
    2378           0 :     XSetWMClientMachine( m_pDisplay, i_pFrame->GetShellWindow(), &aClientProp );
    2379           0 : }
    2380             : 
    2381           0 : void WMAdaptor::answerPing( X11SalFrame* i_pFrame, XClientMessageEvent* i_pEvent ) const
    2382             : {
    2383           0 :     if( m_aWMAtoms[NET_WM_PING] &&
    2384           0 :         i_pEvent->message_type == m_aWMAtoms[ WM_PROTOCOLS ] &&
    2385           0 :         (Atom)i_pEvent->data.l[0] == m_aWMAtoms[ NET_WM_PING ] )
    2386             :     {
    2387             :         XEvent aEvent;
    2388           0 :         aEvent.xclient = *i_pEvent;
    2389           0 :         aEvent.xclient.window = m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() );
    2390             :         XSendEvent( m_pDisplay,
    2391             :                     m_pSalDisplay->GetRootWindow( i_pFrame->GetScreenNumber() ),
    2392             :                     False,
    2393             :                     SubstructureNotifyMask | SubstructureRedirectMask,
    2394             :                     &aEvent
    2395           0 :                     );
    2396           0 :         XFlush( m_pDisplay );
    2397             :     }
    2398           0 : }
    2399             : 
    2400             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10