xref: /aoo41x/main/vcl/unx/generic/window/salframe.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <string.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 
36 #include "tools/debug.hxx"
37 
38 #include "sal/alloca.h"
39 
40 #include "vcl/floatwin.hxx"
41 #include "vcl/svapp.hxx"
42 #include "vcl/keycodes.hxx"
43 #include "vcl/printerinfomanager.hxx"
44 #include "vcl/settings.hxx"
45 
46 #include <tools/prex.h>
47 #include <X11/Xatom.h>
48 #include <X11/keysym.h>
49 #include "FWS.hxx"
50 #include <X11/extensions/shape.h>
51 #ifndef SOLARIS
52 #include <X11/extensions/dpms.h>
53 #endif
54 #include <tools/postx.h>
55 
56 #include "unx/salunx.h"
57 #include "unx/saldata.hxx"
58 #include "unx/saldisp.hxx"
59 #include "unx/salgdi.h"
60 #include "unx/salframe.h"
61 #include "unx/soicon.hxx"
62 #include "unx/dtint.hxx"
63 #include "unx/sm.hxx"
64 #include "unx/wmadaptor.hxx"
65 #include "unx/salprn.h"
66 #include "unx/salbmp.h"
67 #include "unx/i18n_ic.hxx"
68 #include "unx/i18n_keysym.hxx"
69 #include "unx/i18n_status.hxx"
70 
71 #include "salinst.hxx"
72 #include "sallayout.hxx"
73 
74 #include <com/sun/star/uno/Exception.hpp>
75 
76 #include <algorithm>
77 
78 #ifndef Button6
79 # define Button6 6
80 #endif
81 #ifndef Button7
82 # define Button7 7
83 #endif
84 
85 using namespace vcl_sal;
86 using namespace vcl;
87 
88 // -=-= #defines -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
89 #define CLIENT_EVENTS			StructureNotifyMask \
90 								| SubstructureNotifyMask \
91 								| KeyPressMask \
92 								| KeyReleaseMask \
93 								| ButtonPressMask \
94 								| ButtonReleaseMask \
95 								| PointerMotionMask \
96 								| EnterWindowMask \
97 								| LeaveWindowMask \
98 								| FocusChangeMask \
99 								| ExposureMask \
100 								| VisibilityChangeMask \
101 								| PropertyChangeMask \
102 								| ColormapChangeMask
103 
104 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
105 
106 static XLIB_Window	hPresentationWindow = None, hPresFocusWindow = None;
107 static ::std::list< XLIB_Window > aPresentationReparentList;
108 static int			nVisibleFloats		= 0;
109 
110 X11SalFrame* X11SalFrame::s_pSaveYourselfFrame = NULL;
111 
112 // -=-= C++ statics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
113 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
114 static void doReparentPresentationDialogues( SalDisplay* pDisplay )
115 {
116     pDisplay->GetXLib()->PushXErrorLevel( true );
117     while( aPresentationReparentList.begin() != aPresentationReparentList.end() )
118     {
119         int x, y;
120         XLIB_Window aRoot, aChild;
121         unsigned int w, h, bw, d;
122         XGetGeometry( pDisplay->GetDisplay(),
123                       aPresentationReparentList.front(),
124                       &aRoot,
125                       &x, &y, &w, &h, &bw, &d );
126         XTranslateCoordinates( pDisplay->GetDisplay(),
127                                hPresentationWindow,
128                                aRoot,
129                                x, y,
130                                &x, &y,
131                                &aChild );
132         XReparentWindow( pDisplay->GetDisplay(),
133                          aPresentationReparentList.front(),
134                          aRoot,
135                          x, y );
136         aPresentationReparentList.pop_front();
137     }
138     if( hPresFocusWindow )
139         XSetInputFocus( pDisplay->GetDisplay(), hPresFocusWindow, PointerRoot, CurrentTime );
140     XSync( pDisplay->GetDisplay(), False );
141     pDisplay->GetXLib()->PopXErrorLevel();
142 }
143 
144 // -=-= SalFrame / X11SalFrame =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
145 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
146 
147 bool X11SalFrame::IsOverrideRedirect() const
148 {
149     return
150         ((nStyle_ & SAL_FRAME_STYLE_INTRO) && !pDisplay_->getWMAdaptor()->supportsSplash())
151         ||
152         (!( nStyle_ & ~SAL_FRAME_STYLE_DEFAULT ) && !pDisplay_->getWMAdaptor()->supportsFullScreen())
153         ;
154 }
155 
156 bool X11SalFrame::IsFloatGrabWindow() const
157 {
158     static const char* pDisableGrab = getenv( "SAL_DISABLE_FLOATGRAB" );
159 
160     return
161         ( ( !pDisableGrab || !*pDisableGrab ) &&
162           (
163            (nStyle_ & SAL_FRAME_STYLE_FLOAT)	&&
164            ! (nStyle_ & SAL_FRAME_STYLE_TOOLTIP)	&&
165            ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
166            )
167           );
168 }
169 
170 void X11SalFrame::setXEmbedInfo()
171 {
172     if( m_bXEmbed )
173     {
174         long aInfo[2];
175         aInfo[0] = 1; // XEMBED protocol version
176         aInfo[1] = (bMapped_ ? 1 : 0); // XEMBED_MAPPED
177         XChangeProperty( pDisplay_->GetDisplay(),
178                          mhWindow,
179                          pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ),
180                          pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED_INFO ),
181                          32,
182                          PropModeReplace,
183                          reinterpret_cast<unsigned char*>(aInfo),
184                          sizeof(aInfo)/sizeof(aInfo[0]) );
185     }
186 }
187 
188 void X11SalFrame::askForXEmbedFocus( sal_Int32 i_nTimeCode )
189 {
190     XEvent aEvent;
191 
192     rtl_zeroMemory( &aEvent, sizeof(aEvent) );
193     aEvent.xclient.window = mhForeignParent;
194     aEvent.xclient.type = ClientMessage;
195     aEvent.xclient.message_type = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::XEMBED );
196     aEvent.xclient.format = 32;
197     aEvent.xclient.data.l[0] = i_nTimeCode ? i_nTimeCode : CurrentTime;
198     aEvent.xclient.data.l[1] = 3; // XEMBED_REQUEST_FOCUS
199     aEvent.xclient.data.l[2] = 0;
200     aEvent.xclient.data.l[3] = 0;
201     aEvent.xclient.data.l[4] = 0;
202 
203     GetDisplay()->GetXLib()->PushXErrorLevel( true );
204     XSendEvent( pDisplay_->GetDisplay(),
205                 mhForeignParent,
206                 False, NoEventMask, &aEvent );
207     XSync( pDisplay_->GetDisplay(), False );
208     GetDisplay()->GetXLib()->PopXErrorLevel();
209 }
210 
211 
212 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
213 
214 void X11SalFrame::Init( sal_uLong nSalFrameStyle, int nScreen, SystemParentData* pParentData, bool bUseGeometry )
215 {
216     if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
217         nScreen = GetDisplay()->GetDefaultScreenNumber();
218     if( mpParent )
219         nScreen = mpParent->m_nScreen;
220 
221     m_nScreen   = nScreen;
222 	nStyle_ 	= nSalFrameStyle;
223 	XWMHints Hints;
224     Hints.flags = InputHint;
225     Hints.input = (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) ? False : True;
226 
227     int x = 0, y = 0;
228     unsigned int w = 500, h = 500;
229     XSetWindowAttributes Attributes;
230 
231     int nAttrMask =   CWBorderPixel
232                     | CWBackPixmap
233                     | CWColormap
234                     | CWOverrideRedirect
235                     | CWEventMask
236                     ;
237     Attributes.border_pixel             = 0;
238     Attributes.background_pixmap		= None;
239     Attributes.colormap					= GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
240     Attributes.override_redirect		= False;
241     Attributes.event_mask				= CLIENT_EVENTS;
242 
243     const SalVisual& rVis = GetDisplay()->GetVisual( m_nScreen );
244     XLIB_Window aFrameParent = pParentData ? pParentData->aWindow : GetDisplay()->GetRootWindow( m_nScreen );
245     XLIB_Window aClientLeader = None;
246 
247     if( bUseGeometry )
248     {
249         x = maGeometry.nX;
250         y = maGeometry.nY;
251         w = maGeometry.nWidth;
252         h = maGeometry.nHeight;
253     }
254 
255     if( (nSalFrameStyle & SAL_FRAME_STYLE_FLOAT) &&
256         ! (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
257         )
258 	{
259         if( nShowState_ == SHOWSTATE_UNKNOWN )
260         {
261             w = 10;
262             h = 10;
263         }
264         Attributes.override_redirect = True;
265 	}
266     else if( (nSalFrameStyle & SAL_FRAME_STYLE_SYSTEMCHILD ) )
267     {
268         DBG_ASSERT( mpParent, "SAL_FRAME_STYLE_SYSTEMCHILD window without parent" );
269         if( mpParent )
270         {
271             aFrameParent = mpParent->mhWindow;
272             // FIXME: since with SAL_FRAME_STYLE_SYSTEMCHILD
273             // multiple X11SalFrame objects can have the same shell window
274             // dispatching events in saldisp.cxx is unclear (the first frame)
275             // wins. HTH this correctly is unclear yet
276             // for the time being, treat set the shell window to own window
277             // like for a normal frame
278             // mhShellWindow = mpParent->GetShellWindow();
279         }
280     }
281 	else if( pParentData )
282 	{
283         // plugin parent may be killed unexpectedly by
284         // plugging process; ignore XErrors in that case
285         GetDisplay()->setHaveSystemChildFrame();
286 
287 		nStyle_ |= SAL_FRAME_STYLE_PLUG;
288         Attributes.override_redirect = True;
289         if( pParentData->nSize >= sizeof(SystemParentData) )
290             m_bXEmbed = pParentData->bXEmbedSupport;
291 
292 		int x_ret, y_ret;
293 		unsigned int bw, d;
294 		XLIB_Window aRoot, aParent;
295 
296 		XGetGeometry( GetXDisplay(), pParentData->aWindow,
297 					  &aRoot, &x_ret, &y_ret, &w, &h, &bw, &d );
298 		mhForeignParent = pParentData->aWindow;
299 
300 		mhShellWindow = aParent = mhForeignParent;
301 		XLIB_Window* pChildren;
302 		unsigned int nChildren;
303         bool bBreak = false;
304 		do
305 		{
306 			XQueryTree( GetDisplay()->GetDisplay(), mhShellWindow,
307 						&aRoot, &aParent, &pChildren, &nChildren );
308 			XFree( pChildren );
309 			if( aParent != aRoot )
310 				mhShellWindow = aParent;
311             int nCount = 0;
312             Atom* pProps = XListProperties( GetDisplay()->GetDisplay(),
313                                             mhShellWindow,
314                                             &nCount );
315             for( int i = 0; i < nCount && ! bBreak; ++i )
316                 bBreak = (pProps[i] == XA_WM_HINTS);
317             if( pProps )
318                 XFree( pProps );
319 		} while( aParent != aRoot && ! bBreak );
320 
321 		// check if this is really one of our own frames
322 		// do not change the input mask in that case
323         const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
324         std::list< SalFrame* >::const_iterator it = rFrames.begin();
325         while( it != rFrames.end() && mhForeignParent != static_cast<const X11SalFrame*>(*it)->GetWindow() )
326             ++it;
327 
328 		if( it == rFrames.end() )
329 		{
330 			XSelectInput( GetDisplay()->GetDisplay(), mhForeignParent, StructureNotifyMask | FocusChangeMask );
331 			XSelectInput( GetDisplay()->GetDisplay(), mhShellWindow, StructureNotifyMask | FocusChangeMask );
332 		}
333     }
334     else
335     {
336         if( ! bUseGeometry )
337         {
338             Size aScreenSize( GetDisplay()->getDataForScreen( m_nScreen ).m_aSize );
339             w = aScreenSize.Width();
340             h = aScreenSize.Height();
341             if( nSalFrameStyle & SAL_FRAME_STYLE_SIZEABLE &&
342                 nSalFrameStyle & SAL_FRAME_STYLE_MOVEABLE )
343             {
344                 // fill in holy default values brought to us by product management
345                 if( aScreenSize.Width() >= 800 )
346                     w = 785;
347                 if( aScreenSize.Width() >= 1024 )
348                     w = 920;
349 
350                 if( aScreenSize.Height() >= 600 )
351                     h = 550;
352                 if( aScreenSize.Height() >= 768 )
353                     h = 630;
354                 if( aScreenSize.Height() >= 1024 )
355                     h = 875;
356             }
357             if( ! mpParent )
358             {
359                 // find the last document window (if any)
360                 const X11SalFrame* pFrame = NULL;
361                 const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
362                 std::list< SalFrame* >::const_iterator it = rFrames.begin();
363                 while( it != rFrames.end() )
364                 {
365                     pFrame = static_cast< const X11SalFrame* >(*it);
366                     if( ! ( pFrame->mpParent
367                             || pFrame->mbFullScreen
368                             || ! ( pFrame->nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
369                             || ! pFrame->GetUnmirroredGeometry().nWidth
370                             || ! pFrame->GetUnmirroredGeometry().nHeight
371                             )
372                         )
373                         break;
374                     ++it;
375                 }
376 
377                 if( it != rFrames.end() )
378                 {
379                     // set a document position and size
380                     // the first frame gets positioned by the window manager
381                     const SalFrameGeometry& rGeom( pFrame->GetUnmirroredGeometry() );
382                     x = rGeom.nX;
383                     y = rGeom.nY;
384                     if( x+(int)w+40 <= (int)aScreenSize.Width() &&
385                         y+(int)h+40 <= (int)aScreenSize.Height()
386                         )
387                     {
388                         y += 40;
389                         x += 40;
390                     }
391                     else
392                     {
393                         x = 10; // leave some space for decoration
394                         y = 20;
395                     }
396                 }
397                 else if( GetDisplay()->IsXinerama() )
398                 {
399                     // place frame on same screen as mouse pointer
400                     XLIB_Window aRoot, aChild;
401                     int root_x = 0, root_y = 0, lx, ly;
402                     unsigned int mask;
403                     XQueryPointer( GetXDisplay(),
404                                    GetDisplay()->GetRootWindow( m_nScreen ),
405                                    &aRoot, &aChild,
406                                    &root_x, &root_y, &lx, &ly, &mask );
407                     const std::vector< Rectangle >& rScreens = GetDisplay()->GetXineramaScreens();
408                     for( unsigned int i = 0; i < rScreens.size(); i++ )
409                         if( rScreens[i].IsInside( Point( root_x, root_y ) ) )
410                         {
411                             x = rScreens[i].Left();
412                             y = rScreens[i].Top();
413                             break;
414                         }
415                 }
416             }
417         }
418         Attributes.win_gravity = pDisplay_->getWMAdaptor()->getInitWinGravity();
419         nAttrMask |= CWWinGravity;
420         if( mpParent )
421         {
422             Attributes.save_under = True;
423             nAttrMask |= CWSaveUnder;
424         }
425         if( IsOverrideRedirect() )
426             Attributes.override_redirect = True;
427         // default icon
428         if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 )
429         {
430             bool bOk=false;
431             try
432             {
433                 bOk=SelectAppIconPixmap( pDisplay_, m_nScreen,
434                                          mnIconID != 1 ? mnIconID :
435                                          (mpParent ? mpParent->mnIconID : 1), 32,
436                                          Hints.icon_pixmap, Hints.icon_mask );
437             }
438             catch( com::sun::star::uno::Exception& )
439             {
440                 // can happen - no ucb during early startup
441             }
442             if( bOk )
443             {
444                 Hints.flags		|= IconPixmapHint;
445                 if( Hints.icon_mask )
446                     Hints.flags	|= IconMaskHint;
447             }
448         }
449 
450 		// find the top level frame of the transience hierarchy
451         X11SalFrame* pFrame = this;
452         while( pFrame->mpParent )
453             pFrame = pFrame->mpParent;
454 		if( (pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG ) )
455 		{
456 			// if the top level window is a plugin window,
457 			// then we should place us in the same window group as
458 			// the parent application (or none if there is no window group
459 			// hint in the parent).
460 			if( pFrame->GetShellWindow() )
461 			{
462 				XWMHints* pWMHints = XGetWMHints( pDisplay_->GetDisplay(),
463 					pFrame->GetShellWindow() );
464 				if( pWMHints )
465 				{
466 					if( (pWMHints->flags & WindowGroupHint) )
467 					{
468 						Hints.flags |= WindowGroupHint;
469 						Hints.window_group = pWMHints->window_group;
470 					}
471 					XFree( pWMHints );
472 				}
473 			}
474 		}
475 		else
476 		{
477 			Hints.flags			|= WindowGroupHint;
478 			Hints.window_group	= pFrame->GetShellWindow();
479 			// note: for a normal document window this will produce None
480 			// as the window is not yet created and the shell window is
481 			// initialized to None. This must be corrected after window creation.
482 			aClientLeader = GetDisplay()->GetDrawable( m_nScreen );
483 		}
484     }
485 
486 	nShowState_ 				= SHOWSTATE_UNKNOWN;
487 	bViewable_					= sal_True;
488 	bMapped_					= sal_False;
489 	nVisibility_				= VisibilityFullyObscured;
490     mhWindow = XCreateWindow( GetXDisplay(),
491                               aFrameParent,
492                               x, y,
493                               w, h,
494                               0,
495                               rVis.GetDepth(),
496                               InputOutput,
497                               rVis.GetVisual(),
498                               nAttrMask,
499                               &Attributes );
500     // FIXME: see above: fake shell window for now to own window
501     if( /*! IsSysChildWindow() &&*/ pParentData == NULL )
502     {
503         mhShellWindow = mhWindow;
504     }
505 
506 	// correct window group if necessary
507 	if( (Hints.flags & WindowGroupHint) == WindowGroupHint )
508 	{
509 		if( Hints.window_group == None )
510 			Hints.window_group = GetShellWindow();
511 	}
512 
513     maGeometry.nX		= x;
514     maGeometry.nY		= y;
515     maGeometry.nWidth	= w;
516     maGeometry.nHeight	= h;
517     updateScreenNumber();
518 
519     XSync( GetXDisplay(), False );
520     setXEmbedInfo();
521 
522     XLIB_Time nUserTime = (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION | SAL_FRAME_STYLE_TOOLWINDOW) ) == 0 ?
523         pDisplay_->GetLastUserEventTime() : 0;
524     pDisplay_->getWMAdaptor()->setUserTime( this, nUserTime );
525 
526 	if( ! pParentData && ! IsChildWindow() && ! Attributes.override_redirect )
527 	{
528         XSetWMHints( GetXDisplay(), mhWindow, &Hints );
529 		// WM Protocols && internals
530 		Atom a[4];
531 		int  n = 0;
532 		a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW );
533         if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) )
534             a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING );
535         if( ! s_pSaveYourselfFrame && ! mpParent)
536         {
537             // at all times have only one frame with SaveYourself
538             a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF );
539             s_pSaveYourselfFrame = this;
540         }
541         if( (nSalFrameStyle & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
542             a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_TAKE_FOCUS );
543 		XSetWMProtocols( GetXDisplay(), GetShellWindow(), a, n );
544 
545         XClassHint* pClass = XAllocClassHint();
546         pClass->res_name  = const_cast<char*>(X11SalData::getFrameResName());
547         pClass->res_class = const_cast<char*>(X11SalData::getFrameClassName());
548         XSetClassHint( GetXDisplay(), GetShellWindow(), pClass );
549         XFree( pClass );
550 
551         XSizeHints* pHints = XAllocSizeHints();
552         pHints->flags       = PWinGravity | PPosition;
553         pHints->win_gravity = GetDisplay()->getWMAdaptor()->getPositionWinGravity();
554         pHints->x           = 0;
555         pHints->y           = 0;
556         if( mbFullScreen )
557         {
558             pHints->flags |= PMaxSize | PMinSize;
559             pHints->max_width = w+100;
560             pHints->max_height = h+100;
561             pHints->min_width  = w;
562             pHints->min_height = h;
563         }
564         XSetWMNormalHints( GetXDisplay(),
565                            GetShellWindow(),
566                            pHints );
567         XFree (pHints);
568 
569         // set PID and WM_CLIENT_MACHINE
570         pDisplay_->getWMAdaptor()->setClientMachine( this );
571         pDisplay_->getWMAdaptor()->setPID( this );
572 
573         // set client leader
574 		if( aClientLeader )
575 		{
576 			XChangeProperty( GetXDisplay(),
577             	             mhWindow,
578 							 pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_CLIENT_LEADER),
579 							 XA_WINDOW,
580 							 32,
581 							 PropModeReplace,
582 							 (unsigned char*)&aClientLeader,
583 							 1
584 							 );
585 		}
586 #define DECOFLAGS (SAL_FRAME_STYLE_MOVEABLE | SAL_FRAME_STYLE_SIZEABLE | SAL_FRAME_STYLE_CLOSEABLE)
587         int nDecoFlags = WMAdaptor::decoration_All;
588         if( (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) ||
589             (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION)
590             )
591             nDecoFlags = 0;
592         else if( (nStyle_ & DECOFLAGS ) != DECOFLAGS || (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
593         {
594             if( nStyle_ & DECOFLAGS )
595                 // if any decoration, then show a border
596                 nDecoFlags = WMAdaptor::decoration_Border;
597             else
598                 nDecoFlags = 0;
599 
600             if( ! mpParent && (nStyle_ & DECOFLAGS) )
601                 // don't add a min button if window should be decorationless
602                 nDecoFlags |= WMAdaptor::decoration_MinimizeBtn;
603             if( nStyle_ & SAL_FRAME_STYLE_CLOSEABLE )
604                 nDecoFlags |= WMAdaptor::decoration_CloseBtn;
605             if( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
606             {
607                 nDecoFlags |= WMAdaptor::decoration_Resize;
608                 if( ! (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
609                     nDecoFlags |= WMAdaptor::decoration_MaximizeBtn;
610             }
611             if( nStyle_ & SAL_FRAME_STYLE_MOVEABLE )
612                 nDecoFlags |= WMAdaptor::decoration_Title;
613         }
614 
615         WMAdaptor::WMWindowType eType = WMAdaptor::windowType_Normal;
616         if( nStyle_ & SAL_FRAME_STYLE_INTRO )
617             eType = WMAdaptor::windowType_Splash;
618         if( (nStyle_ & SAL_FRAME_STYLE_DIALOG) && hPresentationWindow == None )
619             eType = WMAdaptor::windowType_ModelessDialogue;
620         if( nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW )
621             eType = WMAdaptor::windowType_Utility;
622         if( nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION )
623             eType = WMAdaptor::windowType_Toolbar;
624         if(    (nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN)
625             && GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() )
626             eType = WMAdaptor::windowType_Dock;
627 
628         GetDisplay()->getWMAdaptor()->
629             setFrameTypeAndDecoration( this,
630                                        eType,
631                                        nDecoFlags,
632                                        hPresentationWindow ? NULL : mpParent );
633 
634 	    if( (nStyle_ & (SAL_FRAME_STYLE_DEFAULT |
635                         SAL_FRAME_STYLE_OWNERDRAWDECORATION|
636                         SAL_FRAME_STYLE_FLOAT |
637                         SAL_FRAME_STYLE_INTRO |
638                         SAL_FRAME_STYLE_PARTIAL_FULLSCREEN) )
639              == SAL_FRAME_STYLE_DEFAULT )
640             pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true );
641 	}
642 
643     m_nWorkArea = GetDisplay()->getWMAdaptor()->getCurrentWorkArea();
644 
645 	// Pointer
646 	SetPointer( POINTER_ARROW );
647 }
648 
649 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
650 X11SalFrame::X11SalFrame( SalFrame *pParent, sal_uLong nSalFrameStyle, SystemParentData* pSystemParent )
651 {
652 	X11SalData* pSalData = GetX11SalData();
653 
654     // initialize frame geometry
655     memset( &maGeometry, 0, sizeof(maGeometry) );
656 
657     mpParent					= static_cast< X11SalFrame* >( pParent );
658 
659     mbTransientForRoot			= false;
660 
661 	pDisplay_					= pSalData->GetDisplay();
662 	// insert frame in framelist
663     pDisplay_->registerFrame( this );
664 
665     mhWindow					= None;
666     mhShellWindow				= None;
667     mhStackingWindow			= None;
668     mhForeignParent				= None;
669     mhBackgroundPixmap          = None;
670     m_bSetFocusOnMap            = false;
671 
672 	pGraphics_					= NULL;
673 	pFreeGraphics_				= NULL;
674 
675 	hCursor_					= None;
676 	nCaptured_					= 0;
677 
678  	nReleaseTime_				= 0;
679 	nKeyCode_					= 0;
680 	nKeyState_					= 0;
681 	nCompose_					= -1;
682     mbKeyMenu					= false;
683     mbSendExtKeyModChange		= false;
684     mnExtKeyMod					= 0;
685 
686 	nShowState_ 				= SHOWSTATE_UNKNOWN;
687 	nWidth_ 					= 0;
688 	nHeight_					= 0;
689 	nStyle_ 					= 0;
690     mnExtStyle                  = 0;
691 	bAlwaysOnTop_				= sal_False;
692 
693     // set bViewable_ to sal_True: hack GetClientSize to report something
694     // different to 0/0 before first map
695 	bViewable_					= sal_True;
696 	bMapped_					= sal_False;
697 	bDefaultPosition_			= sal_True;
698 	nVisibility_				= VisibilityFullyObscured;
699     m_nWorkArea                 = 0;
700     mbInShow					= sal_False;
701     m_bXEmbed                   = false;
702 
703 	nScreenSaversTimeout_		= 0;
704 
705 	mpInputContext 				= NULL;
706 	mbInputFocus				= False;
707 
708     maAlwaysOnTopRaiseTimer.SetTimeoutHdl( LINK( this, X11SalFrame, HandleAlwaysOnTopRaise ) );
709     maAlwaysOnTopRaiseTimer.SetTimeout( 100 );
710 
711     meWindowType				= WMAdaptor::windowType_Normal;
712     mnDecorationFlags			= WMAdaptor::decoration_All;
713     mbMaximizedVert				= false;
714     mbMaximizedHorz				= false;
715     mbShaded					= false;
716     mbFullScreen				= false;
717 
718     mnIconID					= 1; // ICON_DEFAULT
719 
720     m_pClipRectangles           = NULL;
721     m_nCurClipRect              = 0;
722     m_nMaxClipRect              = 0;
723 
724 	if( mpParent )
725 		mpParent->maChildren.push_back( this );
726 
727 	Init( nSalFrameStyle, GetDisplay()->GetDefaultScreenNumber(), pSystemParent );
728 }
729 
730 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
731 
732 void X11SalFrame::passOnSaveYourSelf()
733 {
734     if( this == s_pSaveYourselfFrame )
735     {
736         // pass on SaveYourself
737         const X11SalFrame* pFrame = NULL;
738         const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
739         std::list< SalFrame* >::const_iterator it = rFrames.begin();
740         while( it != rFrames.end() )
741         {
742             pFrame = static_cast< const X11SalFrame* >(*it);
743             if( ! ( IsChildWindow() || pFrame->mpParent )
744                 && pFrame != s_pSaveYourselfFrame )
745                     break;
746             ++it;
747         }
748 
749         s_pSaveYourselfFrame = (it != rFrames.end() ) ? const_cast<X11SalFrame*>(pFrame) : NULL;
750         if( s_pSaveYourselfFrame )
751         {
752             Atom a[4];
753             int  n = 0;
754             a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_DELETE_WINDOW );
755             a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_SAVE_YOURSELF );
756             if( pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING ) )
757                 a[n++] = pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::NET_WM_PING );
758             XSetWMProtocols( GetXDisplay(), s_pSaveYourselfFrame->GetShellWindow(), a, n );
759         }
760     }
761 }
762 
763 X11SalFrame::~X11SalFrame()
764 {
765 	notifyDelete();
766 
767     if( m_pClipRectangles )
768     {
769         delete [] m_pClipRectangles;
770         m_pClipRectangles = NULL;
771         m_nCurClipRect = m_nMaxClipRect = 0;
772     }
773 
774     if( mhBackgroundPixmap )
775     {
776         XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None );
777         XFreePixmap( GetXDisplay(), mhBackgroundPixmap );
778     }
779 
780     if( mhStackingWindow )
781         aPresentationReparentList.remove( mhStackingWindow );
782 
783 	// remove from parent's list
784 	if( mpParent )
785 		mpParent->maChildren.remove( this );
786 
787     // deregister on SalDisplay
788     pDisplay_->deregisterFrame( this );
789 
790 	// unselect all events, some may be still in the queue anyway
791     if( ! IsSysChildWindow() )
792         XSelectInput( GetXDisplay(), GetShellWindow(), 0 );
793 	XSelectInput( GetXDisplay(), GetWindow(), 0 );
794 
795 	ShowFullScreen( sal_False, 0 );
796 
797 	if( bMapped_ )
798 		Show( sal_False );
799 
800     if( mpInputContext )
801     {
802         mpInputContext->UnsetICFocus( this );
803         mpInputContext->Unmap( this );
804         delete mpInputContext;
805     }
806 
807     if( GetWindow() == hPresentationWindow )
808     {
809         hPresentationWindow = None;
810         doReparentPresentationDialogues( GetDisplay() );
811     }
812 
813 	if( pGraphics_ )
814 	{
815 		pGraphics_->DeInit();
816 		delete pGraphics_;
817 	}
818 
819 	if( pFreeGraphics_ )
820 	{
821 		pFreeGraphics_->DeInit();
822 		delete pFreeGraphics_;
823 	}
824 
825 
826     XDestroyWindow( GetXDisplay(), mhWindow );
827 
828     /*
829      *  check if there is only the status frame left
830      *  if so, free it
831      */
832     if( ! GetDisplay()->getFrames().empty() && I18NStatus::exists() )
833     {
834         SalFrame* pStatusFrame = I18NStatus::get().getStatusFrame();
835         std::list< SalFrame* >::const_iterator sit = GetDisplay()->getFrames().begin();
836         if( pStatusFrame
837             && *sit == pStatusFrame
838             && ++sit == GetDisplay()->getFrames().end() )
839             vcl::I18NStatus::free();
840     }
841 
842     passOnSaveYourSelf();
843 }
844 
845 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
846 
847 void X11SalFrame::SetExtendedFrameStyle( SalExtStyle nStyle )
848 {
849     if( nStyle != mnExtStyle && ! IsChildWindow() )
850     {
851         mnExtStyle = nStyle;
852 
853         XClassHint* pClass = XAllocClassHint();
854         rtl::OString aResHint = X11SalData::getFrameResName( mnExtStyle );
855         pClass->res_name  = const_cast<char*>(aResHint.getStr());
856         pClass->res_class = const_cast<char*>(X11SalData::getFrameClassName());
857         XSetClassHint( GetXDisplay(), GetShellWindow(), pClass );
858         XFree( pClass );
859     }
860 }
861 
862 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
863 
864 void X11SalFrame::SetBackgroundBitmap( SalBitmap* pBitmap )
865 {
866     if( mhBackgroundPixmap )
867     {
868         XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), None );
869         XFreePixmap( GetXDisplay(), mhBackgroundPixmap );
870         mhBackgroundPixmap = None;
871     }
872     if( pBitmap )
873     {
874         X11SalBitmap* pBM = static_cast<X11SalBitmap*>(pBitmap);
875         Size aSize = pBM->GetSize();
876         if( aSize.Width() && aSize.Height() )
877         {
878             mhBackgroundPixmap =
879                 XCreatePixmap( GetXDisplay(),
880                                GetWindow(),
881                                aSize.Width(),
882                                aSize.Height(),
883                                GetDisplay()->GetVisual( m_nScreen ).GetDepth() );
884             if( mhBackgroundPixmap )
885             {
886                 SalTwoRect aTwoRect;
887                 aTwoRect.mnSrcX = aTwoRect.mnSrcY = aTwoRect.mnDestX = aTwoRect.mnDestY = 0;
888                 aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = aSize.Width();
889                 aTwoRect.mnSrcHeight = aTwoRect.mnDestHeight = aSize.Height();
890                 pBM->ImplDraw( mhBackgroundPixmap,
891                                m_nScreen,
892                                GetDisplay()->GetVisual( m_nScreen ).GetDepth(),
893                                aTwoRect, GetDisplay()->GetCopyGC( m_nScreen ) );
894                 XSetWindowBackgroundPixmap( GetXDisplay(), GetWindow(), mhBackgroundPixmap );
895             }
896         }
897     }
898 }
899 
900 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
901 
902 const SystemChildData* X11SalFrame::GetSystemData() const
903 {
904 	X11SalFrame *pFrame = const_cast<X11SalFrame*>(this);
905 	pFrame->maSystemChildData.nSize 		= sizeof( SystemChildData );
906 	pFrame->maSystemChildData.pDisplay		= GetXDisplay();
907 	pFrame->maSystemChildData.aWindow		= pFrame->GetWindow();
908 	pFrame->maSystemChildData.pSalFrame 	= pFrame;
909 	pFrame->maSystemChildData.pWidget		= NULL;
910 	pFrame->maSystemChildData.pVisual		= GetDisplay()->GetVisual( m_nScreen ).GetVisual();
911 	pFrame->maSystemChildData.nScreen		= m_nScreen;
912 	pFrame->maSystemChildData.nDepth		= GetDisplay()->GetVisual( m_nScreen ).GetDepth();
913 	pFrame->maSystemChildData.aColormap		= GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
914 	pFrame->maSystemChildData.pAppContext	= NULL;
915 	pFrame->maSystemChildData.aShellWindow	= pFrame->GetShellWindow();
916 	pFrame->maSystemChildData.pShellWidget	= NULL;
917 	return &maSystemChildData;
918 }
919 
920 SalGraphics *X11SalFrame::GetGraphics()
921 {
922 	if( pGraphics_ )
923 		return NULL;
924 
925 	if( pFreeGraphics_ )
926 	{
927 		pGraphics_		= pFreeGraphics_;
928 		pFreeGraphics_	= NULL;
929 	}
930 	else
931 	{
932 		pGraphics_ = new X11SalGraphics();
933 		pGraphics_->Init( this, GetWindow(), m_nScreen );
934 	}
935 
936 	return pGraphics_;
937 }
938 
939 void X11SalFrame::ReleaseGraphics( SalGraphics *pGraphics )
940 {
941     DBG_ASSERT( pGraphics == pGraphics_, "SalFrame::ReleaseGraphics pGraphics!=pGraphics_" );
942 
943 	if( pGraphics != pGraphics_ )
944 		return;
945 
946 	pFreeGraphics_	= pGraphics_;
947 	pGraphics_		= NULL;
948 }
949 
950 void X11SalFrame::updateGraphics( bool bClear )
951 {
952     Drawable aDrawable = bClear ? None : GetWindow();
953     if( pGraphics_ )
954         pGraphics_->SetDrawable( aDrawable, m_nScreen );
955     if( pFreeGraphics_ )
956         pFreeGraphics_->SetDrawable( aDrawable, m_nScreen );
957 }
958 
959 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
960 
961 void X11SalFrame::Enable( sal_Bool /*bEnable*/ )
962 {
963 	// NYI: enable/disable frame
964 }
965 
966 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
967 
968 void X11SalFrame::SetIcon( sal_uInt16 nIcon )
969 {
970     if ( ! IsChildWindow() )
971     {
972         // 0 == default icon -> #1
973         if ( nIcon == 0 )
974             nIcon = 1;
975 
976         mnIconID = nIcon;
977 
978         XIconSize *pIconSize = NULL;
979         int nSizes = 0;
980         int iconSize = 32;
981         if ( XGetIconSizes( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen ), &pIconSize, &nSizes ) )
982         {
983 #if OSL_DEBUG_LEVEL > 1
984             fprintf(stderr, "X11SalFrame::SetIcon(): found %d IconSizes:\n", nSizes);
985 #endif
986 
987             const int ourLargestIconSize = 48;
988             bool bFoundIconSize = false;
989 
990             int i;
991             for( i=0; i<nSizes; i++)
992             {
993                // select largest supported icon
994 
995                // Note: olwm/olvwm reports a huge max icon size of
996                // 160x160 pixels; always choosing the max as the
997                // preferred icon size is apparently wrong under olvwm
998                // - so we keep the safe default |iconSize| when we see
999                // unreasonable large max icon sizes (> twice of our
1000                // largest available icon) reported by XGetIconSizes.
1001                 if( pIconSize[i].max_width > iconSize
1002                     && pIconSize[i].max_width <= 2*ourLargestIconSize )
1003                 {
1004                     iconSize = pIconSize[i].max_width;
1005                     bFoundIconSize = true;
1006                 }
1007                 iconSize = pIconSize[i].max_width;
1008 
1009 #if OSL_DEBUG_LEVEL > 1
1010                 fprintf(stderr, "min: %d, %d\nmax: %d, %d\ninc: %d, %d\n\n",
1011                         pIconSize[i].min_width, pIconSize[i].min_height,
1012                         pIconSize[i].max_width, pIconSize[i].max_height,
1013                         pIconSize[i].width_inc, pIconSize[i].height_inc);
1014 #endif
1015             }
1016 
1017             if ( !bFoundIconSize )
1018             {
1019                // Unless someone has fixed olwm/olvwm, we have rejected
1020                // the max icon size from |XGetIconSizes()|.  Provide a
1021                // better icon size default value, in case our window manager
1022                // is olwm/olvwm.
1023                const String& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() );
1024 
1025                if ( rWM.EqualsAscii( "Olwm" ) )
1026                    iconSize = 48;
1027             }
1028 
1029             XFree( pIconSize );
1030         }
1031         else
1032         {
1033             const String& rWM( pDisplay_->getWMAdaptor()->getWindowManagerName() );
1034             if( rWM.EqualsAscii( "KWin" ) )			// assume KDE is running
1035                 iconSize = 48;
1036             static bool bGnomeIconSize = false;
1037             static bool bGnomeChecked = false;
1038             if( ! bGnomeChecked )
1039             {
1040                 bGnomeChecked=true;
1041                 int nCount = 0;
1042                 Atom* pProps = XListProperties( GetXDisplay(),
1043                                                 GetDisplay()->GetRootWindow( m_nScreen ),
1044                                                 &nCount );
1045                 for( int i = 0; i < nCount && !bGnomeIconSize; i++ )
1046                  {
1047                     char* pName = XGetAtomName( GetXDisplay(), pProps[i] );
1048                     if( !strcmp( pName, "GNOME_PANEL_DESKTOP_AREA" ) )
1049                         bGnomeIconSize = true;
1050                     if( pName )
1051                         XFree( pName );
1052                  }
1053                 if( pProps )
1054                     XFree( pProps );
1055             }
1056             if( bGnomeIconSize )
1057                 iconSize = 48;
1058         }
1059 
1060         XWMHints Hints;
1061         Hints.flags = 0;
1062 		XWMHints *pHints = XGetWMHints( GetXDisplay(), GetShellWindow() );
1063         if( pHints )
1064         {
1065             memcpy(&Hints, pHints, sizeof( XWMHints ));
1066             XFree( pHints );
1067         }
1068         pHints = &Hints;
1069 
1070 		sal_Bool bOk = SelectAppIconPixmap( GetDisplay(), m_nScreen,
1071                                         nIcon, iconSize,
1072                                         pHints->icon_pixmap, pHints->icon_mask );
1073         if ( !bOk )
1074         {
1075             // load default icon (0)
1076 		    bOk = SelectAppIconPixmap( GetDisplay(), m_nScreen,
1077                                        0, iconSize,
1078                                        pHints->icon_pixmap, pHints->icon_mask );
1079         }
1080 		if( bOk )
1081         {
1082     		pHints->flags 	 |= IconPixmapHint;
1083 		    if( pHints->icon_mask )
1084 			    pHints->flags |= IconMaskHint;
1085 
1086 		    XSetWMHints( GetXDisplay(), GetShellWindow(), pHints );
1087         }
1088 	}
1089 }
1090 
1091 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1092 
1093 void X11SalFrame::SetMaxClientSize( long nWidth, long nHeight )
1094 {
1095     if( ! IsChildWindow() )
1096     {
1097         if( GetShellWindow() && (nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
1098         {
1099             XSizeHints* pHints = XAllocSizeHints();
1100             long nSupplied = 0;
1101             XGetWMNormalHints( GetXDisplay(),
1102                                GetShellWindow(),
1103                                pHints,
1104                                &nSupplied
1105                                );
1106             pHints->max_width	= nWidth;
1107             pHints->max_height	= nHeight;
1108             pHints->flags |= PMaxSize;
1109             XSetWMNormalHints( GetXDisplay(),
1110                                GetShellWindow(),
1111                                pHints );
1112             XFree( pHints );
1113         }
1114     }
1115 }
1116 
1117 void X11SalFrame::SetMinClientSize( long nWidth, long nHeight )
1118 {
1119     if( ! IsChildWindow() )
1120     {
1121         if( GetShellWindow() && (nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
1122         {
1123             XSizeHints* pHints = XAllocSizeHints();
1124             long nSupplied = 0;
1125             XGetWMNormalHints( GetXDisplay(),
1126                                GetShellWindow(),
1127                                pHints,
1128                                &nSupplied
1129                                );
1130             pHints->min_width	= nWidth;
1131             pHints->min_height	= nHeight;
1132             pHints->flags |= PMinSize;
1133             XSetWMNormalHints( GetXDisplay(),
1134                                GetShellWindow(),
1135                                pHints );
1136             XFree( pHints );
1137         }
1138     }
1139 }
1140 
1141 // Show + Pos (x,y,z) + Size (width,height)
1142 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1143 void X11SalFrame::Show( sal_Bool bVisible, sal_Bool bNoActivate )
1144 {
1145     if( ( bVisible && bMapped_ )
1146         || ( !bVisible && !bMapped_ ) )
1147         return;
1148 
1149     // HACK: this is a workaround for (at least) kwin
1150     // even though transient frames should be kept above their parent
1151     // this does not necessarily hold true for DOCK type windows
1152     // so artificially set ABOVE and remove it again on hide
1153     if( mpParent && (mpParent->nStyle_ & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) && pDisplay_->getWMAdaptor()->isLegacyPartialFullscreen())
1154         pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bVisible );
1155 
1156 	bMapped_   = bVisible;
1157 	bViewable_ = bVisible;
1158     setXEmbedInfo();
1159 	if( bVisible )
1160 	{
1161         SessionManagerClient::open(); // will simply return after the first time
1162 
1163         mbInShow = sal_True;
1164         if( ! (nStyle_ & SAL_FRAME_STYLE_INTRO) )
1165         {
1166             // hide all INTRO frames
1167             const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
1168             for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
1169             {
1170                 const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
1171                 // look for intro bit map; if present, hide it
1172                 if( pFrame->nStyle_ & SAL_FRAME_STYLE_INTRO )
1173                 {
1174                     if( pFrame->bMapped_ )
1175                         const_cast<X11SalFrame*>(pFrame)->Show( sal_False );
1176                 }
1177             }
1178         }
1179 
1180         // update NET_WM_STATE which may have been deleted due to earlier Show(sal_False)
1181         if( nShowState_ == SHOWSTATE_HIDDEN )
1182             GetDisplay()->getWMAdaptor()->frameIsMapping( this );
1183 
1184         /*
1185          *  #95097#
1186          *  Actually this is rather exotic and currently happens only in conjunction
1187          *  with the basic dialogue editor,
1188          *  which shows a frame and instantly hides it again. After that the
1189          *  editor window is shown and the WM takes this as an opportunity
1190          *  to show our hidden transient frame also. So Show( sal_False ) must
1191          *  withdraw the frame AND delete the WM_TRANSIENT_FOR property.
1192          *  In case the frame is shown again, the transient hint must be restored here.
1193          */
1194         if(    ! IsChildWindow()
1195             && ! IsOverrideRedirect()
1196             && ! IsFloatGrabWindow()
1197             && mpParent
1198             )
1199         {
1200             GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent );
1201         }
1202 
1203         // #i45160# switch to desktop where a dialog with parent will appear
1204         if( mpParent && mpParent->m_nWorkArea != m_nWorkArea )
1205             GetDisplay()->getWMAdaptor()->switchToWorkArea( mpParent->m_nWorkArea );
1206 
1207         if( IsFloatGrabWindow() &&
1208             mpParent &&
1209             nVisibleFloats == 0 &&
1210             ! GetDisplay()->GetCaptureFrame() )
1211         {
1212             /* #i39420#
1213              * outsmart KWin's "focus strictly under mouse" mode
1214              * which insists on taking the focus from the document
1215              * to the new float. Grab focus to parent frame BEFORE
1216              * showing the float (cannot grab it to the float
1217              * before show).
1218              */
1219             XGrabPointer( GetXDisplay(),
1220                           mpParent->GetWindow(),
1221                           True,
1222                           PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
1223                           GrabModeAsync,
1224                           GrabModeAsync,
1225                           None,
1226                           mpParent ? mpParent->GetCursor() : None,
1227                           CurrentTime
1228                           );
1229         }
1230 
1231         XLIB_Time nUserTime = 0;
1232         if( ! bNoActivate && (nStyle_ & (SAL_FRAME_STYLE_OWNERDRAWDECORATION)) == 0 )
1233             nUserTime = pDisplay_->GetLastUserEventTime( true );
1234         GetDisplay()->getWMAdaptor()->setUserTime( this, nUserTime );
1235         if( ! bNoActivate && (nStyle_ & SAL_FRAME_STYLE_TOOLWINDOW) )
1236             m_bSetFocusOnMap = true;
1237 
1238         // actually map the window
1239         if( m_bXEmbed )
1240             askForXEmbedFocus( 0 );
1241         else
1242         {
1243             if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
1244             {
1245                 if( IsChildWindow() )
1246                     XMapWindow( GetXDisplay(), GetShellWindow() );
1247                 XSelectInput( GetXDisplay(), GetShellWindow(), CLIENT_EVENTS );
1248             }
1249             if( nStyle_ & SAL_FRAME_STYLE_FLOAT )
1250                 XMapRaised( GetXDisplay(), GetWindow() );
1251             else
1252                 XMapWindow( GetXDisplay(), GetWindow() );
1253         }
1254 		XSelectInput( GetXDisplay(), GetWindow(), CLIENT_EVENTS );
1255 
1256 		if( maGeometry.nWidth > 0
1257             && maGeometry.nHeight > 0
1258 			&& (   nWidth_  != (int)maGeometry.nWidth
1259 				|| nHeight_ != (int)maGeometry.nHeight ) )
1260 		{
1261 			nWidth_  = maGeometry.nWidth;
1262 			nHeight_ = maGeometry.nHeight;
1263 		}
1264 
1265 		XSync( GetXDisplay(), False );
1266 
1267         if( IsFloatGrabWindow() )
1268         {
1269             /*
1270              *  #95453#
1271              *  Sawfish and twm can be switched to enter-exit focus behaviour. In this case
1272              *  we must grab the pointer else the dumb WM will put the focus to the
1273              *  override-redirect float window. The application window will be deactivated
1274              *  which causes that the floats are destroyed, so the user can never click on
1275              *  a menu because it vanishes as soon as he enters it.
1276              */
1277             nVisibleFloats++;
1278             if( nVisibleFloats == 1 && ! GetDisplay()->GetCaptureFrame() )
1279             {
1280                 /* #i39420# now move grab to the new float window */
1281                 XGrabPointer( GetXDisplay(),
1282                               GetWindow(),
1283                               True,
1284                               PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
1285                               GrabModeAsync,
1286                               GrabModeAsync,
1287                               None,
1288                               mpParent ? mpParent->GetCursor() : None,
1289                               CurrentTime
1290                               );
1291             }
1292         }
1293 		CallCallback( SALEVENT_RESIZE, NULL );
1294 
1295         /*
1296          *  sometimes a message box/dialogue is brought up when a frame is not mapped
1297          *  the corresponding TRANSIENT_FOR hint is then set to the root window
1298          *  so that the dialogue shows in all cases. Correct it here if the
1299          *  frame is shown afterwards.
1300          */
1301         if( ! IsChildWindow()
1302             && ! IsOverrideRedirect()
1303             && ! IsFloatGrabWindow()
1304             )
1305         {
1306             for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
1307                  it != maChildren.end(); ++it )
1308             {
1309                 if( (*it)->mbTransientForRoot )
1310                     GetDisplay()->getWMAdaptor()->changeReferenceFrame( *it, this );
1311             }
1312         }
1313         /*
1314          *  leave SHOWSTATE_UNKNOWN as this indicates first mapping
1315          *  and is only reset int HandleSizeEvent
1316          */
1317         if( nShowState_ != SHOWSTATE_UNKNOWN )
1318             nShowState_ = SHOWSTATE_NORMAL;
1319 
1320         /*
1321          *  #98107# plugged windows don't necessarily get the
1322          *  focus on show because the parent may already be mapped
1323          *  and have the focus. So try to set the focus
1324          *  to the child on Show(sal_True)
1325          */
1326         if( (nStyle_ & SAL_FRAME_STYLE_PLUG) && ! m_bXEmbed )
1327             XSetInputFocus( GetXDisplay(),
1328                             GetWindow(),
1329                             RevertToParent,
1330                             CurrentTime );
1331 
1332         if( mpParent )
1333         {
1334             // push this frame so it will be in front of its siblings
1335             // only necessary for insane transient behaviour of Dtwm/olwm
1336             mpParent->maChildren.remove( this );
1337             mpParent->maChildren.push_front(this);
1338         }
1339 	}
1340 	else
1341 	{
1342         if( getInputContext() )
1343             getInputContext()->Unmap( this );
1344 
1345         if( ! IsChildWindow() )
1346         {
1347             /*  FIXME: Is deleting the property really necessary ? It hurts
1348              *  owner drawn windows at least.
1349              */
1350             if( mpParent && ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
1351                 XDeleteProperty( GetXDisplay(), GetShellWindow(), GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::WM_TRANSIENT_FOR ) );
1352             XWithdrawWindow( GetXDisplay(), GetShellWindow(), m_nScreen );
1353         }
1354         else if( ! m_bXEmbed )
1355             XUnmapWindow( GetXDisplay(), GetWindow() );
1356 
1357         nShowState_ = SHOWSTATE_HIDDEN;
1358         if( IsFloatGrabWindow() && nVisibleFloats )
1359         {
1360             nVisibleFloats--;
1361             if( nVisibleFloats == 0  && ! GetDisplay()->GetCaptureFrame() )
1362                 XUngrabPointer( GetXDisplay(),
1363                                 CurrentTime );
1364         }
1365         // flush here; there may be a very seldom race between
1366         // the display connection used for clipboard and our connection
1367         Flush();
1368 	}
1369 }
1370 
1371 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1372 void X11SalFrame::ToTop( sal_uInt16 nFlags )
1373 {
1374 	if( ( nFlags & SAL_FRAME_TOTOP_RESTOREWHENMIN )
1375         && ! ( nStyle_ & SAL_FRAME_STYLE_FLOAT )
1376         && nShowState_ != SHOWSTATE_HIDDEN
1377         && nShowState_ != SHOWSTATE_UNKNOWN
1378         )
1379     {
1380         GetDisplay()->getWMAdaptor()->frameIsMapping( this );
1381         if( GetWindow() != GetShellWindow() && ! IsSysChildWindow() )
1382             XMapWindow( GetXDisplay(), GetShellWindow() );
1383         XMapWindow( GetXDisplay(), GetWindow() );
1384     }
1385 
1386     XLIB_Window aToTopWindow = IsSysChildWindow() ? GetWindow() : GetShellWindow();
1387     if( ! (nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY) )
1388     {
1389         XRaiseWindow( GetXDisplay(), aToTopWindow );
1390         if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected() )
1391             for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
1392                  it != maChildren.end(); ++it )
1393                 (*it)->ToTop( nFlags & ~SAL_FRAME_TOTOP_GRABFOCUS );
1394     }
1395 
1396     if( ( ( nFlags & SAL_FRAME_TOTOP_GRABFOCUS ) || ( nFlags & SAL_FRAME_TOTOP_GRABFOCUS_ONLY ) )
1397         && bMapped_ )
1398     {
1399         if( m_bXEmbed )
1400             askForXEmbedFocus( 0 );
1401         else
1402             XSetInputFocus( GetXDisplay(), aToTopWindow, RevertToParent, CurrentTime );
1403     }
1404 }
1405 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1406 void X11SalFrame::GetWorkArea( Rectangle& rWorkArea )
1407 {
1408     rWorkArea = pDisplay_->getWMAdaptor()->getWorkArea( 0 );
1409 }
1410 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1411 void X11SalFrame::GetClientSize( long &rWidth, long &rHeight )
1412 {
1413 	if( ! bViewable_  )
1414 	{
1415 		rWidth = rHeight = 0;
1416 		return;
1417 	}
1418 
1419 	rWidth	= maGeometry.nWidth;
1420 	rHeight = maGeometry.nHeight;
1421 
1422 	if( !rWidth || !rHeight )
1423 	{
1424 		XWindowAttributes aAttrib;
1425 
1426 		XGetWindowAttributes( GetXDisplay(), GetWindow(), &aAttrib );
1427 
1428 		maGeometry.nWidth = rWidth = aAttrib.width;
1429 		maGeometry.nHeight = rHeight = aAttrib.height;
1430 	}
1431 }
1432 
1433 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1434 
1435 void X11SalFrame::SetWindowGravity (int nGravity) const
1436 {
1437     if( ! IsChildWindow() )
1438     {
1439         XSizeHints* pHint = XAllocSizeHints();
1440         long        nFlag;
1441 
1442         XGetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint, &nFlag);
1443         pHint->flags       |= PWinGravity;
1444         pHint->win_gravity  = nGravity;
1445 
1446         XSetWMNormalHints (GetXDisplay(), GetShellWindow(), pHint);
1447         XSync (GetXDisplay(), False);
1448 
1449         XFree (pHint);
1450     }
1451 }
1452 
1453 void X11SalFrame::Center( )
1454 {
1455 	int 			nX, nY, nScreenWidth, nScreenHeight;
1456 	int				nRealScreenWidth, nRealScreenHeight;
1457 	int				nScreenX = 0, nScreenY = 0;
1458 
1459     const Size& aScreenSize = GetDisplay()->getDataForScreen( m_nScreen ).m_aSize;
1460     nScreenWidth		= aScreenSize.Width();
1461     nScreenHeight		= aScreenSize.Height();
1462     nRealScreenWidth	= nScreenWidth;
1463     nRealScreenHeight	= nScreenHeight;
1464 
1465     if( GetDisplay()->IsXinerama() )
1466     {
1467         // get xinerama screen we are on
1468         // if there is a parent, use its center for screen determination
1469         // else use the pointer
1470         XLIB_Window aRoot, aChild;
1471         int root_x, root_y, x, y;
1472         unsigned int mask;
1473         if( mpParent )
1474         {
1475             root_x = mpParent->maGeometry.nX + mpParent->maGeometry.nWidth/2;
1476             root_y = mpParent->maGeometry.nY + mpParent->maGeometry.nHeight/2;
1477         }
1478         else
1479             XQueryPointer( GetXDisplay(),
1480                            GetShellWindow(),
1481                            &aRoot, &aChild,
1482                            &root_x, &root_y,
1483                            &x, &y,
1484                            &mask );
1485         const std::vector< Rectangle >& rScreens = GetDisplay()->GetXineramaScreens();
1486         for( unsigned int i = 0; i < rScreens.size(); i++ )
1487             if( rScreens[i].IsInside( Point( root_x, root_y ) ) )
1488             {
1489                 nScreenX			= rScreens[i].Left();
1490                 nScreenY			= rScreens[i].Top();
1491                 nRealScreenWidth	= rScreens[i].GetWidth();
1492                 nRealScreenHeight	= rScreens[i].GetHeight();
1493                 break;
1494             }
1495     }
1496 
1497 	if( mpParent )
1498 	{
1499 		X11SalFrame* pFrame = mpParent;
1500 		while( pFrame->mpParent )
1501 			pFrame = pFrame->mpParent;
1502 		if( pFrame->maGeometry.nWidth < 1  || pFrame->maGeometry.nHeight < 1 )
1503         {
1504             Rectangle aRect;
1505 			pFrame->GetPosSize( aRect );
1506             pFrame->maGeometry.nX		= aRect.Left();
1507             pFrame->maGeometry.nY		= aRect.Top();
1508             pFrame->maGeometry.nWidth	= aRect.GetWidth();
1509             pFrame->maGeometry.nHeight	= aRect.GetHeight();
1510         }
1511 
1512 		if( pFrame->nStyle_ & SAL_FRAME_STYLE_PLUG )
1513 		{
1514 			XLIB_Window aRoot;
1515 			unsigned int bw, depth;
1516 			XGetGeometry( GetXDisplay(),
1517 						  pFrame->GetShellWindow(),
1518 						  &aRoot,
1519 						  &nScreenX, &nScreenY,
1520 						  (unsigned int*)&nScreenWidth,
1521 						  (unsigned int*)&nScreenHeight,
1522 						  &bw, &depth );
1523 		}
1524 		else
1525 		{
1526 			nScreenX		= pFrame->maGeometry.nX;
1527 			nScreenY		= pFrame->maGeometry.nY;
1528 			nScreenWidth	= pFrame->maGeometry.nWidth;
1529 			nScreenHeight	= pFrame->maGeometry.nHeight;
1530 		}
1531 	}
1532 
1533 	if( mpParent && mpParent->nShowState_ == SHOWSTATE_NORMAL )
1534 	{
1535 		if( maGeometry.nWidth >= mpParent->maGeometry.nWidth &&
1536 			maGeometry.nHeight >= mpParent->maGeometry.nHeight )
1537 		{
1538 			nX = nScreenX + 40;
1539 			nY = nScreenY + 40;
1540 		}
1541 		else
1542 		{
1543 			// center the window relative to the top level frame
1544 			nX = (nScreenWidth	- (int)maGeometry.nWidth ) / 2 + nScreenX;
1545 			nY = (nScreenHeight - (int)maGeometry.nHeight) / 2 + nScreenY;
1546 		}
1547 	}
1548 	else
1549 	{
1550 		// center the window relative to screen
1551 		nX = (nRealScreenWidth	- (int)maGeometry.nWidth ) / 2 + nScreenX;
1552 		nY = (nRealScreenHeight - (int)maGeometry.nHeight) / 2 + nScreenY;
1553 	}
1554     nX = nX < 0 ? 0 : nX;
1555     nY = nY < 0 ? 0 : nY;
1556 
1557 	bDefaultPosition_ = False;
1558     if( mpParent )
1559     {
1560         nX -= mpParent->maGeometry.nX;
1561         nY -= mpParent->maGeometry.nY;
1562     }
1563 
1564     Point aPoint(nX, nY);
1565 	SetPosSize( Rectangle( aPoint, Size( maGeometry.nWidth, maGeometry.nHeight ) ) );
1566 }
1567 
1568 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1569 void X11SalFrame::updateScreenNumber()
1570 {
1571     if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
1572     {
1573         Point aPoint( maGeometry.nX, maGeometry.nY );
1574         const std::vector<Rectangle>& rScreenRects( GetDisplay()->GetXineramaScreens() );
1575         size_t nScreens = rScreenRects.size();
1576         for( size_t i = 0; i < nScreens; i++ )
1577         {
1578             if( rScreenRects[i].IsInside( aPoint ) )
1579             {
1580                 maGeometry.nScreenNumber = static_cast<unsigned int>(i);
1581                 break;
1582             }
1583         }
1584     }
1585     else
1586         maGeometry.nScreenNumber = static_cast<unsigned int>(m_nScreen);
1587 }
1588 
1589 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1590 void X11SalFrame::SetPosSize( long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags )
1591 {
1592     if( nStyle_ & SAL_FRAME_STYLE_PLUG )
1593         return;
1594 
1595     // relative positioning in X11SalFrame::SetPosSize
1596     Rectangle aPosSize( Point( maGeometry.nX, maGeometry.nY ), Size( maGeometry.nWidth, maGeometry.nHeight ) );
1597     aPosSize.Justify();
1598 
1599     if( ! ( nFlags & SAL_FRAME_POSSIZE_X ) )
1600     {
1601         nX = aPosSize.Left();
1602         if( mpParent )
1603             nX -= mpParent->maGeometry.nX;
1604     }
1605     if( ! ( nFlags & SAL_FRAME_POSSIZE_Y ) )
1606     {
1607         nY = aPosSize.Top();
1608         if( mpParent )
1609             nY -= mpParent->maGeometry.nY;
1610     }
1611     if( ! ( nFlags & SAL_FRAME_POSSIZE_WIDTH ) )
1612         nWidth = aPosSize.GetWidth();
1613     if( ! ( nFlags & SAL_FRAME_POSSIZE_HEIGHT ) )
1614         nHeight = aPosSize.GetHeight();
1615 
1616     aPosSize = Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) );
1617 
1618     if( ! ( nFlags & ( SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y ) ) )
1619     {
1620         if( bDefaultPosition_ )
1621         {
1622             maGeometry.nWidth = aPosSize.GetWidth();
1623             maGeometry.nHeight = aPosSize.GetHeight();
1624             Center();
1625         }
1626         else
1627             SetSize( Size( nWidth, nHeight ) );
1628     }
1629     else
1630         SetPosSize( aPosSize );
1631 
1632     bDefaultPosition_ = False;
1633 }
1634 
1635 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1636 void X11SalFrame::SetAlwaysOnTop( sal_Bool bOnTop )
1637 {
1638     if( ! IsOverrideRedirect() )
1639     {
1640         bAlwaysOnTop_ = bOnTop;
1641         pDisplay_->getWMAdaptor()->enableAlwaysOnTop( this, bOnTop );
1642     }
1643 }
1644 
1645 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1646 
1647 #define _FRAMESTATE_MASK_GEOMETRY \
1648      (SAL_FRAMESTATE_MASK_X     | SAL_FRAMESTATE_MASK_Y |   \
1649       SAL_FRAMESTATE_MASK_WIDTH | SAL_FRAMESTATE_MASK_HEIGHT)
1650 #define _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY \
1651      (SAL_FRAMESTATE_MASK_MAXIMIZED_X     | SAL_FRAMESTATE_MASK_MAXIMIZED_Y |   \
1652       SAL_FRAMESTATE_MASK_MAXIMIZED_WIDTH | SAL_FRAMESTATE_MASK_MAXIMIZED_HEIGHT)
1653 
1654 void X11SalFrame::SetWindowState( const SalFrameState *pState )
1655 {
1656     if (pState == NULL)
1657         return;
1658 
1659     // Request for position or size change
1660     if (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY)
1661     {
1662         Rectangle aPosSize;
1663         bool bDoAdjust = false;
1664 
1665         /* #i44325#
1666          * if maximized, set restore size and guess maximized size from last time
1667          * in state change below maximize window
1668          */
1669         if( ! IsChildWindow() &&
1670             (pState->mnMask & SAL_FRAMESTATE_MASK_STATE) &&
1671             (pState->mnState & SAL_FRAMESTATE_MAXIMIZED) &&
1672             (pState->mnMask & _FRAMESTATE_MASK_GEOMETRY) == _FRAMESTATE_MASK_GEOMETRY &&
1673             (pState->mnMask & _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY) == _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY
1674             )
1675         {
1676             XSizeHints* pHints = XAllocSizeHints();
1677             long nSupplied = 0;
1678             XGetWMNormalHints( GetXDisplay(),
1679                                GetShellWindow(),
1680                                pHints,
1681                                &nSupplied );
1682             pHints->flags |= PPosition | PWinGravity;
1683             pHints->x			= pState->mnX;
1684             pHints->y			= pState->mnY;
1685             pHints->win_gravity	= pDisplay_->getWMAdaptor()->getPositionWinGravity();
1686             XSetWMNormalHints( GetXDisplay(),
1687                                GetShellWindow(),
1688                                pHints );
1689             XFree( pHints );
1690 
1691             XMoveResizeWindow( GetXDisplay(), GetShellWindow(),
1692                                pState->mnX, pState->mnY,
1693                                pState->mnWidth, pState->mnHeight );
1694             // guess maximized geometry from last time
1695             maGeometry.nX      = pState->mnMaximizedX;
1696             maGeometry.nY      = pState->mnMaximizedY;
1697             maGeometry.nWidth  = pState->mnMaximizedWidth;
1698             maGeometry.nHeight = pState->mnMaximizedHeight;
1699             updateScreenNumber();
1700         }
1701         else
1702         {
1703             // initialize with current geometry
1704             if ((pState->mnMask & _FRAMESTATE_MASK_GEOMETRY) != _FRAMESTATE_MASK_GEOMETRY)
1705                 GetPosSize (aPosSize);
1706 
1707             // change requested properties
1708             if (pState->mnMask & SAL_FRAMESTATE_MASK_X)
1709             {
1710                 aPosSize.setX (pState->mnX);
1711             }
1712             if (pState->mnMask & SAL_FRAMESTATE_MASK_Y)
1713             {
1714                 aPosSize.setY (pState->mnY);
1715             }
1716             if (pState->mnMask & SAL_FRAMESTATE_MASK_WIDTH)
1717             {
1718                 long nWidth = pState->mnWidth > 0 ? pState->mnWidth  - 1 : 0;
1719                 aPosSize.setWidth (nWidth);
1720                 bDoAdjust = true;
1721             }
1722             if (pState->mnMask & SAL_FRAMESTATE_MASK_HEIGHT)
1723             {
1724                 int nHeight = pState->mnHeight > 0 ? pState->mnHeight - 1 : 0;
1725                 aPosSize.setHeight (nHeight);
1726                 bDoAdjust = true;
1727             }
1728 
1729             const Size& aScreenSize = pDisplay_->getDataForScreen( m_nScreen ).m_aSize;
1730             const WMAdaptor *pWM = GetDisplay()->getWMAdaptor();
1731 
1732             if( bDoAdjust && aPosSize.GetWidth() <= aScreenSize.Width()
1733                 && aPosSize.GetHeight() <= aScreenSize.Height() )
1734             {
1735                 SalFrameGeometry aGeom = maGeometry;
1736 
1737                 if( ! (nStyle_ & ( SAL_FRAME_STYLE_FLOAT | SAL_FRAME_STYLE_PLUG ) ) &&
1738                     mpParent &&
1739                 aGeom.nLeftDecoration == 0 &&
1740                 aGeom.nTopDecoration == 0 )
1741                 {
1742                     aGeom = mpParent->maGeometry;
1743                     if( aGeom.nLeftDecoration == 0 &&
1744                         aGeom.nTopDecoration == 0 )
1745                     {
1746                         aGeom.nLeftDecoration = 5;
1747                         aGeom.nTopDecoration = 20;
1748                         aGeom.nRightDecoration = 5;
1749                         aGeom.nBottomDecoration = 5;
1750                     }
1751                 }
1752 
1753                 // adjust position so that frame fits onto screen
1754                 if( aPosSize.Right()+(long)aGeom.nRightDecoration > aScreenSize.Width()-1 )
1755                     aPosSize.Move( (long)aScreenSize.Width() - (long)aPosSize.Right() - (long)aGeom.nRightDecoration, 0 );
1756                 if( aPosSize.Bottom()+(long)aGeom.nBottomDecoration > aScreenSize.Height()-1 )
1757                     aPosSize.Move( 0, (long)aScreenSize.Height() - (long)aPosSize.Bottom() - (long)aGeom.nBottomDecoration );
1758                 if( aPosSize.Left() < (long)aGeom.nLeftDecoration )
1759                     aPosSize.Move( (long)aGeom.nLeftDecoration - (long)aPosSize.Left(), 0 );
1760                 if( aPosSize.Top() < (long)aGeom.nTopDecoration )
1761                     aPosSize.Move( 0, (long)aGeom.nTopDecoration - (long)aPosSize.Top() );
1762             }
1763 
1764             // resize with new args
1765             if (pWM->supportsICCCMPos())
1766             {
1767                 if( mpParent )
1768                     aPosSize.Move( -mpParent->maGeometry.nX,
1769                 -mpParent->maGeometry.nY );
1770                 SetPosSize( aPosSize );
1771                 bDefaultPosition_ = False;
1772             }
1773             else
1774                 SetPosSize( 0, 0, aPosSize.GetWidth(), aPosSize.GetHeight(), SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
1775         }
1776     }
1777 
1778     // request for status change
1779     if (pState->mnMask & SAL_FRAMESTATE_MASK_STATE)
1780     {
1781 	    if (pState->mnState & SAL_FRAMESTATE_MAXIMIZED)
1782 	    {
1783 		    nShowState_ = SHOWSTATE_NORMAL;
1784             if( ! (pState->mnState & (SAL_FRAMESTATE_MAXIMIZED_HORZ|SAL_FRAMESTATE_MAXIMIZED_VERT) ) )
1785                 Maximize();
1786             else
1787             {
1788                 bool bHorz = (pState->mnState & SAL_FRAMESTATE_MAXIMIZED_HORZ) ? true : false;
1789                 bool bVert = (pState->mnState & SAL_FRAMESTATE_MAXIMIZED_VERT) ? true : false;
1790                 GetDisplay()->getWMAdaptor()->maximizeFrame( this, bHorz, bVert );
1791             }
1792             maRestorePosSize.Left() = pState->mnX;
1793             maRestorePosSize.Top() = pState->mnY;
1794             maRestorePosSize.Right() = maRestorePosSize.Left() + pState->mnWidth;
1795             maRestorePosSize.Right() = maRestorePosSize.Left() + pState->mnHeight;
1796 	    }
1797         else if( mbMaximizedHorz || mbMaximizedVert )
1798             GetDisplay()->getWMAdaptor()->maximizeFrame( this, false, false );
1799 
1800 	    if (pState->mnState & SAL_FRAMESTATE_MINIMIZED)
1801 	    {
1802 		    if (nShowState_ == SHOWSTATE_UNKNOWN)
1803 			    nShowState_ = SHOWSTATE_NORMAL;
1804 		    Minimize();
1805         }
1806         if (pState->mnState & SAL_FRAMESTATE_NORMAL)
1807         {
1808             if (nShowState_ != SHOWSTATE_NORMAL)
1809                 Restore();
1810         }
1811         if (pState->mnState & SAL_FRAMESTATE_ROLLUP)
1812             GetDisplay()->getWMAdaptor()->shade( this, true );
1813 	}
1814 }
1815 
1816 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1817 sal_Bool X11SalFrame::GetWindowState( SalFrameState* pState )
1818 {
1819 	if( SHOWSTATE_MINIMIZED == nShowState_ )
1820 		pState->mnState = SAL_FRAMESTATE_MINIMIZED;
1821 	else
1822 		pState->mnState = SAL_FRAMESTATE_NORMAL;
1823 
1824 	Rectangle aPosSize;
1825     if( maRestorePosSize.IsEmpty() )
1826         GetPosSize( aPosSize );
1827     else
1828         aPosSize = maRestorePosSize;
1829 
1830     if( mbMaximizedHorz )
1831         pState->mnState |= SAL_FRAMESTATE_MAXIMIZED_HORZ;
1832     if( mbMaximizedVert )
1833         pState->mnState |= SAL_FRAMESTATE_MAXIMIZED_VERT;
1834     if( mbShaded )
1835         pState->mnState |= SAL_FRAMESTATE_ROLLUP;
1836 
1837 	pState->mnX 	 = aPosSize.Left();
1838 	pState->mnY 	 = aPosSize.Top();
1839 	pState->mnWidth  = aPosSize.GetWidth();
1840 	pState->mnHeight = aPosSize.GetHeight();
1841 
1842     pState->mnMask   = _FRAMESTATE_MASK_GEOMETRY | SAL_FRAMESTATE_MASK_STATE;
1843 
1844 
1845 	if (! maRestorePosSize.IsEmpty() )
1846 	{
1847         GetPosSize( aPosSize );
1848 		pState->mnState |= SAL_FRAMESTATE_MAXIMIZED;
1849         pState->mnMaximizedX      = aPosSize.Left();
1850         pState->mnMaximizedY      = aPosSize.Top();
1851         pState->mnMaximizedWidth  = aPosSize.GetWidth();
1852         pState->mnMaximizedHeight = aPosSize.GetHeight();
1853         pState->mnMask |= _FRAMESTATE_MASK_MAXIMIZED_GEOMETRY;
1854 	}
1855 
1856 	return sal_True;
1857 }
1858 
1859 // ----------------------------------------------------------------------------
1860 // get a screenshot of the current frame including window manager decoration
1861 SalBitmap* X11SalFrame::SnapShot()
1862 {
1863     Display* pDisplay = GetXDisplay();
1864 
1865     // make sure the frame has been reparented and all paint timer have been
1866     // expired
1867     do
1868     {
1869         XSync(pDisplay, False);
1870         Application::Reschedule ();
1871     }
1872     while (XPending(pDisplay));
1873     TimeValue aVal;
1874     aVal.Seconds = 0;
1875     aVal.Nanosec = 50000000;
1876     osl_waitThread( &aVal );
1877     do
1878     {
1879         XSync(pDisplay, False);
1880         Application::Reschedule ();
1881     }
1882     while (XPending(pDisplay));
1883 
1884     // get the most outer window, usually the window manager decoration
1885     Drawable hWindow = None;
1886     if (IsOverrideRedirect())
1887         hWindow = GetDrawable();
1888     else
1889     if (hPresentationWindow != None)
1890         hWindow = hPresentationWindow;
1891     else
1892         hWindow = GetStackingWindow();
1893 
1894     // query the contents of the window
1895     if (hWindow != None)
1896     {
1897         X11SalBitmap *pBmp = new X11SalBitmap;
1898         if (pBmp->SnapShot (pDisplay, hWindow))
1899             return pBmp;
1900         else
1901             delete pBmp;
1902     }
1903 
1904     return NULL;
1905 }
1906 
1907 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1908 
1909 // native menu implementation - currently empty
1910 void X11SalFrame::DrawMenuBar()
1911 {
1912 }
1913 
1914 void X11SalFrame::SetMenu( SalMenu* )
1915 {
1916 }
1917 
1918 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1919 void X11SalFrame::GetPosSize( Rectangle &rPosSize )
1920 {
1921 	if( maGeometry.nWidth < 1 || maGeometry.nHeight < 1 )
1922 	{
1923         const Size& aScreenSize = pDisplay_->getDataForScreen( m_nScreen ).m_aSize;
1924 		long w = aScreenSize.Width()  - maGeometry.nLeftDecoration - maGeometry.nRightDecoration;
1925 		long h = aScreenSize.Height() - maGeometry.nTopDecoration - maGeometry.nBottomDecoration;
1926 
1927 		rPosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ), Size( w, h ) );
1928 	}
1929 	else
1930 		rPosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ),
1931                               Size( maGeometry.nWidth, maGeometry.nHeight ) );
1932 }
1933 
1934 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1935 void X11SalFrame::SetSize( const Size &rSize )
1936 {
1937 	if( rSize.Width() > 0 && rSize.Height() > 0 )
1938 	{
1939  		if( ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
1940             && ! IsChildWindow()
1941             && ( nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT )
1942  		{
1943             XSizeHints* pHints = XAllocSizeHints();
1944             long nSupplied = 0;
1945             XGetWMNormalHints( GetXDisplay(),
1946                                GetShellWindow(),
1947                                pHints,
1948                                &nSupplied
1949                                );
1950             pHints->min_width	= rSize.Width();
1951             pHints->min_height	= rSize.Height();
1952             pHints->max_width	= rSize.Width();
1953             pHints->max_height	= rSize.Height();
1954             pHints->flags |= PMinSize | PMaxSize;
1955             XSetWMNormalHints( GetXDisplay(),
1956                                GetShellWindow(),
1957                                pHints );
1958             XFree( pHints );
1959  		}
1960         XResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), rSize.Width(), rSize.Height() );
1961         if( GetWindow() != GetShellWindow() )
1962         {
1963             if( (nStyle_ & SAL_FRAME_STYLE_PLUG ) )
1964                 XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, rSize.Width(), rSize.Height() );
1965             else
1966                 XResizeWindow( GetXDisplay(), GetWindow(), rSize.Width(), rSize.Height() );
1967         }
1968 
1969         maGeometry.nWidth  = rSize.Width();
1970         maGeometry.nHeight = rSize.Height();
1971 
1972 		// allow the external status window to reposition
1973 		if (mbInputFocus && mpInputContext != NULL)
1974 			mpInputContext->SetICFocus ( this );
1975 	}
1976 }
1977 
1978 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1979 
1980 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1981 
1982 void X11SalFrame::SetPosSize( const Rectangle &rPosSize )
1983 {
1984 	XWindowChanges values;
1985 	values.x		= rPosSize.Left();
1986 	values.y		= rPosSize.Top();
1987 	values.width	= rPosSize.GetWidth();
1988 	values.height	= rPosSize.GetHeight();
1989 
1990     if( !values.width || !values.height )
1991         return;
1992 
1993  	if( mpParent && ! IsSysChildWindow() )
1994  	{
1995         // --- RTL --- (mirror window pos)
1996         if( Application::GetSettings().GetLayoutRTL() )
1997             values.x = mpParent->maGeometry.nWidth-values.width-1-values.x;
1998 
1999  		XLIB_Window aChild;
2000  		// coordinates are relative to parent, so translate to root coordinates
2001  		XTranslateCoordinates( GetDisplay()->GetDisplay(),
2002  							   mpParent->GetWindow(),
2003  							   GetDisplay()->GetRootWindow( m_nScreen ),
2004  							   values.x, values.y,
2005  							   &values.x, &values.y,
2006  							   & aChild );
2007  	}
2008 
2009     bool bMoved = false;
2010     bool bSized = false;
2011     if( values.x != maGeometry.nX || values.y != maGeometry.nY )
2012         bMoved = true;
2013     if( values.width != (int)maGeometry.nWidth || values.height != (int)maGeometry.nHeight )
2014         bSized = true;
2015 
2016 	if( ! ( nStyle_ & ( SAL_FRAME_STYLE_PLUG | SAL_FRAME_STYLE_FLOAT ) )
2017         && !(pDisplay_->GetProperties() & PROPERTY_SUPPORT_WM_ClientPos) )
2018     {
2019         values.x	-= maGeometry.nLeftDecoration;
2020         values.y	-= maGeometry.nTopDecoration;
2021     }
2022 
2023     // do net set WMNormalHints for ..
2024     if(
2025         // child windows
2026         ! IsChildWindow()
2027         // popups (menu, help window, etc.)
2028         && 	(nStyle_ & (SAL_FRAME_STYLE_FLOAT|SAL_FRAME_STYLE_OWNERDRAWDECORATION) ) != SAL_FRAME_STYLE_FLOAT
2029         // shown, sizeable windows
2030         && ( nShowState_ == SHOWSTATE_UNKNOWN ||
2031              nShowState_ == SHOWSTATE_HIDDEN ||
2032              ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE )
2033              )
2034         )
2035     {
2036         XSizeHints* pHints = XAllocSizeHints();
2037         long nSupplied = 0;
2038         XGetWMNormalHints( GetXDisplay(),
2039                            GetShellWindow(),
2040                            pHints,
2041                            &nSupplied
2042                            );
2043         if( ! ( nStyle_ & SAL_FRAME_STYLE_SIZEABLE ) )
2044         {
2045             pHints->min_width	= rPosSize.GetWidth();
2046             pHints->min_height	= rPosSize.GetHeight();
2047             pHints->max_width	= rPosSize.GetWidth();
2048             pHints->max_height	= rPosSize.GetHeight();
2049             pHints->flags |= PMinSize | PMaxSize;
2050         }
2051         if( nShowState_ == SHOWSTATE_UNKNOWN || nShowState_ == SHOWSTATE_HIDDEN )
2052         {
2053             pHints->flags |= PPosition | PWinGravity;
2054             pHints->x			= values.x;
2055             pHints->y			= values.y;
2056             pHints->win_gravity	= pDisplay_->getWMAdaptor()->getPositionWinGravity();
2057         }
2058         if( mbFullScreen )
2059         {
2060             pHints->max_width	= 10000;
2061             pHints->max_height	= 10000;
2062             pHints->flags |= PMaxSize;
2063         }
2064         XSetWMNormalHints( GetXDisplay(),
2065                            GetShellWindow(),
2066                            pHints );
2067         XFree( pHints );
2068     }
2069 
2070     XMoveResizeWindow( GetXDisplay(), IsSysChildWindow() ? GetWindow() : GetShellWindow(), values.x, values.y, values.width, values.height );
2071     if( GetShellWindow() != GetWindow() )
2072     {
2073         if( (nStyle_ & SAL_FRAME_STYLE_PLUG ) )
2074             XMoveResizeWindow( GetXDisplay(), GetWindow(), 0, 0, values.width, values.height );
2075         else
2076             XMoveResizeWindow( GetXDisplay(), GetWindow(), values.x, values.y, values.width, values.height );
2077     }
2078 
2079     maGeometry.nX		= values.x;
2080     maGeometry.nY		= values.y;
2081     maGeometry.nWidth	= values.width;
2082     maGeometry.nHeight	= values.height;
2083     if( IsSysChildWindow() && mpParent )
2084     {
2085         // translate back to root coordinates
2086         maGeometry.nX += mpParent->maGeometry.nX;
2087         maGeometry.nY += mpParent->maGeometry.nY;
2088     }
2089 
2090     updateScreenNumber();
2091     if( bSized && ! bMoved )
2092         CallCallback( SALEVENT_RESIZE, NULL );
2093     else if( bMoved && ! bSized )
2094         CallCallback( SALEVENT_MOVE, NULL );
2095     else
2096         CallCallback( SALEVENT_MOVERESIZE, NULL );
2097 
2098 	// allow the external status window to reposition
2099 	if (mbInputFocus && mpInputContext != NULL)
2100 		mpInputContext->SetICFocus ( this );
2101 }
2102 
2103 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2104 void X11SalFrame::Minimize()
2105 {
2106     if( IsSysChildWindow() )
2107         return;
2108 
2109 	if( SHOWSTATE_UNKNOWN == nShowState_ || SHOWSTATE_HIDDEN == nShowState_ )
2110 	{
2111 		stderr0( "X11SalFrame::Minimize on withdrawn window\n" );
2112 		return;
2113 	}
2114 
2115 	if( XIconifyWindow( GetXDisplay(),
2116 						GetShellWindow(),
2117 						pDisplay_->GetDefaultScreenNumber() ) )
2118 		nShowState_ = SHOWSTATE_MINIMIZED;
2119 }
2120 
2121 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2122 void X11SalFrame::Maximize()
2123 {
2124     if( IsSysChildWindow() )
2125         return;
2126 
2127 	if( SHOWSTATE_MINIMIZED == nShowState_ )
2128 	{
2129         GetDisplay()->getWMAdaptor()->frameIsMapping( this );
2130 		XMapWindow( GetXDisplay(), GetShellWindow() );
2131 		nShowState_ = SHOWSTATE_NORMAL;
2132 	}
2133 
2134     pDisplay_->getWMAdaptor()->maximizeFrame( this, true, true );
2135 }
2136 
2137 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2138 void X11SalFrame::Restore()
2139 {
2140     if( IsSysChildWindow() )
2141         return;
2142 
2143 	if( SHOWSTATE_UNKNOWN == nShowState_ || SHOWSTATE_HIDDEN == nShowState_ )
2144 	{
2145 		stderr0( "X11SalFrame::Restore on withdrawn window\n" );
2146 		return;
2147 	}
2148 
2149 	if( SHOWSTATE_MINIMIZED == nShowState_ )
2150 	{
2151         GetDisplay()->getWMAdaptor()->frameIsMapping( this );
2152 		XMapWindow( GetXDisplay(), GetShellWindow() );
2153 		nShowState_ = SHOWSTATE_NORMAL;
2154 	}
2155 
2156     pDisplay_->getWMAdaptor()->maximizeFrame( this, false, false );
2157 }
2158 
2159 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2160 
2161 void X11SalFrame::SetScreenNumber( unsigned int nNewScreen )
2162 {
2163     if( nNewScreen == maGeometry.nScreenNumber )
2164         return;
2165 
2166     if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
2167     {
2168         if( nNewScreen >= GetDisplay()->GetXineramaScreens().size() )
2169             return;
2170 
2171         Rectangle aOldScreenRect( GetDisplay()->GetXineramaScreens()[maGeometry.nScreenNumber] );
2172         Rectangle aNewScreenRect( GetDisplay()->GetXineramaScreens()[nNewScreen] );
2173         bool bVisible = bMapped_;
2174         if( bVisible )
2175             Show( sal_False );
2176         maGeometry.nX = aNewScreenRect.Left() + (maGeometry.nX - aOldScreenRect.Left());
2177         maGeometry.nY = aNewScreenRect.Top() + (maGeometry.nY - aOldScreenRect.Top());
2178         createNewWindow( None, m_nScreen );
2179         if( bVisible )
2180             Show( sal_True );
2181         maGeometry.nScreenNumber = nNewScreen;
2182     }
2183     else if( sal_Int32(nNewScreen) < GetDisplay()->GetScreenCount() )
2184     {
2185         bool bVisible = bMapped_;
2186         if( bVisible )
2187             Show( sal_False );
2188         createNewWindow( None, nNewScreen );
2189         if( bVisible )
2190             Show( sal_True );
2191         maGeometry.nScreenNumber = nNewScreen;
2192     }
2193 }
2194 
2195 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2196 
2197 void X11SalFrame::ShowFullScreen( sal_Bool bFullScreen, sal_Int32 nScreen )
2198 {
2199     if( GetDisplay()->IsXinerama() && GetDisplay()->GetXineramaScreens().size() > 1 )
2200     {
2201         if( mbFullScreen == (bool)bFullScreen )
2202             return;
2203         if( bFullScreen )
2204         {
2205             maRestorePosSize = Rectangle( Point( maGeometry.nX, maGeometry.nY ),
2206                                           Size( maGeometry.nWidth, maGeometry.nHeight ) );
2207             Rectangle aRect;
2208             if( nScreen < 0 || nScreen >= static_cast<int>(GetDisplay()->GetXineramaScreens().size()) )
2209                 aRect = Rectangle( Point(0,0), GetDisplay()->GetScreenSize( m_nScreen ) );
2210             else
2211                 aRect = GetDisplay()->GetXineramaScreens()[nScreen];
2212             nStyle_ |= SAL_FRAME_STYLE_PARTIAL_FULLSCREEN;
2213             bool bVisible = bMapped_;
2214             if( bVisible )
2215                 Show( sal_False );
2216             maGeometry.nX = aRect.Left();
2217             maGeometry.nY = aRect.Top();
2218             maGeometry.nWidth = aRect.GetWidth();
2219             maGeometry.nHeight = aRect.GetHeight();
2220             mbMaximizedHorz = mbMaximizedVert = false;
2221             mbFullScreen = true;
2222             createNewWindow( None, m_nScreen );
2223             if( GetDisplay()->getWMAdaptor()->isLegacyPartialFullscreen() )
2224                 GetDisplay()->getWMAdaptor()->enableAlwaysOnTop( this, true );
2225             else
2226             {
2227                 GetDisplay()->getWMAdaptor()->setFullScreenMonitors( GetShellWindow(), nScreen );
2228                 GetDisplay()->getWMAdaptor()->showFullScreen( this, true );
2229             }
2230             if( bVisible )
2231                 Show(sal_True);
2232 
2233         }
2234         else
2235         {
2236             mbFullScreen = false;
2237             nStyle_ &= ~SAL_FRAME_STYLE_PARTIAL_FULLSCREEN;
2238             bool bVisible = bMapped_;
2239             Rectangle aRect = maRestorePosSize;
2240             maRestorePosSize = Rectangle();
2241             if( bVisible )
2242                 Show( sal_False );
2243             createNewWindow( None, m_nScreen );
2244             if( !aRect.IsEmpty() )
2245                 SetPosSize( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
2246                             SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y |
2247                             SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT );
2248             if( bVisible )
2249                 Show( sal_True );
2250         }
2251     }
2252     else
2253     {
2254         if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
2255             nScreen = m_nScreen;
2256         if( nScreen != m_nScreen )
2257         {
2258             bool bVisible = bMapped_;
2259             if( mbFullScreen )
2260                 pDisplay_->getWMAdaptor()->showFullScreen( this, false );
2261             if( bVisible )
2262                 Show( sal_False );
2263             createNewWindow( None, nScreen );
2264             if( mbFullScreen )
2265                 pDisplay_->getWMAdaptor()->showFullScreen( this, true );
2266             if( bVisible )
2267                 Show( sal_True );
2268         }
2269         if( mbFullScreen == (bool)bFullScreen )
2270             return;
2271 
2272         pDisplay_->getWMAdaptor()->showFullScreen( this, bFullScreen );
2273         if( IsOverrideRedirect()
2274             && WMSupportsFWS( GetXDisplay(), GetDisplay()->GetRootWindow( m_nScreen ) ) )
2275         {
2276             AddFwsProtocols( GetXDisplay(), GetShellWindow() );
2277             RegisterFwsWindow( GetXDisplay(), GetShellWindow() );
2278         }
2279     }
2280 }
2281 
2282 /* ---------------------------------------------------------------------
2283    the xautolock pseudo screen saver needs special treatment since it
2284    doesn't cooperate with XxxxScreenSaver settings
2285    ------------------------------------------------------------------- */
2286 
2287 static Bool
2288 IsRunningXAutoLock( Display *p_display, XLIB_Window a_window )
2289 {
2290 	const char *p_atomname = "XAUTOLOCK_SEMAPHORE_PID";
2291 	Atom		a_pidatom;
2292 
2293 	// xautolock interns this atom
2294 	a_pidatom    = XInternAtom( p_display, p_atomname, True );
2295 	if ( a_pidatom == None )
2296 		return False;
2297 
2298 	Atom          a_type;
2299 	int           n_format;
2300 	unsigned long n_items;
2301 	unsigned long n_bytes_after;
2302 	pid_t		 *p_pid;
2303 	pid_t         n_pid;
2304 	// get pid of running xautolock
2305 	XGetWindowProperty (p_display, a_window, a_pidatom, 0L, 2L, False,
2306     		AnyPropertyType, &a_type, &n_format, &n_items, &n_bytes_after,
2307             (unsigned char**) &p_pid );
2308 	n_pid = *p_pid;
2309 	XFree( p_pid );
2310 
2311   	if ( a_type == XA_INTEGER )
2312   	{
2313 		// check if xautolock pid points to a running process
2314 		if ( kill(n_pid, 0) == -1 )
2315 			return False;
2316 		else
2317 			return True;
2318 	}
2319 
2320 	return False;
2321 }
2322 
2323 /* definitions from xautolock.c (pl15) */
2324 #define XAUTOLOCK_DISABLE 1
2325 #define XAUTOLOCK_ENABLE  2
2326 
2327 static Bool
2328 MessageToXAutoLock( Display *p_display, int n_message )
2329 {
2330 	const char *p_atomname = "XAUTOLOCK_MESSAGE" ;
2331 	Atom        a_messageatom;
2332 	XLIB_Window a_rootwindow;
2333 
2334 	a_rootwindow = RootWindowOfScreen( ScreenOfDisplay(p_display, 0) );
2335 	if ( ! IsRunningXAutoLock(p_display, a_rootwindow) )
2336 	{
2337 		// remove any pending messages
2338 		a_messageatom = XInternAtom( p_display, p_atomname, True );
2339 		if ( a_messageatom != None )
2340 			XDeleteProperty( p_display, a_rootwindow, a_messageatom );
2341 		return False;
2342 	}
2343 
2344 	a_messageatom = XInternAtom( p_display, p_atomname, False );
2345 	XChangeProperty (p_display, a_rootwindow, a_messageatom, XA_INTEGER,
2346     		8, PropModeReplace, (unsigned char*)&n_message, sizeof(n_message) );
2347 
2348 	return True;
2349 }
2350 
2351 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2352 void X11SalFrame::StartPresentation( sal_Bool bStart )
2353 {
2354     I18NStatus::get().show( !bStart, I18NStatus::presentation );
2355 	if ( bStart )
2356 		MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_DISABLE );
2357 	else
2358 		MessageToXAutoLock( GetXDisplay(), XAUTOLOCK_ENABLE );
2359 
2360     if( ! bStart && hPresentationWindow != None )
2361         doReparentPresentationDialogues( GetDisplay() );
2362     hPresentationWindow = (bStart && IsOverrideRedirect() ) ? GetWindow() : None;
2363 
2364 
2365 	// needs static here to save DPMS settings
2366     int dummy;
2367     static bool DPMSExtensionAvailable =
2368 #ifndef SOLARIS
2369         (DPMSQueryExtension(GetXDisplay(), &dummy, &dummy) != 0);
2370 	static sal_Bool DPMSEnabled = false;
2371 #else
2372         false;
2373     bool DPMSEnabled = false;
2374     (void)dummy;
2375 #define CARD16 unsigned short
2376 #endif
2377 	static CARD16 dpms_standby_timeout=0;
2378 	static CARD16 dpms_suspend_timeout=0;
2379 	static CARD16 dpms_off_timeout=0;
2380 
2381 
2382 	if( bStart || nScreenSaversTimeout_ || DPMSEnabled)
2383 	{
2384         if( hPresentationWindow )
2385         {
2386             /*  #i10559# workaround for WindowMaker: try to restore
2387              *  current focus after presentation window is gone
2388              */
2389             int revert_to = 0;
2390             XGetInputFocus( GetXDisplay(), &hPresFocusWindow, &revert_to );
2391         }
2392 		int timeout, interval, prefer_blanking, allow_exposures;
2393 		XGetScreenSaver( GetXDisplay(),
2394 						 &timeout,
2395 						 &interval,
2396 						 &prefer_blanking,
2397 						 &allow_exposures );
2398 
2399 
2400 		// get the DPMS state right before the start
2401 		if (DPMSExtensionAvailable)
2402         {
2403 #ifndef SOLARIS
2404 			CARD16 state; // card16 is defined in Xdm.h
2405 			DPMSInfo(	GetXDisplay(),
2406 						&state,
2407 						&DPMSEnabled);
2408 #endif
2409 		}
2410 		if( bStart ) // start show
2411 		{
2412 			if ( timeout )
2413 			{
2414 				nScreenSaversTimeout_ = timeout;
2415 				XResetScreenSaver( GetXDisplay() );
2416 				XSetScreenSaver( GetXDisplay(),
2417 								 0,
2418 								 interval,
2419 								 prefer_blanking,
2420 								 allow_exposures );
2421 			}
2422 #ifndef SOLARIS
2423 			if( DPMSEnabled )
2424 			{
2425 				if ( DPMSExtensionAvailable )
2426 				{
2427 					DPMSGetTimeouts(	GetXDisplay(),
2428 										&dpms_standby_timeout,
2429 										&dpms_suspend_timeout,
2430 										&dpms_off_timeout);
2431 					DPMSSetTimeouts(GetXDisplay(), 0,0,0);
2432 				}
2433 			}
2434 #endif
2435 		}
2436 		else // if( !bStart ) // end of show
2437 		{
2438 			if( nScreenSaversTimeout_ )
2439 			{
2440 				XSetScreenSaver( GetXDisplay(),
2441 							 nScreenSaversTimeout_,
2442 							 interval,
2443 							 prefer_blanking,
2444 							 allow_exposures );
2445 				nScreenSaversTimeout_ = 0;
2446 			}
2447 #ifndef SOLARIS
2448 			if ( DPMSEnabled )
2449 			{
2450 				if ( DPMSExtensionAvailable )
2451 				{
2452 				// restore timeouts
2453 					DPMSSetTimeouts(GetXDisplay(), dpms_standby_timeout,
2454 						dpms_suspend_timeout, dpms_off_timeout);
2455 				}
2456 			}
2457 #endif
2458 		}
2459 	}
2460 }
2461 
2462 // Pointer
2463 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2464 void X11SalFrame::SetPointer( PointerStyle ePointerStyle )
2465 {
2466 	hCursor_ = pDisplay_->GetPointer( ePointerStyle );
2467 	XDefineCursor( GetXDisplay(), GetWindow(), hCursor_ );
2468 
2469 	if( IsCaptured() || nVisibleFloats > 0 )
2470 		XChangeActivePointerGrab( GetXDisplay(),
2471 						PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
2472 						hCursor_,
2473 						CurrentTime );
2474 }
2475 
2476 void X11SalFrame::SetPointerPos(long nX, long nY)
2477 {
2478     /* #87921# when the application tries to center the mouse in the dialog the
2479      * window isn't mapped already. So use coordinates relative to the root window.
2480      */
2481     unsigned int nWindowLeft = maGeometry.nX + nX;
2482     unsigned int nWindowTop  = maGeometry.nY + nY;
2483 
2484     XWarpPointer( GetXDisplay(), None, pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() ),
2485                   0, 0, 0, 0, nWindowLeft, nWindowTop);
2486 }
2487 
2488 // delay handling of extended text input
2489 #if !defined(__synchronous_extinput__)
2490 void
2491 X11SalFrame::PostExtTextEvent (sal_uInt16 nExtTextEventType, void *pExtTextEvent)
2492 {
2493 	XLIB_Window nFocusWindow = GetWindow();
2494 	Atom 		nEventAtom	 = GetDisplay()->getWMAdaptor()->getAtom( WMAdaptor::SAL_EXTTEXTEVENT );
2495 
2496     XEvent aEvent;
2497     aEvent.xclient.type			= ClientMessage;
2498     aEvent.xclient.serial		= 0;
2499     aEvent.xclient.send_event	= True;
2500     aEvent.xclient.display		= GetXDisplay();
2501     aEvent.xclient.window		= nFocusWindow;
2502     aEvent.xclient.message_type	= nEventAtom;
2503     aEvent.xclient.format		= 32;
2504 
2505 #if SAL_TYPES_SIZEOFLONG > 4
2506     aEvent.xclient.data.l[0] = (sal_uInt32)((long)pExtTextEvent & 0xffffffff);
2507     aEvent.xclient.data.l[1] = (sal_uInt32)((long)pExtTextEvent >> 32);
2508 #else
2509     aEvent.xclient.data.l[0] = (sal_uInt32)((long)pExtTextEvent);
2510     aEvent.xclient.data.l[1] = 0;
2511 #endif
2512     aEvent.xclient.data.l[2] = (sal_uInt32)nExtTextEventType;
2513     aEvent.xclient.data.l[3] = 0;
2514     aEvent.xclient.data.l[4] = 0;
2515 
2516     XPutBackEvent( GetXDisplay(), &aEvent );
2517 }
2518 
2519 void
2520 X11SalFrame::HandleExtTextEvent (XClientMessageEvent *pEvent)
2521 {
2522 	#if SAL_TYPES_SIZEOFLONG > 4
2523 	void* pExtTextEvent = (void*)(  (pEvent->data.l[0] & 0xffffffff)
2524 								  | (pEvent->data.l[1] << 32) );
2525 	#else
2526 	void* pExtTextEvent = (void*)(pEvent->data.l[0]);
2527 	#endif
2528 	sal_uInt16 nExtTextEventType = sal_uInt16(pEvent->data.l[2]);
2529 
2530 	CallCallback(nExtTextEventType, pExtTextEvent);
2531 
2532 	switch (nExtTextEventType)
2533 	{
2534 		case SALEVENT_ENDEXTTEXTINPUT:
2535 			break;
2536 
2537 		case SALEVENT_EXTTEXTINPUT:
2538 			break;
2539 
2540 		default:
2541 
2542 			fprintf(stderr, "X11SalFrame::HandleExtTextEvent: invalid extended input\n");
2543 	}
2544 }
2545 #endif /* defined(__synchronous_extinput__) */
2546 
2547 // PostEvent
2548 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2549 sal_Bool X11SalFrame::PostEvent( void *pData )
2550 {
2551     GetDisplay()->SendInternalEvent( this, pData );
2552 	return sal_True;
2553 }
2554 
2555 // Title
2556 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2557 void X11SalFrame::SetTitle( const XubString& rTitle )
2558 {
2559     if( ! ( IsChildWindow() || (nStyle_ & SAL_FRAME_STYLE_FLOAT ) ) )
2560     {
2561         m_aTitle = rTitle;
2562         GetDisplay()->getWMAdaptor()->setWMName( this, rTitle );
2563     }
2564 }
2565 
2566 // -----------------------------------------------------------------------
2567 
2568 void X11SalFrame::Flush()
2569 {
2570 	XFlush( GetDisplay()->GetDisplay() );
2571 }
2572 
2573 // -----------------------------------------------------------------------
2574 
2575 void X11SalFrame::Sync()
2576 {
2577 	XSync( GetDisplay()->GetDisplay(), False );
2578 }
2579 
2580 // Keyboard
2581 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2582 
2583 // -----------------------------------------------------------------------
2584 
2585 void X11SalFrame::SetInputContext( SalInputContext* pContext )
2586 {
2587   	if (pContext == NULL)
2588 		return;
2589 
2590   	// 1. We should create an input context for this frame
2591   	//    only when SAL_INPUTCONTEXT_TEXT is set.
2592 
2593   	if (!(pContext->mnOptions & SAL_INPUTCONTEXT_TEXT))
2594     {
2595         if( mpInputContext )
2596             mpInputContext->Unmap( this );
2597 		return;
2598     }
2599 
2600 	// 2. We should use on-the-spot inputstyle
2601   	//    only when SAL_INPUTCONTEXT_EXTTEXTINPUT is set.
2602 
2603   	if (mpInputContext == NULL)
2604 	{
2605         I18NStatus& rStatus( I18NStatus::get() );
2606         rStatus.setParent( this );
2607         mpInputContext = new SalI18N_InputContext( this );
2608 		if (mpInputContext->UseContext())
2609 		{
2610 	  		mpInputContext->ExtendEventMask( GetShellWindow() );
2611 	  		if (pContext->mnOptions & SAL_INPUTCONTEXT_CHANGELANGUAGE)
2612 				mpInputContext->SetLanguage(pContext->meLanguage);
2613 			if (mbInputFocus)
2614 				mpInputContext->SetICFocus( this );
2615 		}
2616   	}
2617     else
2618         mpInputContext->Map( this );
2619   	return;
2620 }
2621 
2622 // -----------------------------------------------------------------------
2623 
2624 void X11SalFrame::EndExtTextInput( sal_uInt16 nFlags )
2625 {
2626     if (mpInputContext != NULL)
2627   	    mpInputContext->EndExtTextInput( nFlags );
2628 }
2629 
2630 // -----------------------------------------------------------------------
2631 
2632 XubString X11SalFrame::GetKeyName( sal_uInt16 nKeyCode )
2633 {
2634 	return GetDisplay()->GetKeyName( nKeyCode );
2635 }
2636 
2637 XubString X11SalFrame::GetSymbolKeyName( const XubString&, sal_uInt16 nKeyCode )
2638 {
2639   return GetKeyName( nKeyCode );
2640 }
2641 
2642 sal_Bool X11SalFrame::MapUnicodeToKeyCode( sal_Unicode , LanguageType , KeyCode& )
2643 {
2644     // not supported yet
2645     return sal_False;
2646 }
2647 
2648 LanguageType X11SalFrame::GetInputLanguage()
2649 {
2650     // could be improved by checking unicode ranges of the last input
2651     return LANGUAGE_DONTKNOW;
2652 }
2653 
2654 // Settings
2655 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2656 
2657 inline Color getColorFromLong( long nColor )
2658 {
2659 	return Color( (nColor & 0xff), (nColor & 0xff00)>>8, (nColor & 0xff0000)>>16);
2660 }
2661 
2662 void X11SalFrame::UpdateSettings( AllSettings& rSettings )
2663 {
2664 
2665     DtIntegrator* pIntegrator = GetDisplay()->getDtIntegrator();
2666 #if OSL_DEBUG_LEVEL > 1
2667     fprintf( stderr, "DtIntegrator: %d\n", pIntegrator ? pIntegrator->GetDtType() : -1 );
2668 #endif
2669     if( pIntegrator )
2670         pIntegrator->GetSystemLook( rSettings );
2671 }
2672 
2673 void X11SalFrame::CaptureMouse( sal_Bool bCapture )
2674 {
2675     nCaptured_ = pDisplay_->CaptureMouse( bCapture ? this : NULL );
2676 }
2677 
2678 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2679 
2680 void X11SalFrame::SetParent( SalFrame* pNewParent )
2681 {
2682     if( mpParent != pNewParent )
2683     {
2684         if( mpParent )
2685             mpParent->maChildren.remove( this );
2686 
2687         mpParent = static_cast<X11SalFrame*>(pNewParent);
2688         mpParent->maChildren.push_back( this );
2689         if( mpParent->m_nScreen != m_nScreen )
2690             createNewWindow( None, mpParent->m_nScreen );
2691         GetDisplay()->getWMAdaptor()->changeReferenceFrame( this, mpParent );
2692     }
2693 }
2694 
2695 SalFrame* X11SalFrame::GetParent() const
2696 {
2697     return mpParent;
2698 }
2699 
2700 void X11SalFrame::createNewWindow( XLIB_Window aNewParent, int nScreen )
2701 {
2702     bool bWasVisible = bMapped_;
2703     if( bWasVisible )
2704         Show( sal_False );
2705 
2706     if( nScreen < 0 || nScreen >= GetDisplay()->GetScreenCount() )
2707         nScreen = m_nScreen;
2708 
2709     SystemParentData aParentData;
2710     aParentData.aWindow = aNewParent;
2711     aParentData.bXEmbedSupport = (aNewParent != None && m_bXEmbed); // caution: this is guesswork
2712     if( aNewParent == None )
2713     {
2714         aNewParent = GetDisplay()->GetRootWindow(nScreen);
2715         aParentData.aWindow = None;
2716         m_bXEmbed = false;
2717     }
2718     else
2719     {
2720         // is new parent a root window ?
2721         Display* pDisp = GetDisplay()->GetDisplay();
2722         int nScreens = GetDisplay()->GetScreenCount();
2723         for( int i = 0; i < nScreens; i++ )
2724         {
2725             if( aNewParent == RootWindow( pDisp, i ) )
2726             {
2727                 nScreen = i;
2728                 aParentData.aWindow = None;
2729                 m_bXEmbed = false;
2730                 break;
2731             }
2732         }
2733     }
2734 
2735     // first deinit frame
2736     updateGraphics(true);
2737     if( mpInputContext )
2738     {
2739         mpInputContext->UnsetICFocus( this );
2740         mpInputContext->Unmap( this );
2741     }
2742     if( GetWindow() == hPresentationWindow )
2743     {
2744         hPresentationWindow = None;
2745         doReparentPresentationDialogues( GetDisplay() );
2746     }
2747     XDestroyWindow( GetXDisplay(), mhWindow );
2748     mhWindow = None;
2749 
2750     passOnSaveYourSelf();
2751 
2752     // now init with new parent again
2753     if ( aParentData.aWindow != None )
2754 	    Init( nStyle_ | SAL_FRAME_STYLE_PLUG, nScreen, &aParentData );
2755     else
2756 	    Init( nStyle_ & ~SAL_FRAME_STYLE_PLUG, nScreen, NULL, true );
2757 
2758 	// update graphics if necessary
2759     updateGraphics(false);
2760 
2761     if( m_aTitle.Len() )
2762         SetTitle( m_aTitle );
2763 
2764     if( mpParent )
2765     {
2766         if( mpParent->m_nScreen != m_nScreen )
2767             SetParent( NULL );
2768         else
2769             pDisplay_->getWMAdaptor()->changeReferenceFrame( this, mpParent );
2770     }
2771 
2772     if( bWasVisible )
2773         Show( sal_True );
2774 
2775     std::list< X11SalFrame* > aChildren = maChildren;
2776     for( std::list< X11SalFrame* >::iterator it = aChildren.begin(); it != aChildren.end(); ++it )
2777         (*it)->createNewWindow( None, m_nScreen );
2778 
2779     // FIXME: SalObjects
2780 }
2781 
2782 bool X11SalFrame::SetPluginParent( SystemParentData* pNewParent )
2783 {
2784     if( pNewParent->nSize >= sizeof(SystemParentData) )
2785         m_bXEmbed = pNewParent->aWindow != None && pNewParent->bXEmbedSupport;
2786     createNewWindow( pNewParent ? pNewParent->aWindow : None );
2787 
2788     return true;
2789 }
2790 
2791 // Sound
2792 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2793 void X11SalFrame::Beep( SoundType eSoundType ) // not fully suported
2794 {
2795     switch( eSoundType )
2796     {
2797         case SOUND_DEFAULT:
2798         case SOUND_ERROR:
2799             GetDisplay()->Beep();
2800             break;
2801         default:
2802             // Excessive beeping averted
2803             break;
2804     }
2805 }
2806 
2807 // Event Handling
2808 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2809 static sal_uInt16 sal_GetCode( int state )
2810 {
2811 	sal_uInt16 nCode = 0;
2812 
2813 	if( state & Button1Mask )
2814 		nCode |= MOUSE_LEFT;
2815 	if( state & Button2Mask )
2816 		nCode |= MOUSE_MIDDLE;
2817 	if( state & Button3Mask )
2818 		nCode |= MOUSE_RIGHT;
2819 
2820 	if( state & ShiftMask )
2821 		nCode |= KEY_SHIFT;
2822 	if( state & ControlMask )
2823 		nCode |= KEY_MOD1;
2824 	if( state & Mod1Mask )
2825 		nCode |= KEY_MOD2;
2826 
2827         // Map Meta/Super modifier to MOD3 on all Unix systems
2828         // except Mac OS X
2829         if( (state & Mod3Mask) )
2830             nCode |= KEY_MOD3;
2831 
2832 	return nCode;
2833 }
2834 
2835 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2836 
2837 SalFrame::SalPointerState X11SalFrame::GetPointerState()
2838 {
2839     SalPointerState aState;
2840     XLIB_Window aRoot, aChild;
2841     int rx, ry, wx, wy;
2842     unsigned int nMask = 0;
2843     XQueryPointer( GetXDisplay(),
2844                    GetShellWindow(),
2845                    &aRoot,
2846                    &aChild,
2847                    &rx, &ry,
2848                    &wx, &wy,
2849                    &nMask
2850                    );
2851 
2852     aState.maPos = Point(wx, wy);
2853     aState.mnState = sal_GetCode( nMask );
2854     return aState;
2855 }
2856 
2857 long X11SalFrame::HandleMouseEvent( XEvent *pEvent )
2858 {
2859 	SalMouseEvent		aMouseEvt;
2860 	sal_uInt16				nEvent = 0;
2861     bool				bClosePopups = false;
2862 
2863     if( nVisibleFloats && pEvent->type == EnterNotify )
2864         return 0;
2865 
2866 	// Solaris X86: clicking the right button on a two-button mouse
2867 	// generates a button2 event not a button3 event
2868 	if (pDisplay_->GetProperties() & PROPERTY_SUPPORT_3ButtonMouse )
2869 	{
2870 		switch (pEvent->type)
2871 		{
2872 			case EnterNotify:
2873 			case LeaveNotify:
2874 				if ( pEvent->xcrossing.state & Button2Mask )
2875 				{
2876 					pEvent->xcrossing.state &= ~Button2Mask;
2877 					pEvent->xcrossing.state |=	Button3Mask;
2878 				}
2879 				break;
2880 
2881 			case MotionNotify:
2882 				if ( pEvent->xmotion.state & Button2Mask )
2883 				{
2884 					pEvent->xmotion.state &= ~Button2Mask;
2885 					pEvent->xmotion.state |=  Button3Mask;
2886 				}
2887 				break;
2888 
2889 			default:
2890 				if ( Button2 == pEvent->xbutton.button )
2891 				{
2892 					pEvent->xbutton.state &= ~Button2Mask;
2893 					pEvent->xbutton.state |=  Button3Mask;
2894 					pEvent->xbutton.button =  Button3;
2895 				}
2896 				break;
2897 		}
2898 	}
2899 
2900 
2901 	if( LeaveNotify == pEvent->type || EnterNotify == pEvent->type )
2902 	{
2903         /*
2904          *  #89075# #89335#
2905          *
2906          *  some WMs (and/or) applications  have a passive grab on
2907          *  mouse buttons (XGrabButton). This leads to enter/leave notifies
2908          *  with mouse buttons pressed in the state mask before the actual
2909          *  ButtonPress event gets dispatched. But EnterNotify
2910          *  is reported in vcl as MouseMove event. Some office code
2911          *  decides that a pressed button in a MouseMove belongs to
2912          *  a drag operation which leads to doing things differently.
2913          *
2914          *  #95901#
2915          *  ignore Enter/LeaveNotify resulting from grabs so that
2916          *  help windows do not disappear just after appearing
2917          *
2918          *  hopefully this workaround will not break anything.
2919          */
2920         if( pEvent->xcrossing.mode == NotifyGrab || pEvent->xcrossing.mode == NotifyUngrab  )
2921             return 0;
2922 
2923 		aMouseEvt.mnX		= pEvent->xcrossing.x;
2924 		aMouseEvt.mnY		= pEvent->xcrossing.y;
2925 		aMouseEvt.mnTime	= pEvent->xcrossing.time;
2926         aMouseEvt.mnCode	= sal_GetCode( pEvent->xcrossing.state );
2927 		aMouseEvt.mnButton	= 0;
2928 
2929 		nEvent				= LeaveNotify == pEvent->type
2930 							  ? SALEVENT_MOUSELEAVE
2931 							  : SALEVENT_MOUSEMOVE;
2932 	}
2933 	else if( pEvent->type == MotionNotify )
2934 	{
2935 		aMouseEvt.mnX		= pEvent->xmotion.x;
2936 		aMouseEvt.mnY		= pEvent->xmotion.y;
2937 		aMouseEvt.mnTime	= pEvent->xmotion.time;
2938 		aMouseEvt.mnCode	= sal_GetCode( pEvent->xmotion.state );
2939 
2940 		aMouseEvt.mnButton	= 0;
2941 
2942 		nEvent				= SALEVENT_MOUSEMOVE;
2943         if( nVisibleFloats > 0 && mpParent )
2944         {
2945             XLIB_Cursor aCursor = mpParent->GetCursor();
2946             if( pEvent->xmotion.x >= 0 && pEvent->xmotion.x < (int)maGeometry.nWidth &&
2947                 pEvent->xmotion.y >= 0 && pEvent->xmotion.y < (int)maGeometry.nHeight )
2948                 aCursor = None;
2949 
2950             XChangeActivePointerGrab( GetXDisplay(),
2951                                       PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
2952                                       aCursor,
2953                                       CurrentTime );
2954         }
2955 	}
2956 	else
2957 	{
2958         // let mouse events reach the correct window
2959         if( nVisibleFloats < 1 )
2960         {
2961             if( ! (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) )
2962                 XUngrabPointer( GetXDisplay(), CurrentTime );
2963         }
2964         else if( pEvent->type == ButtonPress )
2965         {
2966             // see if the user clicks outside all of the floats
2967             // if yes release the grab
2968             bool bInside = false;
2969             const std::list< SalFrame* >& rFrames = GetDisplay()->getFrames();
2970             for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
2971             {
2972                 const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
2973                 if( pFrame->IsFloatGrabWindow()										&&
2974                     pFrame->bMapped_												&&
2975                     pEvent->xbutton.x_root >= pFrame->maGeometry.nX								&&
2976                     pEvent->xbutton.x_root < pFrame->maGeometry.nX + (int)pFrame->maGeometry.nWidth	&&
2977                     pEvent->xbutton.y_root >= pFrame->maGeometry.nY								&&
2978                     pEvent->xbutton.y_root < pFrame->maGeometry.nY + (int)pFrame->maGeometry.nHeight )
2979                 {
2980                     bInside = true;
2981                     break;
2982                 }
2983             }
2984             if( ! bInside )
2985             {
2986                 // need not take care of the XUngrabPointer in Show( sal_False )
2987                 // because XUngrabPointer does not produce errors if pointer
2988                 // is not grabbed
2989                 XUngrabPointer( GetXDisplay(), CurrentTime );
2990                 bClosePopups = true;
2991 
2992                 /*  #i15246# only close popups if pointer is outside all our frames
2993                  *  cannot use our own geometry data here because stacking
2994                  *  is unknown (the above case implicitly assumes
2995                  *  that floats are on top which should be true)
2996                  */
2997                 XLIB_Window aRoot, aChild;
2998                 int root_x, root_y, win_x, win_y;
2999                 unsigned int mask_return;
3000                 if( XQueryPointer( GetXDisplay(),
3001                                    GetDisplay()->GetRootWindow( m_nScreen ),
3002                                    &aRoot, &aChild,
3003                                    &root_x, &root_y,
3004                                    &win_x, &win_y,
3005                                    &mask_return )
3006                     && aChild // pointer may not be in any child
3007                     )
3008                 {
3009                     for( std::list< SalFrame* >::const_iterator it = rFrames.begin(); it != rFrames.end(); ++it )
3010                     {
3011                         const X11SalFrame* pFrame = static_cast< const X11SalFrame* >(*it);
3012                         if( ! pFrame->IsFloatGrabWindow()
3013                             && ( pFrame->GetWindow() == aChild ||
3014                                  pFrame->GetShellWindow() == aChild ||
3015                                  pFrame->GetStackingWindow() == aChild )
3016                             )
3017                         {
3018                             // #i63638# check that pointer is inside window, not
3019                             // only inside stacking window
3020                             if( root_x >= pFrame->maGeometry.nX && root_x < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nWidth) &&
3021                                 root_y >= pFrame->maGeometry.nY && root_y < sal::static_int_cast< int >(pFrame->maGeometry.nX+pFrame->maGeometry.nHeight) )
3022                             {
3023                                 bClosePopups = false;
3024                             }
3025                             break;
3026                         }
3027                     }
3028                 }
3029             }
3030         }
3031 
3032         if( m_bXEmbed && pEvent->xbutton.button == Button1 )
3033             askForXEmbedFocus( pEvent->xbutton.time );
3034 
3035 		if( pEvent->xbutton.button == Button1 ||
3036 			pEvent->xbutton.button == Button2 ||
3037 			pEvent->xbutton.button == Button3 )
3038 		{
3039 			aMouseEvt.mnX		= pEvent->xbutton.x;
3040 			aMouseEvt.mnY		= pEvent->xbutton.y;
3041 			aMouseEvt.mnTime	= pEvent->xbutton.time;
3042 			aMouseEvt.mnCode	= sal_GetCode( pEvent->xbutton.state );
3043 
3044 			if( Button1 == pEvent->xbutton.button )
3045 				aMouseEvt.mnButton	= MOUSE_LEFT;
3046 			else if( Button2 == pEvent->xbutton.button )
3047 				aMouseEvt.mnButton	= MOUSE_MIDDLE;
3048 			else if( Button3 == pEvent->xbutton.button )
3049 				aMouseEvt.mnButton	= MOUSE_RIGHT;
3050 
3051 			nEvent				= ButtonPress == pEvent->type
3052 				? SALEVENT_MOUSEBUTTONDOWN
3053 				: SALEVENT_MOUSEBUTTONUP;
3054 		}
3055 		else if( pEvent->xbutton.button == Button4 ||
3056                  pEvent->xbutton.button == Button5 ||
3057                  pEvent->xbutton.button == Button6 ||
3058                  pEvent->xbutton.button == Button7 )
3059 		{
3060             const bool bIncrement(
3061                 pEvent->xbutton.button == Button4 ||
3062                 pEvent->xbutton.button == Button6 );
3063             const bool bHoriz(
3064                 pEvent->xbutton.button == Button6 ||
3065                 pEvent->xbutton.button == Button7 );
3066 
3067             if( pEvent->type == ButtonRelease )
3068                 return 0;
3069 
3070             static sal_uLong		nLines = 0;
3071 			if( ! nLines )
3072 			{
3073 				char* pEnv = getenv( "SAL_WHEELLINES" );
3074 				nLines = pEnv ? atoi( pEnv ) : 3;
3075 				if( nLines > 10 )
3076 					nLines = SAL_WHEELMOUSE_EVENT_PAGESCROLL;
3077 			}
3078 
3079 			SalWheelMouseEvent	aWheelEvt;
3080 			aWheelEvt.mnTime		= pEvent->xbutton.time;
3081 			aWheelEvt.mnX			= pEvent->xbutton.x;
3082 			aWheelEvt.mnY			= pEvent->xbutton.y;
3083 			aWheelEvt.mnDelta		= bIncrement ? 120 : -120;
3084 			aWheelEvt.mnNotchDelta	= bIncrement ? 1 : -1;
3085 			aWheelEvt.mnScrollLines = nLines;
3086 			aWheelEvt.mnCode		= sal_GetCode( pEvent->xbutton.state );
3087 			aWheelEvt.mbHorz		= bHoriz;
3088 
3089 			nEvent = SALEVENT_WHEELMOUSE;
3090 
3091             // --- RTL --- (mirror mouse pos)
3092             if( Application::GetSettings().GetLayoutRTL() )
3093                 aWheelEvt.mnX = nWidth_-1-aWheelEvt.mnX;
3094 			return CallCallback( nEvent, &aWheelEvt );
3095 		}
3096 	}
3097 
3098     int nRet = 0;
3099 	if( nEvent == SALEVENT_MOUSELEAVE
3100 		|| ( aMouseEvt.mnX <  nWidth_  && aMouseEvt.mnX >  -1 &&
3101 			 aMouseEvt.mnY <  nHeight_ && aMouseEvt.mnY >  -1 )
3102 		|| pDisplay_->MouseCaptured( this )
3103         )
3104     {
3105         // --- RTL --- (mirror mouse pos)
3106         if( Application::GetSettings().GetLayoutRTL() )
3107             aMouseEvt.mnX = nWidth_-1-aMouseEvt.mnX;
3108 		nRet = CallCallback( nEvent, &aMouseEvt );
3109     }
3110 
3111     if( bClosePopups )
3112     {
3113         /*  #108213# close popups after dispatching the event outside the popup;
3114          *  applications do weird things.
3115          */
3116         ImplSVData* pSVData = ImplGetSVData();
3117         if ( pSVData->maWinData.mpFirstFloat )
3118         {
3119             static const char* pEnv = getenv( "SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
3120             if ( !(pSVData->maWinData.mpFirstFloat->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE) && !(pEnv && *pEnv) )
3121                 pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
3122         }
3123     }
3124 
3125 	return nRet;
3126 }
3127 
3128 // F10 means either KEY_F10 or KEY_MENU, which has to be decided
3129 // in the independent part.
3130 struct KeyAlternate
3131 {
3132 	sal_uInt16			nKeyCode;
3133 	sal_Unicode		nCharCode;
3134 	KeyAlternate() : nKeyCode( 0 ), nCharCode( 0 ) {}
3135 	KeyAlternate( sal_uInt16 nKey, sal_Unicode nChar = 0 ) : nKeyCode( nKey ), nCharCode( nChar ) {}
3136 };
3137 
3138 inline KeyAlternate
3139 GetAlternateKeyCode( const sal_uInt16 nKeyCode )
3140 {
3141 	KeyAlternate aAlternate;
3142 
3143 	switch( nKeyCode )
3144 	{
3145 		case KEY_F10: aAlternate = KeyAlternate( KEY_MENU );break;
3146 		case KEY_F24: aAlternate = KeyAlternate( KEY_SUBTRACT, '-' );break;
3147 	}
3148 
3149 	return aAlternate;
3150 }
3151 
3152 void X11SalFrame::beginUnicodeSequence()
3153 {
3154     rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );
3155     DeletionListener aDeleteWatch( this );
3156 
3157     if( rSeq.getLength() )
3158         endUnicodeSequence();
3159 
3160     rSeq = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "u" ) );
3161 
3162     if( ! aDeleteWatch.isDeleted() )
3163     {
3164         sal_uInt16 nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
3165         SalExtTextInputEvent aEv;
3166         aEv.mnTime          = 0;
3167         aEv.maText          = rSeq;
3168         aEv.mpTextAttr      = &nTextAttr;
3169         aEv.mnCursorPos     = 0;
3170         aEv.mnDeltaStart    = 0;
3171         aEv.mnCursorFlags   = 0;
3172         aEv.mbOnlyCursor    = sal_False;
3173 
3174         CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
3175     }
3176 }
3177 
3178 bool X11SalFrame::appendUnicodeSequence( sal_Unicode c )
3179 {
3180     bool bRet = false;
3181     rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );
3182     if( rSeq.getLength() > 0 )
3183     {
3184         // range check
3185         if( (c >= sal_Unicode('0') && c <= sal_Unicode('9')) ||
3186             (c >= sal_Unicode('a') && c <= sal_Unicode('f')) ||
3187             (c >= sal_Unicode('A') && c <= sal_Unicode('F')) )
3188         {
3189             rtl::OUStringBuffer aBuf( rSeq.getLength() + 1 );
3190             aBuf.append( rSeq );
3191             aBuf.append( c );
3192             rSeq = aBuf.makeStringAndClear();
3193             std::vector<sal_uInt16> attribs( rSeq.getLength(), SAL_EXTTEXTINPUT_ATTR_UNDERLINE );
3194 
3195             SalExtTextInputEvent aEv;
3196             aEv.mnTime          = 0;
3197             aEv.maText          = rSeq;
3198             aEv.mpTextAttr      = &attribs[0];
3199             aEv.mnCursorPos     = 0;
3200             aEv.mnDeltaStart    = 0;
3201             aEv.mnCursorFlags   = 0;
3202             aEv.mbOnlyCursor    = sal_False;
3203 
3204             CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
3205             bRet = true;
3206         }
3207         else
3208             bRet = endUnicodeSequence();
3209     }
3210     else
3211         endUnicodeSequence();
3212     return bRet;
3213 }
3214 
3215 bool X11SalFrame::endUnicodeSequence()
3216 {
3217     rtl::OUString& rSeq( GetX11SalData()->GetUnicodeAccumulator() );
3218 
3219     DeletionListener aDeleteWatch( this );
3220     if( rSeq.getLength() > 1 && rSeq.getLength() < 6 )
3221     {
3222         // cut the "u"
3223         rtl::OUString aNumbers( rSeq.copy( 1 ) );
3224         sal_Int32 nValue = aNumbers.toInt32( 16 );
3225         if( nValue >= 32 )
3226         {
3227             sal_uInt16 nTextAttr = SAL_EXTTEXTINPUT_ATTR_UNDERLINE;
3228             SalExtTextInputEvent aEv;
3229             aEv.mnTime          = 0;
3230             aEv.maText          = rtl::OUString( sal_Unicode(nValue) );
3231             aEv.mpTextAttr      = &nTextAttr;
3232             aEv.mnCursorPos     = 0;
3233             aEv.mnDeltaStart    = 0;
3234             aEv.mnCursorFlags   = 0;
3235             aEv.mbOnlyCursor    = sal_False;
3236             CallCallback(SALEVENT_EXTTEXTINPUT, (void*)&aEv);
3237         }
3238     }
3239     bool bWasInput = rSeq.getLength() > 0;
3240     rSeq = rtl::OUString();
3241     if( bWasInput && ! aDeleteWatch.isDeleted() )
3242         CallCallback(SALEVENT_ENDEXTTEXTINPUT, NULL);
3243     return bWasInput;
3244 }
3245 
3246 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3247 long X11SalFrame::HandleKeyEvent( XKeyEvent *pEvent )
3248 {
3249 	KeySym			nKeySym;
3250     KeySym          nUnmodifiedKeySym;
3251 	int 			nLen = 2048;
3252 	unsigned char	*pPrintable = (unsigned char*)alloca( nLen );
3253 
3254 	// singlebyte code composed by input method, the new default
3255 	if (mpInputContext != NULL && mpInputContext->UseContext())
3256 	{
3257 		// returns a keysym as well as the pPrintable (in system encoding)
3258 		// printable may be empty.
3259 		Status nStatus;
3260     	nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
3261                                         &nUnmodifiedKeySym,
3262                                         &nStatus, mpInputContext->GetContext() );
3263 		if ( nStatus == XBufferOverflow )
3264 		{
3265 			nLen *= 2;
3266 			pPrintable = (unsigned char*)alloca( nLen );
3267 			nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen,
3268                                             &nUnmodifiedKeySym,
3269                                             &nStatus, mpInputContext->GetContext() );
3270 		}
3271 	}
3272 	else
3273 	{
3274 		// fallback, this should never ever be called
3275 		Status nStatus = 0;
3276        	nKeySym = pDisplay_->GetKeySym( pEvent, pPrintable, &nLen, &nUnmodifiedKeySym, &nStatus );
3277  	}
3278 
3279 	SalKeyEvent aKeyEvt;
3280 	sal_uInt16      nKeyCode;
3281 	sal_uInt16 nModCode = 0;
3282 	char		aDummy;
3283 
3284 	if( pEvent->state & ShiftMask )
3285 		nModCode |= KEY_SHIFT;
3286 	if( pEvent->state & ControlMask )
3287 		nModCode |= KEY_MOD1;
3288 	if( pEvent->state & Mod1Mask )
3289 		nModCode |= KEY_MOD2;
3290 
3291     if( nModCode != (KEY_SHIFT|KEY_MOD1) )
3292         endUnicodeSequence();
3293 
3294 	if( 	nKeySym == XK_Shift_L 	|| nKeySym == XK_Shift_R
3295 		|| 	nKeySym == XK_Control_L || nKeySym == XK_Control_R
3296 		|| 	nKeySym == XK_Alt_L		|| nKeySym == XK_Alt_R
3297 		|| 	nKeySym == XK_Meta_L 	|| nKeySym == XK_Meta_R
3298                 ||      nKeySym == XK_Super_L   || nKeySym == XK_Super_R )
3299 	{
3300 		SalKeyModEvent aModEvt;
3301         aModEvt.mnModKeyCode = 0;
3302         if( pEvent->type == XLIB_KeyPress && mnExtKeyMod == 0 )
3303             mbSendExtKeyModChange = true;
3304         else if( pEvent->type == KeyRelease && mbSendExtKeyModChange )
3305         {
3306             aModEvt.mnModKeyCode = mnExtKeyMod;
3307             mnExtKeyMod = 0;
3308         }
3309 
3310 		// pressing just the ctrl key leads to a keysym of XK_Control but
3311 		// the event state does not contain ControlMask. In the release
3312 		// event its the other way round: it does contain the Control mask.
3313 		// The modifier mode therefore has to be adapted manually.
3314         sal_uInt16 nExtModMask = 0;
3315         sal_uInt16 nModMask = 0;
3316         switch( nKeySym )
3317         {
3318             case XK_Control_L:
3319                 nExtModMask = MODKEY_LMOD1;
3320                 nModMask = KEY_MOD1;
3321                 break;
3322             case XK_Control_R:
3323                 nExtModMask = MODKEY_RMOD1;
3324                 nModMask = KEY_MOD1;
3325                 break;
3326             case XK_Alt_L:
3327                 nExtModMask = MODKEY_LMOD2;
3328                 nModMask = KEY_MOD2;
3329                 break;
3330             case XK_Alt_R:
3331                 nExtModMask = MODKEY_RMOD2;
3332                 nModMask = KEY_MOD2;
3333                 break;
3334             case XK_Shift_L:
3335                 nExtModMask = MODKEY_LSHIFT;
3336                 nModMask = KEY_SHIFT;
3337                 break;
3338             case XK_Shift_R:
3339                 nExtModMask = MODKEY_RSHIFT;
3340                 nModMask = KEY_SHIFT;
3341                 break;
3342             // Map Meta/Super keys to MOD3 modifier on all Unix systems
3343             // except Mac OS X
3344             case XK_Meta_L:
3345             case XK_Super_L:
3346                 nExtModMask = MODKEY_LMOD3;
3347                 nModMask = KEY_MOD3;
3348                 break;
3349             case XK_Meta_R:
3350             case XK_Super_R:
3351                 nExtModMask = MODKEY_RMOD3;
3352                 nModMask = KEY_MOD3;
3353                 break;
3354         }
3355         if( pEvent->type == KeyRelease )
3356         {
3357             nModCode &= ~nModMask;
3358             mnExtKeyMod &= ~nExtModMask;
3359         }
3360         else
3361         {
3362             nModCode |= nModMask;
3363             mnExtKeyMod |= nExtModMask;
3364         }
3365 
3366 		aModEvt.mnCode = nModCode;
3367 		aModEvt.mnTime = pEvent->time;
3368 
3369 		int nRet = CallCallback( SALEVENT_KEYMODCHANGE, &aModEvt );
3370 
3371         // emulate KEY_MENU
3372         if ( ( (nKeySym == XK_Alt_L) || (nKeySym == XK_Alt_R) ) &&
3373              ( (nModCode & ~(KEY_MOD3|KEY_MOD2)) == 0 ) )
3374         {
3375             if( pEvent->type == XLIB_KeyPress )
3376                 mbKeyMenu = true;
3377             else if( mbKeyMenu )
3378             {
3379                 // simulate KEY_MENU
3380                 aKeyEvt.mnCode	   = KEY_MENU | nModCode;
3381                 aKeyEvt.mnRepeat   = 0;
3382                 aKeyEvt.mnTime	   = pEvent->time;
3383                 aKeyEvt.mnCharCode = 0;
3384                 nRet = CallCallback( SALEVENT_KEYINPUT, &aKeyEvt );
3385                 nRet = CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3386             }
3387         }
3388         else
3389             mbKeyMenu = false;
3390         return nRet;
3391 	}
3392 
3393     mbSendExtKeyModChange = mbKeyMenu = false;
3394 
3395 	// try to figure out the vcl code for the keysym
3396     // #i52338# use the unmodified KeySym if there is none for the real KeySym
3397     // because the independent part has only keycodes for unshifted keys
3398 	nKeyCode = pDisplay_->GetKeyCode( nKeySym, &aDummy );
3399     if( nKeyCode == 0 )
3400         nKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy );
3401 
3402 	// try to figure out a printable if XmbLookupString returns only a keysym
3403 	// and NOT a printable. Do not store it in pPrintable[0] since it is expected to
3404 	// be in system encoding, not unicode.
3405     // #i8988##, if KeySym and printable look equally promising then prefer KeySym
3406     // the printable is bound to the encoding so the KeySym might contain more
3407     // information (in et_EE locale: "Compose + Z + <" delivers "," in printable and
3408     // (the desired) Zcaron in KeySym
3409 	sal_Unicode nKeyString = 0x0;
3410 	if (   (nLen == 0)
3411         || ((nLen == 1) && (nKeySym > 0)) )
3412 		nKeyString = KeysymToUnicode (nKeySym);
3413 	// if we have nothing we give up
3414 	if( !nKeyCode && !nLen && !nKeyString)
3415 		return 0;
3416 
3417     DeletionListener aDeleteWatch( this );
3418 
3419     if( nModCode == (KEY_SHIFT | KEY_MOD1) && pEvent->type == XLIB_KeyPress )
3420     {
3421         sal_uInt16 nSeqKeyCode = pDisplay_->GetKeyCode( nUnmodifiedKeySym, &aDummy );
3422         if( nSeqKeyCode == KEY_U )
3423         {
3424             beginUnicodeSequence();
3425             return 1;
3426         }
3427         else if( nSeqKeyCode >= KEY_0 && nSeqKeyCode <= KEY_9 )
3428         {
3429             if( appendUnicodeSequence( sal_Unicode( '0' ) + sal_Unicode(nSeqKeyCode - KEY_0) ) )
3430                 return 1;
3431         }
3432         else if( nSeqKeyCode >= KEY_A && nSeqKeyCode <= KEY_F )
3433         {
3434             if( appendUnicodeSequence( sal_Unicode( 'a' ) + sal_Unicode(nSeqKeyCode - KEY_A) ) )
3435                 return 1;
3436         }
3437         else
3438             endUnicodeSequence();
3439     }
3440 
3441     if( aDeleteWatch.isDeleted() )
3442         return 0;
3443 
3444 	rtl_TextEncoding nEncoding;
3445 
3446     if (mpInputContext != NULL && mpInputContext->IsMultiLingual() )
3447         nEncoding = RTL_TEXTENCODING_UTF8;
3448     else
3449         nEncoding = osl_getThreadTextEncoding();
3450 
3451 	sal_Unicode *pBuffer;
3452 	sal_Unicode *pString;
3453 	sal_Size     nBufferSize = nLen * 2;
3454 	sal_Size     nSize;
3455 	pBuffer = (sal_Unicode*) malloc( nBufferSize + 2 );
3456 	pBuffer[ 0 ] = 0;
3457 
3458 	if (nKeyString != 0)
3459 	{
3460 		pString = &nKeyString;
3461 		nSize = 1;
3462 	}
3463 	else
3464 	if (nLen > 0 && nEncoding != RTL_TEXTENCODING_UNICODE)
3465 	{
3466 		// create text converter
3467 		rtl_TextToUnicodeConverter aConverter =
3468 				rtl_createTextToUnicodeConverter( nEncoding );
3469 		rtl_TextToUnicodeContext aContext =
3470 			 	rtl_createTextToUnicodeContext( aConverter );
3471 
3472 		sal_uInt32  nConversionInfo;
3473 		sal_Size    nConvertedChars;
3474 
3475 		// convert to single byte text stream
3476 		nSize = rtl_convertTextToUnicode(
3477 				                aConverter, aContext,
3478                                 (char*)pPrintable, nLen,
3479                                 pBuffer, nBufferSize,
3480                                 RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE |
3481                                 RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE,
3482                                 &nConversionInfo, &nConvertedChars );
3483 
3484 		// destroy converter
3485 		rtl_destroyTextToUnicodeContext( aConverter, aContext );
3486 		rtl_destroyTextToUnicodeConverter( aConverter );
3487 
3488 		pString = pBuffer;
3489 	}
3490 	else
3491 	if (nLen > 0 /* nEncoding == RTL_TEXTENCODING_UNICODE */)
3492 	{
3493 		pString = (sal_Unicode*)pPrintable;
3494 	  	nSize = nLen;
3495 	}
3496     else
3497     {
3498         pString = pBuffer;
3499         nSize   = 0;
3500     }
3501 
3502 	if (   mpInputContext != NULL
3503 		&& mpInputContext->UseContext()
3504 		&& KeyRelease != pEvent->type
3505 		&& (   (nSize >  1)
3506             || (nSize >  0 && mpInputContext->IsPreeditMode())) )
3507 	{
3508         mpInputContext->CommitKeyEvent(pString, nSize);
3509 	}
3510 	else
3511     // normal single character keyinput
3512 	{
3513 		aKeyEvt.mnCode	   = nKeyCode | nModCode;
3514 		aKeyEvt.mnRepeat   = 0;
3515 		aKeyEvt.mnTime	   = pEvent->time;
3516 		aKeyEvt.mnCharCode = pString[ 0 ];
3517 
3518 		if( KeyRelease == pEvent->type )
3519 		{
3520 			CallCallback( SALEVENT_KEYUP, &aKeyEvt );
3521 		}
3522 		else
3523 		{
3524 			if ( ! CallCallback(SALEVENT_KEYINPUT, &aKeyEvt) )
3525 			{
3526 				// independent layer doesnt want to handle key-event, so check
3527 				// whether the keycode may have an alternate meaning
3528 				KeyAlternate aAlternate = GetAlternateKeyCode( nKeyCode );
3529 				if ( aAlternate.nKeyCode != 0 )
3530 				{
3531 					aKeyEvt.mnCode = aAlternate.nKeyCode | nModCode;
3532 					if( aAlternate.nCharCode )
3533 						aKeyEvt.mnCharCode = aAlternate.nCharCode;
3534 					CallCallback(SALEVENT_KEYINPUT, &aKeyEvt);
3535 				}
3536 			}
3537 		}
3538 	}
3539 
3540   	//
3541   	// update the spot location for PreeditPosition IME style
3542   	//
3543     if (! aDeleteWatch.isDeleted())
3544     {
3545         if (mpInputContext != NULL && mpInputContext->UseContext())
3546             mpInputContext->UpdateSpotLocation();
3547     }
3548 
3549 	free (pBuffer);
3550 	return True;
3551 }
3552 
3553 
3554 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3555 long X11SalFrame::HandleFocusEvent( XFocusChangeEvent *pEvent )
3556 {
3557     // #107739# ReflectionX in Windows mode changes focus while mouse is grabbed
3558 	if( nVisibleFloats > 0 && GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "ReflectionX Windows" ) )
3559 		return 1;
3560 
3561 	/*	#55691# ignore focusout resulting from keyboard grabs
3562 	 *	we do not grab it and are not interested when
3563 	 *	someone else does CDE e.g. does a XGrabKey on arrow keys
3564 	 *	#73179# handle focus events with mode NotifyWhileGrabbed
3565 	 *	because with CDE alt-tab focus changing we do not get
3566 	 *	normal focus events
3567 	 *	#71791# cast focus event to the input context, otherwise the
3568 	 *	status window does not follow the application frame
3569 	 */
3570 
3571 	if ( mpInputContext != NULL  )
3572 	{
3573 		if( FocusIn == pEvent->type )
3574             mpInputContext->SetICFocus( this );
3575         else
3576         {
3577             /*
3578              *  do not unset the IC focuse here because would kill
3579              *  a lookup choice windows that might have the focus now
3580              *  	mpInputContext->UnsetICFocus( this );
3581              */
3582             I18NStatus::get().show( false, I18NStatus::focus );
3583         }
3584 	}
3585 
3586 
3587 	if ( pEvent->mode == NotifyNormal || pEvent->mode == NotifyWhileGrabbed ||
3588          ( ( nStyle_ & SAL_FRAME_STYLE_PLUG ) && pEvent->window == GetShellWindow() )
3589          )
3590 	{
3591         if( hPresentationWindow != None && hPresentationWindow != GetShellWindow() )
3592             return 0;
3593 
3594 		if( FocusIn == pEvent->type )
3595 		{
3596             vcl_sal::PrinterUpdate::update();
3597 			mbInputFocus = True;
3598             ImplSVData* pSVData = ImplGetSVData();
3599 
3600 
3601 
3602 			long nRet = CallCallback( SALEVENT_GETFOCUS,  0 );
3603             if ((mpParent != NULL && nStyle_ == 0)
3604                 && pSVData->maWinData.mpFirstFloat )
3605             {
3606                 sal_uLong nMode = pSVData->maWinData.mpFirstFloat->GetPopupModeFlags();
3607                 pSVData->maWinData.mpFirstFloat->SetPopupModeFlags(
3608                                         nMode & ~(FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE));
3609             }
3610             return nRet;
3611 		}
3612 		else
3613 		{
3614 			mbInputFocus = False;
3615             mbSendExtKeyModChange = mbKeyMenu = false;
3616             mnExtKeyMod = 0;
3617 			return CallCallback( SALEVENT_LOSEFOCUS, 0 );
3618 		}
3619 	}
3620 
3621 	return 0;
3622 }
3623 
3624 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3625 
3626 long X11SalFrame::HandleExposeEvent( XEvent *pEvent )
3627 {
3628 	XRectangle	aRect = { 0, 0, 0, 0 };
3629 	sal_uInt16		nCount = 0;
3630 
3631 	if( pEvent->type == Expose )
3632 	{
3633 		aRect.x 		= pEvent->xexpose.x;
3634 		aRect.y 		= pEvent->xexpose.y;
3635 		aRect.width 	= pEvent->xexpose.width;
3636 		aRect.height	= pEvent->xexpose.height;
3637 		nCount			= pEvent->xexpose.count;
3638 	}
3639 	else if( pEvent->type == GraphicsExpose )
3640 	{
3641 		aRect.x 		= pEvent->xgraphicsexpose.x;
3642 		aRect.y 		= pEvent->xgraphicsexpose.y;
3643 		aRect.width 	= pEvent->xgraphicsexpose.width;
3644 		aRect.height	= pEvent->xgraphicsexpose.height;
3645 		nCount			= pEvent->xgraphicsexpose.count;
3646 	}
3647 
3648     if( IsOverrideRedirect() && mbFullScreen &&
3649         aPresentationReparentList.begin() == aPresentationReparentList.end() )
3650 		// we are in fullscreen mode -> override redirect
3651  		// focus is possibly lost, so reget it
3652  		XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToNone, CurrentTime );
3653 
3654     // width and height are extents, so they are of by one for rectangle
3655     maPaintRegion.Union( Rectangle( Point(aRect.x, aRect.y), Size(aRect.width+1, aRect.height+1) ) );
3656 
3657 	if( nCount )
3658         // wait for last expose rectangle, do not wait for resize timer
3659         // if a completed graphics expose sequence is available
3660 		return 1;
3661 
3662 	SalPaintEvent aPEvt( maPaintRegion.Left(), maPaintRegion.Top(), maPaintRegion.GetWidth(), maPaintRegion.GetHeight() );
3663 
3664  	CallCallback( SALEVENT_PAINT, &aPEvt );
3665     maPaintRegion = Rectangle();
3666 
3667 	return 1;
3668 }
3669 
3670 void X11SalFrame::RestackChildren( XLIB_Window* pTopLevelWindows, int nTopLevelWindows )
3671 {
3672     if( maChildren.begin() != maChildren.end() )
3673     {
3674         int nWindow = nTopLevelWindows;
3675         while( nWindow-- )
3676             if( pTopLevelWindows[nWindow] == GetStackingWindow() )
3677                 break;
3678         if( nWindow < 0 )
3679             return;
3680 
3681         std::list< X11SalFrame* >::const_iterator it;
3682         for( it = maChildren.begin(); it != maChildren.end(); ++it )
3683         {
3684             X11SalFrame* pData = *it;
3685             if( pData->bMapped_ )
3686             {
3687                 int nChild = nWindow;
3688                 while( nChild-- )
3689                 {
3690                     if( pTopLevelWindows[nChild] == pData->GetStackingWindow() )
3691                     {
3692                         // if a child is behind its parent, place it above the
3693                         // parent (for insane WMs like Dtwm and olwm)
3694                         XWindowChanges aCfg;
3695                         aCfg.sibling	= GetStackingWindow();
3696                         aCfg.stack_mode	= Above;
3697                         XConfigureWindow( GetXDisplay(), pData->GetStackingWindow(), CWSibling|CWStackMode, &aCfg );
3698                         break;
3699                     }
3700                 }
3701             }
3702         }
3703         for( it = maChildren.begin(); it != maChildren.end(); ++it )
3704         {
3705             X11SalFrame* pData = *it;
3706             pData->RestackChildren( pTopLevelWindows, nTopLevelWindows );
3707         }
3708     }
3709 }
3710 
3711 void X11SalFrame::RestackChildren()
3712 {
3713     if( ! GetDisplay()->getWMAdaptor()->isTransientBehaviourAsExpected()
3714         && maChildren.begin() != maChildren.end() )
3715     {
3716         XLIB_Window aRoot, aParent, *pChildren = NULL;
3717         unsigned int nChildren;
3718         if( XQueryTree( GetXDisplay(),
3719                         GetDisplay()->GetRootWindow( m_nScreen ),
3720                         &aRoot,
3721                         &aParent,
3722                         &pChildren,
3723                         &nChildren ) )
3724         {
3725             RestackChildren( pChildren, nChildren );
3726             XFree( pChildren );
3727         }
3728     }
3729 }
3730 
3731 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3732 long X11SalFrame::HandleSizeEvent( XConfigureEvent *pEvent )
3733 {
3734 	if (   pEvent->window != GetShellWindow()
3735            && pEvent->window != GetWindow()
3736            && pEvent->window != GetForeignParent()
3737            && pEvent->window != GetStackingWindow()
3738            )
3739 	{
3740 		// could be as well a sys-child window (aka SalObject)
3741 		return 1;
3742 	}
3743 
3744 
3745 	if( ( nStyle_ & SAL_FRAME_STYLE_PLUG ) && pEvent->window == GetShellWindow() )
3746 	{
3747 		// just update the children's positions
3748 		RestackChildren();
3749 		return 1;
3750 	}
3751 
3752 	if( pEvent->window == GetForeignParent() )
3753         XResizeWindow( GetXDisplay(),
3754                        GetWindow(),
3755                        pEvent->width,
3756                        pEvent->height );
3757 
3758 	XLIB_Window hDummy;
3759 	XTranslateCoordinates( GetXDisplay(),
3760 						   GetWindow(),
3761 						   pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() ),
3762 						   0, 0,
3763 						   &pEvent->x, &pEvent->y,
3764 						   &hDummy );
3765 
3766     if( pEvent->window == GetStackingWindow() )
3767     {
3768         if( maGeometry.nX != pEvent->x || maGeometry.nY != pEvent->y )
3769         {
3770             maGeometry.nX = pEvent->x;
3771             maGeometry.nY = pEvent->y;
3772             CallCallback( SALEVENT_MOVE, NULL );
3773         }
3774         return 1;
3775     }
3776 
3777     // check size hints in first time SalFrame::Show
3778 	if( SHOWSTATE_UNKNOWN == nShowState_ && bMapped_ )
3779         nShowState_ = SHOWSTATE_NORMAL;
3780 
3781     nWidth_ 	= pEvent->width;
3782     nHeight_	= pEvent->height;
3783 
3784     bool bMoved = ( pEvent->x != maGeometry.nX || pEvent->y != maGeometry.nY );
3785     bool bSized = ( pEvent->width != (int)maGeometry.nWidth || pEvent->height != (int)maGeometry.nHeight );
3786 
3787     maGeometry.nX		= pEvent->x;
3788     maGeometry.nY		= pEvent->y;
3789     maGeometry.nWidth	= pEvent->width;
3790     maGeometry.nHeight	= pEvent->height;
3791     updateScreenNumber();
3792 
3793 	// update children's position
3794 	RestackChildren();
3795 
3796     if( bSized && ! bMoved )
3797         CallCallback( SALEVENT_RESIZE, NULL );
3798     else if( bMoved && ! bSized )
3799         CallCallback( SALEVENT_MOVE, NULL );
3800     else if( bMoved && bSized )
3801         CallCallback( SALEVENT_MOVERESIZE, NULL );
3802 
3803 	return 1;
3804 }
3805 
3806 IMPL_LINK( X11SalFrame, HandleAlwaysOnTopRaise, void*, EMPTYARG )
3807 {
3808     if( bMapped_ )
3809         ToTop( 0 );
3810     return 0;
3811 }
3812 
3813 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3814 long X11SalFrame::HandleReparentEvent( XReparentEvent *pEvent )
3815 {
3816 	Display 	   *pDisplay   = pEvent->display;
3817 	XLIB_Window 	hWM_Parent;
3818 	XLIB_Window 	hRoot, *Children, hDummy;
3819 	unsigned int	nChildren;
3820 	sal_Bool			bNone = pDisplay_->GetProperties()
3821 							& PROPERTY_SUPPORT_WM_Parent_Pixmap_None;
3822     sal_Bool            bAccessParentWindow = ! (pDisplay_->GetProperties()
3823 							& PROPERTY_FEATURE_TrustedSolaris);
3824 
3825 	static const char* pDisableStackingCheck = getenv( "SAL_DISABLE_STACKING_CHECK" );
3826 
3827     GetDisplay()->GetXLib()->PushXErrorLevel( true );
3828 
3829     /*
3830      *  #89186# don't rely on the new parent from the event.
3831      *  the event may be "out of date", that is the window manager
3832      *  window may not exist anymore. This can happen if someone
3833      *  shows a frame and hides it again quickly (not that that would
3834      *  be very sensible)
3835      */
3836     hWM_Parent = GetShellWindow();
3837     do
3838     {
3839         Children = NULL;
3840         XQueryTree( pDisplay,
3841                     hWM_Parent,
3842                     &hRoot,
3843                     &hDummy,
3844                     &Children,
3845                     &nChildren );
3846         if( GetDisplay()->GetXLib()->HasXErrorOccured() )
3847         {
3848             hWM_Parent = GetShellWindow();
3849             break;
3850         }
3851          /* #107048# this sometimes happens if a Show(sal_True) is
3852          *  immediately followed by Show(sal_False) (which is braindead anyway)
3853          */
3854         if(  hDummy == hWM_Parent )
3855             hDummy = hRoot;
3856         if( hDummy != hRoot )
3857         {
3858             hWM_Parent = hDummy;
3859             if( bAccessParentWindow && bNone )
3860                 XSetWindowBackgroundPixmap( pDisplay, hWM_Parent, None );
3861         }
3862         if( Children )
3863             XFree( Children );
3864     } while( hDummy != hRoot );
3865 
3866 	if( GetStackingWindow() == None
3867         && hWM_Parent != hPresentationWindow
3868         && hWM_Parent != GetShellWindow()
3869         && ( ! pDisableStackingCheck || ! *pDisableStackingCheck )
3870         )
3871 	{
3872 		mhStackingWindow = hWM_Parent;
3873 		if (bAccessParentWindow)
3874             XSelectInput( pDisplay, GetStackingWindow(), StructureNotifyMask );
3875 	}
3876 
3877 	if( 	hWM_Parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() )
3878             || 	hWM_Parent == GetForeignParent()
3879             || 	pEvent->parent == pDisplay_->GetRootWindow( pDisplay_->GetDefaultScreenNumber() )
3880             || ( nStyle_ & SAL_FRAME_STYLE_FLOAT ) )
3881 	{
3882 		// Reparenting before Destroy
3883         aPresentationReparentList.remove( GetStackingWindow() );
3884 		mhStackingWindow = None;
3885         GetDisplay()->GetXLib()->PopXErrorLevel();
3886 		return 0;
3887 	}
3888 
3889     /*
3890      *  evil hack to show decorated windows on top
3891      *  of override redirect presentation windows:
3892      *  reparent the window manager window to the presentation window
3893      *  does not work with non-reparenting WMs
3894      *  in future this should not be necessary anymore with
3895      *  _NET_WM_STATE_FULLSCREEN available
3896      */
3897     if( hPresentationWindow != None
3898         && hPresentationWindow != GetWindow()
3899         && GetStackingWindow() != None
3900         && GetStackingWindow() != GetDisplay()->GetRootWindow( m_nScreen )
3901         )
3902     {
3903         int x = 0, y = 0;
3904         XLIB_Window aChild;
3905         XTranslateCoordinates( GetXDisplay(),
3906                                GetStackingWindow(),
3907                                GetDisplay()->GetRootWindow( m_nScreen ),
3908                                0, 0,
3909                                &x, &y,
3910                                &aChild
3911                                );
3912         XReparentWindow( GetXDisplay(),
3913                          GetStackingWindow(),
3914                          hPresentationWindow,
3915                          x, y
3916                          );
3917         aPresentationReparentList.push_back( GetStackingWindow() );
3918     }
3919 
3920     int nLeft = 0, nTop = 0;
3921 	XTranslateCoordinates( GetXDisplay(),
3922                            GetShellWindow(),
3923                            hWM_Parent,
3924                            0, 0,
3925                            &nLeft,
3926                            &nTop,
3927                            &hDummy );
3928     maGeometry.nLeftDecoration	= nLeft > 0 ? nLeft-1 : 0;
3929     maGeometry.nTopDecoration	= nTop  > 0 ? nTop-1  : 0;
3930 
3931     /*
3932      *  decorations are not symmetric,
3933      *  so need real geometries here
3934      *  (this will fail with virtual roots ?)
3935      */
3936     GetDisplay()->GetXLib()->ResetXErrorOccured();
3937     int xp, yp, x, y;
3938     unsigned int wp, w, hp, h, bw, d;
3939     XGetGeometry( GetXDisplay(),
3940                   GetShellWindow(),
3941                   &hRoot,
3942                   &x, &y, &w, &h, &bw, &d );
3943     XGetGeometry( GetXDisplay(),
3944                   hWM_Parent,
3945                   &hRoot,
3946                   &xp, &yp, &wp, &hp, &bw, &d );
3947     bool bResized = false;
3948     if( ! GetDisplay()->GetXLib()->HasXErrorOccured() )
3949     {
3950         maGeometry.nRightDecoration 	= wp - w - maGeometry.nLeftDecoration;
3951         maGeometry.nBottomDecoration	= hp - h - maGeometry.nTopDecoration;
3952         /*
3953          *  note: this works because hWM_Parent is direct child of root,
3954          *  not necessarily parent of GetShellWindow()
3955          */
3956         maGeometry.nX		= xp + nLeft;
3957         maGeometry.nY		= yp + nTop;
3958         bResized = w != maGeometry.nWidth || h != maGeometry.nHeight;
3959         maGeometry.nWidth	= w;
3960         maGeometry.nHeight = h;
3961     }
3962 
3963 
3964     // limit width and height if we are too large: #47757
3965     // olwm and fvwm need this, it doesnt harm the rest
3966 
3967     // #i81311# do this only for sizable frames
3968     if( (nStyle_ & SAL_FRAME_STYLE_SIZEABLE) != 0 )
3969     {
3970         Size aScreenSize = GetDisplay()->GetScreenSize( m_nScreen );
3971         int nScreenWidth  = aScreenSize.Width();
3972         int nScreenHeight = aScreenSize.Height();
3973         int nFrameWidth   = maGeometry.nWidth + maGeometry.nLeftDecoration + maGeometry.nRightDecoration;
3974         int nFrameHeight  = maGeometry.nHeight + maGeometry.nTopDecoration  + maGeometry.nBottomDecoration;
3975 
3976         if ((nFrameWidth > nScreenWidth) || (nFrameHeight > nScreenHeight))
3977         {
3978             Size aSize(maGeometry.nWidth, maGeometry.nHeight);
3979 
3980             if (nFrameWidth  > nScreenWidth)
3981                 aSize.Width()  = nScreenWidth  - maGeometry.nRightDecoration - maGeometry.nLeftDecoration;
3982             if (nFrameHeight > nScreenHeight)
3983                 aSize.Height() = nScreenHeight - maGeometry.nBottomDecoration - maGeometry.nTopDecoration;
3984 
3985             SetSize( aSize );
3986             bResized = false;
3987         }
3988     }
3989     if( bResized )
3990         CallCallback( SALEVENT_RESIZE, NULL );
3991 
3992     GetDisplay()->GetXLib()->PopXErrorLevel();
3993 
3994 	return 1;
3995 }
3996 
3997 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
3998 long X11SalFrame::HandleColormapEvent( XColormapEvent* )
3999 {
4000 	return 0;
4001 }
4002 
4003 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
4004 long X11SalFrame::HandleStateEvent( XPropertyEvent *pEvent )
4005 {
4006 	Atom		  actual_type;
4007 	int 		  actual_format;
4008 	unsigned long nitems, bytes_after;
4009 	unsigned char *prop = NULL;
4010 
4011 	if( 0 != XGetWindowProperty( GetXDisplay(),
4012 								 GetShellWindow(),
4013 								 pEvent->atom,			// property
4014 								 0, 					// long_offset (32bit)
4015 								 2, 					// long_length (32bit)
4016 								 False, 				// delete
4017 								 pEvent->atom,			// req_type
4018 								 &actual_type,
4019 								 &actual_format,
4020 								 &nitems,
4021 								 &bytes_after,
4022 								 &prop )
4023 		|| ! prop
4024 		)
4025 		return 0;
4026 
4027 	DBG_ASSERT( actual_type = pEvent->atom
4028 				&& 32 == actual_format
4029 				&&	2 == nitems
4030 				&&	0 == bytes_after, "HandleStateEvent" );
4031 
4032 	if( *(unsigned long*)prop == NormalState )
4033 		nShowState_ = SHOWSTATE_NORMAL;
4034 	else if( *(unsigned long*)prop == IconicState )
4035 		nShowState_ = SHOWSTATE_MINIMIZED;
4036 
4037 	XFree( prop );
4038 	return 1;
4039 }
4040 
4041 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
4042 long X11SalFrame::HandleClientMessage( XClientMessageEvent *pEvent )
4043 {
4044     const WMAdaptor& rWMAdaptor( *pDisplay_->getWMAdaptor() );
4045 
4046 #if !defined(__synchronous_extinput__)
4047 	if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_EXTTEXTEVENT ) )
4048 	{
4049 		HandleExtTextEvent (pEvent);
4050 		return 1;
4051 	}
4052 #endif
4053 	else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::SAL_QUITEVENT ) )
4054 	{
4055 		stderr0( "X11SalFrame::Dispatch Quit\n" );
4056 		Close(); // ???
4057 		return 1;
4058 	}
4059 	else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::WM_PROTOCOLS ) )
4060     {
4061         if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::NET_WM_PING ) )
4062             rWMAdaptor.answerPing( this, pEvent );
4063         else if( ! ( nStyle_ & SAL_FRAME_STYLE_PLUG )
4064               && ! (( nStyle_ & SAL_FRAME_STYLE_FLOAT ) && (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION))
4065              )
4066         {
4067             if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_DELETE_WINDOW ) )
4068             {
4069                 Close();
4070                 return 1;
4071             }
4072             else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_TAKE_FOCUS ) )
4073             {
4074                 // do nothing, we set the input focus in ToTop() if necessary
4075     #if OSL_DEBUG_LEVEL > 1
4076                 fprintf( stderr, "got WM_TAKE_FOCUS on %s window\n",
4077                          (nStyle_&SAL_FRAME_STYLE_OWNERDRAWDECORATION) ?
4078                          "ownerdraw" : "NON OWNERDRAW" );
4079     #endif
4080             }
4081             else if( (Atom)pEvent->data.l[0] == rWMAdaptor.getAtom( WMAdaptor::WM_SAVE_YOURSELF ) )
4082             {
4083                 bool bSession = rWMAdaptor.getWindowManagerName().EqualsAscii( "Dtwm" );
4084 
4085                 if( ! bSession )
4086                 {
4087                     if( this == s_pSaveYourselfFrame )
4088                     {
4089                         ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
4090                         const char* argv[2];
4091                         argv[0] = "/bin/sh";
4092                         argv[1] = const_cast<char*>(aExec.GetBuffer());
4093     #if OSL_DEBUG_LEVEL > 1
4094                         fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] );
4095     #endif
4096                         XSetCommand( GetXDisplay(), GetShellWindow(), (char**)argv, 2 );
4097                     }
4098                     else
4099                         // can only happen in race between WM and window closing
4100                         XChangeProperty( GetXDisplay(), GetShellWindow(), rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 );
4101                 }
4102                 else
4103                 {
4104                     // save open documents; would be good for non Dtwm, too,
4105                     // but there is no real Shutdown message in the ancient
4106                     // SM protocol; on Dtwm SaveYourself really means Shutdown, too.
4107                     IceSalSession::handleOldX11SaveYourself( this );
4108                 }
4109             }
4110         }
4111     }
4112     else if( pEvent->message_type == rWMAdaptor.getAtom( WMAdaptor::XEMBED ) &&
4113              pEvent->window == GetWindow() )
4114     {
4115         if( pEvent->data.l[1] == 1 || // XEMBED_WINDOW_ACTIVATE
4116             pEvent->data.l[1] == 2 )  // XEMBED_WINDOW_DEACTIVATE
4117         {
4118             XFocusChangeEvent aEvent;
4119             aEvent.type         = (pEvent->data.l[1] == 1 ? FocusIn : FocusOut);
4120             aEvent.serial       = pEvent->serial;
4121             aEvent.send_event   = True;
4122             aEvent.display      = pEvent->display;
4123             aEvent.window       = pEvent->window;
4124             aEvent.mode         = NotifyNormal;
4125             aEvent.detail       = NotifyDetailNone;
4126             HandleFocusEvent( &aEvent );
4127         }
4128     }
4129 	return 0;
4130 }
4131 
4132 void X11SalFrame::SaveYourselfDone( SalFrame* pSaveFrame )
4133 {
4134     // session save was done, inform dtwm
4135     if( s_pSaveYourselfFrame && pSaveFrame )
4136     {
4137         ByteString aExec( SessionManagerClient::getExecName(), osl_getThreadTextEncoding() );
4138         const char* argv[2];
4139         argv[0] = "/bin/sh";
4140         argv[1] = const_cast<char*>(aExec.GetBuffer());
4141 #if OSL_DEBUG_LEVEL > 1
4142         fprintf( stderr, "SaveYourself request, setting command: %s %s\n", argv[0], argv[1] );
4143 #endif
4144         XSetCommand( s_pSaveYourselfFrame->GetXDisplay(),
4145                      s_pSaveYourselfFrame->GetShellWindow(),
4146                      (char**)argv, 2 );
4147         if( pSaveFrame != s_pSaveYourselfFrame )
4148         {
4149             // check if it still exists
4150             const X11SalFrame* pFrame = NULL;
4151             const std::list< SalFrame* >& rFrames = static_cast<X11SalFrame*>(pSaveFrame)->GetDisplay()->getFrames();
4152             std::list< SalFrame* >::const_iterator it = rFrames.begin();
4153             while( it != rFrames.end() )
4154             {
4155                 pFrame = static_cast< const X11SalFrame* >(*it);
4156                 if( pFrame == pSaveFrame )
4157                     break;
4158                 ++it;
4159             }
4160             if( pFrame == pSaveFrame )
4161             {
4162                 const WMAdaptor& rWMAdaptor( *pFrame->pDisplay_->getWMAdaptor() );
4163                 XChangeProperty( pFrame->GetXDisplay(),
4164                                  pFrame->GetShellWindow(),
4165                                  rWMAdaptor.getAtom( WMAdaptor::WM_COMMAND ), XA_STRING, 8, PropModeReplace, (unsigned char*)"", 0 );
4166             }
4167         }
4168         s_pSaveYourselfFrame->ShutDown();
4169     }
4170 }
4171 
4172 // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
4173 
4174 extern "C"
4175 {
4176 Bool call_checkKeyReleaseForRepeat( Display* pDisplay, XEvent* pCheck, XPointer pX11SalFrame )
4177 {
4178     return X11SalFrame::checkKeyReleaseForRepeat( pDisplay, pCheck, pX11SalFrame );
4179 }
4180 }
4181 
4182 Bool X11SalFrame::checkKeyReleaseForRepeat( Display*, XEvent* pCheck, XPointer pX11SalFrame )
4183 {
4184 	X11SalFrame* pThis = (X11SalFrame*)pX11SalFrame;
4185 	return
4186 		pCheck->type			== XLIB_KeyPress &&
4187 		pCheck->xkey.state		== pThis->nKeyState_ &&
4188 		pCheck->xkey.keycode	== pThis->nKeyCode_ &&
4189 		pCheck->xkey.time		== pThis->nReleaseTime_  ? True : False;
4190 }
4191 
4192 long X11SalFrame::Dispatch( XEvent *pEvent )
4193 {
4194 	long nRet = 0;
4195 
4196 	if( -1 == nCaptured_ )
4197 	{
4198 		CaptureMouse( sal_True );
4199 #ifdef DBG_UTIL
4200 		if( -1 != nCaptured_ )
4201 			pDisplay_->PrintEvent( "Captured", pEvent );
4202 #endif
4203 	}
4204 
4205 	if( pEvent->xany.window == GetShellWindow() || pEvent->xany.window == GetWindow() )
4206 	{
4207 		switch( pEvent->type )
4208 		{
4209 			case XLIB_KeyPress:
4210 				nKeyCode_	= pEvent->xkey.keycode;
4211 				nKeyState_	= pEvent->xkey.state;
4212 				nRet		= HandleKeyEvent( &pEvent->xkey );
4213 				break;
4214 
4215 			case KeyRelease:
4216 				if( -1 == nCompose_ )
4217 				{
4218 					nReleaseTime_ = pEvent->xkey.time;
4219 					XEvent aEvent;
4220 					if( XCheckIfEvent( pEvent->xkey.display, &aEvent, call_checkKeyReleaseForRepeat, (XPointer)this ) )
4221 						XPutBackEvent( pEvent->xkey.display, &aEvent );
4222 					else
4223 						nRet		= HandleKeyEvent( &pEvent->xkey );
4224 				}
4225 			break;
4226 
4227 			case ButtonPress:
4228 				// #74406# if we loose the focus in presentation mode
4229 				// there are good chances that we never get it back
4230 				// since the WM ignores us
4231  				if( IsOverrideRedirect() )
4232  				{
4233  					XSetInputFocus( GetXDisplay(), GetShellWindow(),
4234  							RevertToNone, CurrentTime );
4235  				}
4236 
4237 			case ButtonRelease:
4238 			case MotionNotify:
4239 			case EnterNotify:
4240 			case LeaveNotify:
4241 				nRet = HandleMouseEvent( pEvent );
4242 				break;
4243 
4244 			case FocusIn:
4245 			case FocusOut:
4246 				nRet = HandleFocusEvent( &pEvent->xfocus );
4247 				break;
4248 
4249 			case Expose:
4250 			case GraphicsExpose:
4251 				nRet = HandleExposeEvent( pEvent );
4252 				break;
4253 
4254 			case MapNotify:
4255 				if( pEvent->xmap.window == GetShellWindow() )
4256 				{
4257                     if( nShowState_ == SHOWSTATE_HIDDEN )
4258                     {
4259                         /*
4260                          *  #95097# workaround for (at least) KWin 2.2.2
4261                          *  which will map windows that were once transient
4262                          *  even if they are withdrawn when the respective
4263                          *  document is mapped.
4264                          */
4265                         if( ! (nStyle_ & SAL_FRAME_STYLE_PLUG) )
4266                             XUnmapWindow( GetXDisplay(), GetShellWindow() );
4267                         break;
4268                     }
4269 					bMapped_   = sal_True;
4270 					bViewable_ = sal_True;
4271 					nRet = sal_True;
4272 					if ( mpInputContext != NULL )
4273 						mpInputContext->Map( this );
4274                     CallCallback( SALEVENT_RESIZE, NULL );
4275                     if( pDisplay_->GetServerVendor() == vendor_hummingbird )
4276                     {
4277                         /*
4278                          *  With Exceed sometimes there does not seem to be
4279                          *  an Expose after the MapNotify.
4280                          *  so start a delayed paint here
4281                          */
4282                         maPaintRegion.Union( Rectangle( Point( 0, 0 ), Size( maGeometry.nWidth, maGeometry.nHeight ) ) );
4283                         XEvent aEvent;
4284                         aEvent.xexpose.type		= Expose;
4285                         aEvent.xexpose.display	= pDisplay_->GetDisplay();
4286                         aEvent.xexpose.x		= 0;
4287                         aEvent.xexpose.y		= 0;
4288                         aEvent.xexpose.width	= maGeometry.nWidth;
4289                         aEvent.xexpose.height	= maGeometry.nHeight;
4290                         aEvent.xexpose.count	= 0;
4291                         XSendEvent( pDisplay_->GetDisplay(),
4292                                     GetWindow(),
4293                                     True,
4294                                     ExposureMask,
4295                                     &aEvent );
4296                     }
4297 
4298                     bool bSetFocus = m_bSetFocusOnMap;
4299                     /*  #99570# another workaround for sawfish: if a transient window for the same parent is shown
4300                      *  sawfish does not set the focus to it. Applies only for click to focus mode.
4301                      */
4302                     if( ! (nStyle_ & SAL_FRAME_STYLE_FLOAT ) && mbInShow && GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Sawfish" ) )
4303                     {
4304                         // #101775# don't set the focus into the IME status window
4305                         // since this will lead to a parent loose-focus, close status,
4306                         // reget focus, open status, .... flicker loop
4307                         if ( (I18NStatus::get().getStatusFrame() != this) )
4308                             bSetFocus = true;
4309                     }
4310 
4311                     /*
4312                      *  sometimes a message box/dialogue is brought up when a frame is not mapped
4313                      *  the corresponding TRANSIENT_FOR hint is then set to the root window
4314                      *  so that the dialogue shows in all cases. Correct it here if the
4315                      *  frame is shown afterwards.
4316                      */
4317                     if( ! IsChildWindow()
4318                         && ! IsOverrideRedirect()
4319                         && ! IsFloatGrabWindow()
4320                         )
4321                     {
4322                         for( std::list< X11SalFrame* >::const_iterator it = maChildren.begin();
4323                              it != maChildren.end(); ++it )
4324                         {
4325                             if( (*it)->mbTransientForRoot )
4326                                 pDisplay_->getWMAdaptor()->changeReferenceFrame( *it, this );
4327                         }
4328                     }
4329 
4330                     if( hPresentationWindow != None && GetShellWindow() == hPresentationWindow )
4331                         XSetInputFocus( GetXDisplay(), GetShellWindow(), RevertToParent, CurrentTime );
4332                     /*  For unknown reasons Dtwm does respect the input_hint
4333                      *  set to False, but not when mapping the window. So
4334                      *  emulate the correct behaviour and set the focus back
4335                      *  to where it most probably should have been.
4336                      */
4337                     if( (nStyle_ & SAL_FRAME_STYLE_OWNERDRAWDECORATION) &&
4338                         mpParent &&
4339                         GetDisplay()->getWMAdaptor()->getWindowManagerName().EqualsAscii( "Dtwm" )
4340                         )
4341                     {
4342                         XSetInputFocus( GetXDisplay(),
4343                                         mpParent->GetShellWindow(),
4344                                         RevertToParent,
4345                                         CurrentTime );
4346                         bSetFocus = false;
4347                     }
4348 
4349                     if( bSetFocus )
4350                     {
4351                         XSetInputFocus( GetXDisplay(),
4352                                         GetShellWindow(),
4353                                         RevertToParent,
4354                                         CurrentTime );
4355                     }
4356 
4357 
4358                     RestackChildren();
4359                     mbInShow = sal_False;
4360                     m_bSetFocusOnMap = false;
4361 				}
4362 				break;
4363 
4364 			case UnmapNotify:
4365 				if( pEvent->xunmap.window == GetShellWindow() )
4366 				{
4367 					bMapped_   = sal_False;
4368 					bViewable_ = sal_False;
4369 					nRet = sal_True;
4370 					if ( mpInputContext != NULL )
4371 						mpInputContext->Unmap( this );
4372 					CallCallback( SALEVENT_RESIZE, NULL );
4373 				}
4374 				break;
4375 
4376 			case ConfigureNotify:
4377 				if( pEvent->xconfigure.window == GetShellWindow()
4378                     || pEvent->xconfigure.window == GetWindow() )
4379 					nRet = HandleSizeEvent( &pEvent->xconfigure );
4380 				break;
4381 
4382 			case VisibilityNotify:
4383 				nVisibility_ = pEvent->xvisibility.state;
4384 				nRet = sal_True;
4385                 if( bAlwaysOnTop_
4386                     && bMapped_
4387                     && ! GetDisplay()->getWMAdaptor()->isAlwaysOnTopOK()
4388                     && nVisibility_ != VisibilityUnobscured )
4389                     maAlwaysOnTopRaiseTimer.Start();
4390             break;
4391 
4392 			case ReparentNotify:
4393 				nRet = HandleReparentEvent( &pEvent->xreparent );
4394 				break;
4395 
4396 			case MappingNotify:
4397 				if( MappingPointer != pEvent->xmapping.request )
4398 					nRet = CallCallback( SALEVENT_KEYBOARDCHANGED, 0 );
4399 				break;
4400 
4401 			case ColormapNotify:
4402 				nRet = HandleColormapEvent( &pEvent->xcolormap );
4403 				break;
4404 
4405 			case PropertyNotify:
4406 			{
4407 				if( pEvent->xproperty.atom == pDisplay_->getWMAdaptor()->getAtom( WMAdaptor::WM_STATE ) )
4408 					nRet = HandleStateEvent( &pEvent->xproperty );
4409 				else
4410 					nRet = pDisplay_->getWMAdaptor()->handlePropertyNotify( this, &pEvent->xproperty );
4411 				break;
4412 			}
4413 
4414 			case ClientMessage:
4415 				nRet = HandleClientMessage( &pEvent->xclient );
4416 				break;
4417 		}
4418 	}
4419 	else
4420 	{
4421 		switch( pEvent->type )
4422 		{
4423  			case FocusIn:
4424  			case FocusOut:
4425                 if( ( nStyle_ & SAL_FRAME_STYLE_PLUG )
4426                     && ( pEvent->xfocus.window == GetShellWindow()
4427                          || pEvent->xfocus.window == GetForeignParent() )
4428                     )
4429                 {
4430                     nRet = HandleFocusEvent( &pEvent->xfocus );
4431                 }
4432  				break;
4433 
4434 			case ConfigureNotify:
4435 				if( pEvent->xconfigure.window == GetForeignParent() ||
4436 					pEvent->xconfigure.window == GetShellWindow() )
4437 					nRet = HandleSizeEvent( &pEvent->xconfigure );
4438 
4439 				if( pEvent->xconfigure.window == GetStackingWindow() )
4440                     nRet = HandleSizeEvent( &pEvent->xconfigure );
4441 
4442 				RestackChildren();
4443 				break;
4444 		}
4445 	}
4446 
4447 	return nRet;
4448 }
4449 
4450 void X11SalFrame::ResetClipRegion()
4451 {
4452     delete [] m_pClipRectangles;
4453     m_pClipRectangles = NULL;
4454     m_nCurClipRect = m_nMaxClipRect = 0;
4455 
4456 	const int	dest_kind	= ShapeBounding;
4457 	const int	op			= ShapeSet;
4458 	const int	ordering	= YSorted;
4459 
4460 	XWindowAttributes win_attrib;
4461 	XRectangle		  win_size;
4462 
4463 	XLIB_Window aShapeWindow = mhShellWindow;
4464 
4465 	XGetWindowAttributes ( GetDisplay()->GetDisplay(),
4466 						   aShapeWindow,
4467 						   &win_attrib );
4468 
4469 	win_size.x		= 0;
4470 	win_size.y		= 0;
4471 	win_size.width	= win_attrib.width;
4472 	win_size.height = win_attrib.height;
4473 
4474 	XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
4475 							  aShapeWindow,
4476 							  dest_kind,
4477 							  0, 0, 			// x_off, y_off
4478 							  &win_size,		// list of rectangles
4479 							  1,				// number of rectangles
4480 							  op, ordering );
4481 }
4482 
4483 void X11SalFrame::BeginSetClipRegion( sal_uLong nRects )
4484 {
4485     if( m_pClipRectangles )
4486         delete [] m_pClipRectangles;
4487     if( nRects )
4488         m_pClipRectangles = new XRectangle[nRects];
4489     else
4490         m_pClipRectangles = NULL;
4491     m_nMaxClipRect = static_cast<int>(nRects);
4492     m_nCurClipRect = 0;
4493 }
4494 
4495 void X11SalFrame::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
4496 {
4497     if( m_pClipRectangles && m_nCurClipRect < m_nMaxClipRect )
4498     {
4499         m_pClipRectangles[m_nCurClipRect].x      = nX;
4500         m_pClipRectangles[m_nCurClipRect].y      = nY;
4501         m_pClipRectangles[m_nCurClipRect].width  = nWidth;
4502         m_pClipRectangles[m_nCurClipRect].height = nHeight;
4503         m_nCurClipRect++;
4504     }
4505 }
4506 
4507 void X11SalFrame::EndSetClipRegion()
4508 {
4509 	const int	dest_kind	= ShapeBounding;
4510 	const int	ordering	= YSorted;
4511 	const int	op = ShapeSet;
4512 
4513 	XLIB_Window aShapeWindow = mhShellWindow;
4514 	XShapeCombineRectangles ( GetDisplay()->GetDisplay(),
4515 							  aShapeWindow,
4516 							  dest_kind,
4517 							  0, 0, // x_off, y_off
4518 							  m_pClipRectangles,
4519 							  m_nCurClipRect,
4520 							  op, ordering );
4521 
4522 }
4523 
4524