xref: /AOO41X/main/vcl/unx/generic/window/salframe.cxx (revision c82f28778d59b20a7e6c0f9982d1bc73807a432a)
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 doesnt 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 doesnt 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