1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salobj.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <tools/prex.h>
36 #include <X11/extensions/shape.h>
37 #include <tools/postx.h>
41 #include <saldata.hxx>
42 #ifndef _SV_SALINST_HXX
45 #include <saldisp.hxx>
46 #ifndef _SV_SALFRAME_HXX
50 #include <vcl/salwtype.hxx>
51 #include <vcl/keycodes.hxx>
53 #include <tools/debug.hxx>
54 #if OSL_DEBUG_LEVEL > 1
58 // =======================================================================
59 // SalInstance member to create and destroy a SalObject
61 SalObject
* X11SalInstance::CreateObject( SalFrame
* pParent
, SystemWindowData
* pWindowData
, BOOL bShow
)
63 return X11SalObject::CreateObject( pParent
, pWindowData
, bShow
);
66 X11SalObject
* X11SalObject::CreateObject( SalFrame
* pParent
, SystemWindowData
* pWindowData
, BOOL bShow
)
68 int error_base
, event_base
;
69 X11SalObject
* pObject
= new X11SalObject();
70 SystemChildData
* pObjData
= const_cast<SystemChildData
*>(pObject
->GetSystemData());
72 if ( ! XShapeQueryExtension( (Display
*)pObjData
->pDisplay
,
73 &event_base
, &error_base
) )
79 pObject
->mpParent
= pParent
;
81 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
82 const SystemEnvData
* pEnv
= pParent
->GetSystemData();
83 Display
* pDisp
= pSalDisp
->GetDisplay();
84 XLIB_Window aObjectParent
= (XLIB_Window
)pEnv
->aWindow
;
86 // find out on which screen that window is
87 XWindowAttributes aParentAttr
;
88 XGetWindowAttributes( pDisp
, aObjectParent
, &aParentAttr
);
89 int nScreen
= XScreenNumberOfScreen( aParentAttr
.screen
);
90 Visual
* pVisual
= (pWindowData
&& pWindowData
->pVisual
) ?
91 (Visual
*)pWindowData
->pVisual
:
92 pSalDisp
->GetVisual( nScreen
).GetVisual();
94 VisualID aVisID
= XVisualIDFromVisual( pVisual
);
95 XVisualInfo aTemplate
;
96 aTemplate
.visualid
= aVisID
;
98 XVisualInfo
* pInfos
= XGetVisualInfo( pDisp
, VisualIDMask
, &aTemplate
, &nVisuals
);
99 // only one VisualInfo structure can match the visual id
100 DBG_ASSERT( nVisuals
== 1, "match count for visual id is not 1" );
101 unsigned int nDepth
= pInfos
->depth
;
103 XSetWindowAttributes aAttribs
;
104 aAttribs
.event_mask
= StructureNotifyMask
115 XCreateSimpleWindow( pDisp
,
119 pSalDisp
->GetColormap( nScreen
).GetBlackPixel(),
120 pSalDisp
->GetColormap( nScreen
).GetWhitePixel()
122 if( aVisID
== pSalDisp
->GetVisual( nScreen
).GetVisualId() )
124 pObject
->maSecondary
=
125 XCreateSimpleWindow( pDisp
,
129 pSalDisp
->GetColormap( nScreen
).GetBlackPixel(),
130 pSalDisp
->GetColormap( nScreen
).GetWhitePixel()
135 #if OSL_DEBUG_LEVEL > 1
136 fprintf( stderr
, "visual id of vcl %x, of visual %x\n",
137 static_cast<unsigned int> (pSalDisp
->GetVisual( nScreen
).GetVisualId()),
138 static_cast<unsigned int> (aVisID
) );
140 pSalDisp
->GetXLib()->PushXErrorLevel( true );
142 // create colormap for visual - there might not be one
143 pObject
->maColormap
= aAttribs
.colormap
= XCreateColormap(
145 pSalDisp
->GetRootWindow( nScreen
),
149 pObject
->maSecondary
=
150 XCreateWindow( pDisp
,
151 pSalDisp
->GetRootWindow( nScreen
),
156 CWEventMask
|CWColormap
, &aAttribs
);
157 XSync( pDisp
, False
);
158 BOOL bWasXError
= pSalDisp
->GetXLib()->HasXErrorOccured();
159 pSalDisp
->GetXLib()->PopXErrorLevel();
162 pObject
->maSecondary
= None
;
166 XReparentWindow( pDisp
, pObject
->maSecondary
, pObject
->maPrimary
, 0, 0 );
169 pSalDisp
->GetXLib()->PushXErrorLevel( true );
171 XMapWindow( pDisp
, pObject
->maSecondary
);
172 XMapWindow( pDisp
, pObject
->maPrimary
);
175 pObjData
->pDisplay
= pDisp
;
176 pObjData
->aWindow
= pObject
->maSecondary
;
177 pObjData
->pWidget
= NULL
;
178 pObjData
->pVisual
= pVisual
;
179 pObjData
->nDepth
= nDepth
;
180 pObjData
->aColormap
= aVisID
== pSalDisp
->GetVisual( nScreen
).GetVisualId() ?
181 pSalDisp
->GetColormap( nScreen
).GetXColormap() : None
;
182 pObjData
->pAppContext
= NULL
;
185 BOOL bWasXError
= pSalDisp
->GetXLib()->HasXErrorOccured();
186 pSalDisp
->GetXLib()->PopXErrorLevel();
197 void X11SalInstance::DestroyObject( SalObject
* pObject
)
203 // ======================================================================
204 // SalClipRegion is a member of SalObject
205 // definition of SalClipRegion my be found in unx/inc/salobj.h
208 SalClipRegion::SalClipRegion()
210 ClipRectangleList
= NULL
;
211 numClipRectangles
= 0;
212 maxClipRectangles
= 0;
213 nClipRegionType
= SAL_OBJECT_CLIP_INCLUDERECTS
;
217 SalClipRegion::~SalClipRegion()
219 if ( ClipRectangleList
)
220 delete [] ClipRectangleList
;
225 SalClipRegion::BeginSetClipRegion( ULONG nRects
)
227 if (ClipRectangleList
)
228 delete [] ClipRectangleList
;
230 ClipRectangleList
= new XRectangle
[nRects
];
231 numClipRectangles
= 0;
232 maxClipRectangles
= nRects
;
237 SalClipRegion::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
239 if ( nWidth
&& nHeight
&& (numClipRectangles
< maxClipRectangles
) )
241 XRectangle
*aRect
= ClipRectangleList
+ numClipRectangles
;
243 aRect
->x
= (short) nX
;
244 aRect
->y
= (short) nY
;
245 aRect
->width
= (unsigned short) nWidth
;
246 aRect
->height
= (unsigned short) nHeight
;
253 // =======================================================================
254 // SalObject Implementation
257 X11SalObject::X11SalObject()
259 maSystemChildData
.nSize
= sizeof( SystemChildData
);
260 maSystemChildData
.pDisplay
= GetX11SalData()->GetDisplay()->GetDisplay();
261 maSystemChildData
.aWindow
= None
;
262 maSystemChildData
.pSalFrame
= 0;
263 maSystemChildData
.pWidget
= 0;
264 maSystemChildData
.pVisual
= 0;
265 maSystemChildData
.nDepth
= 0;
266 maSystemChildData
.aColormap
= 0;
267 maSystemChildData
.pAppContext
= NULL
;
268 maSystemChildData
.aShellWindow
= 0;
269 maSystemChildData
.pShellWidget
= NULL
;
274 std::list
< SalObject
* >& rObjects
= GetX11SalData()->GetDisplay()->getSalObjects();
275 rObjects
.push_back( this );
279 X11SalObject::~X11SalObject()
281 std::list
< SalObject
* >& rObjects
= GetX11SalData()->GetDisplay()->getSalObjects();
282 rObjects
.remove( this );
283 SalDisplay
* pSalDisp
= GetX11SalData()->GetDisplay();
284 pSalDisp
->GetXLib()->PushXErrorLevel( true );
286 XDestroyWindow( (Display
*)maSystemChildData
.pDisplay
, maSecondary
);
288 XDestroyWindow( (Display
*)maSystemChildData
.pDisplay
, maPrimary
);
290 XFreeColormap((Display
*)maSystemChildData
.pDisplay
, maColormap
);
291 XSync( (Display
*)maSystemChildData
.pDisplay
, False
);
292 pSalDisp
->GetXLib()->PopXErrorLevel();
297 X11SalObject::ResetClipRegion()
299 maClipRegion
.ResetClipRegion();
301 const int dest_kind
= ShapeBounding
;
302 const int op
= ShapeSet
;
303 const int ordering
= YSorted
;
305 XWindowAttributes win_attrib
;
308 XLIB_Window aShapeWindow
= maPrimary
;
310 XGetWindowAttributes ( (Display
*)maSystemChildData
.pDisplay
,
316 win_size
.width
= win_attrib
.width
;
317 win_size
.height
= win_attrib
.height
;
319 XShapeCombineRectangles ( (Display
*)maSystemChildData
.pDisplay
,
322 0, 0, // x_off, y_off
323 &win_size
, // list of rectangles
324 1, // number of rectangles
330 X11SalObject::BeginSetClipRegion( ULONG nRectCount
)
332 maClipRegion
.BeginSetClipRegion ( nRectCount
);
337 X11SalObject::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
339 maClipRegion
.UnionClipRegion ( nX
, nY
, nWidth
, nHeight
);
344 X11SalObject::EndSetClipRegion()
346 XRectangle
*pRectangles
= maClipRegion
.EndSetClipRegion ();
347 const int nType
= maClipRegion
.GetClipRegionType();
348 const int nRectangles
= maClipRegion
.GetRectangleCount();
350 const int dest_kind
= ShapeBounding
;
351 const int ordering
= YSorted
;
356 case SAL_OBJECT_CLIP_INCLUDERECTS
:
359 case SAL_OBJECT_CLIP_EXCLUDERECTS
:
362 case SAL_OBJECT_CLIP_ABSOLUTE
:
369 XLIB_Window aShapeWindow
= maPrimary
;
371 XShapeCombineRectangles ( (Display
*)maSystemChildData
.pDisplay
,
374 0, 0, // x_off, y_off
382 X11SalObject::GetClipRegionType()
384 return maClipRegion
.GetClipRegionType();
387 // -----------------------------------------------------------------------
390 X11SalObject::SetPosSize( long nX
, long nY
, long nWidth
, long nHeight
)
392 if ( maPrimary
&& maSecondary
&& nWidth
&& nHeight
)
394 XMoveResizeWindow( (Display
*)maSystemChildData
.pDisplay
,
396 nX
, nY
, nWidth
, nHeight
);
397 XMoveResizeWindow( (Display
*)maSystemChildData
.pDisplay
,
399 0, 0, nWidth
, nHeight
);
405 X11SalObject::Show( BOOL bVisible
)
407 if ( ! maSystemChildData
.aWindow
)
411 XMapWindow( (Display
*)maSystemChildData
.pDisplay
,
413 XMapWindow( (Display
*)maSystemChildData
.pDisplay
,
416 XUnmapWindow( (Display
*)maSystemChildData
.pDisplay
,
418 XUnmapWindow( (Display
*)maSystemChildData
.pDisplay
,
421 mbVisible
= bVisible
;
424 // -----------------------------------------------------------------------
426 void X11SalObject::Enable( BOOL
)
430 // -----------------------------------------------------------------------
432 void X11SalObject::GrabFocus()
435 XSetInputFocus( (Display
*)maSystemChildData
.pDisplay
,
436 maSystemChildData
.aWindow
,
441 // -----------------------------------------------------------------------
443 void X11SalObject::SetBackground()
447 // -----------------------------------------------------------------------
449 void X11SalObject::SetBackground( SalColor
)
453 // -----------------------------------------------------------------------
455 const SystemChildData
* X11SalObject::GetSystemData() const
457 return &maSystemChildData
;
460 static USHORT
sal_GetCode( int state
)
464 if( state
& Button1Mask
)
466 if( state
& Button2Mask
)
467 nCode
|= MOUSE_MIDDLE
;
468 if( state
& Button3Mask
)
469 nCode
|= MOUSE_RIGHT
;
471 if( state
& ShiftMask
)
473 if( state
& ControlMask
)
475 if( state
& Mod1Mask
)
477 if( state
& Mod3Mask
)
483 long X11SalObject::Dispatch( XEvent
* pEvent
)
485 std::list
< SalObject
* >& rObjects
= GetX11SalData()->GetDisplay()->getSalObjects();
487 for( std::list
< SalObject
* >::iterator it
= rObjects
.begin(); it
!= rObjects
.end(); ++it
)
489 X11SalObject
* pObject
= static_cast<X11SalObject
*>(*it
);
490 if( pEvent
->xany
.window
== pObject
->maPrimary
||
491 pEvent
->xany
.window
== pObject
->maSecondary
)
493 if( pObject
->IsMouseTransparent() && (
494 pEvent
->type
== ButtonPress
||
495 pEvent
->type
== ButtonRelease
||
496 pEvent
->type
== EnterNotify
||
497 pEvent
->type
== LeaveNotify
||
498 pEvent
->type
== MotionNotify
503 const SystemEnvData
* pParentData
= pObject
->mpParent
->GetSystemData();
505 XLIB_Window aChild
= None
;
506 XTranslateCoordinates( pEvent
->xbutton
.display
,
507 pEvent
->xbutton
.root
,
508 pParentData
->aWindow
,
509 pEvent
->xbutton
.x_root
,
510 pEvent
->xbutton
.y_root
,
515 aEvt
.mnTime
= pEvent
->xbutton
.time
;
516 aEvt
.mnCode
= sal_GetCode( pEvent
->xbutton
.state
);
519 if( pEvent
->type
== ButtonPress
||
520 pEvent
->type
== ButtonRelease
)
522 switch( pEvent
->xbutton
.button
)
524 case Button1
: aEvt
.mnButton
= MOUSE_LEFT
;break;
525 case Button2
: aEvt
.mnButton
= MOUSE_MIDDLE
;break;
526 case Button3
: aEvt
.mnButton
= MOUSE_RIGHT
;break;
528 nEvent
= (pEvent
->type
== ButtonPress
) ?
529 SALEVENT_MOUSEBUTTONDOWN
:
530 SALEVENT_MOUSEBUTTONUP
;
532 else if( pEvent
->type
== EnterNotify
)
533 nEvent
= SALEVENT_MOUSELEAVE
;
535 nEvent
= SALEVENT_MOUSEMOVE
;
536 pObject
->mpParent
->CallCallback( nEvent
, &aEvt
);
540 switch( pEvent
->type
)
543 pObject
->mbVisible
= FALSE
;
546 pObject
->mbVisible
= TRUE
;
549 pObject
->CallCallback( SALOBJ_EVENT_TOTOP
, NULL
);
552 pObject
->CallCallback( SALOBJ_EVENT_GETFOCUS
, NULL
);
555 pObject
->CallCallback( SALOBJ_EVENT_LOSEFOCUS
, NULL
);