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