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