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