1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #if OSL_DEBUG_LEVEL > 1
25 #include <X11/extensions/shape.h>
27 #include <tools/debug.hxx>
29 #include <vcl/keycodes.hxx>
31 #include <unx/salunx.h>
32 #include <unx/saldata.hxx>
33 #include <unx/salinst.h>
34 #include <unx/saldisp.hxx>
35 #include <unx/salframe.h>
36 #include <unx/salobj.h>
38 #include <salwtype.hxx>
40 // SalInstance member to create and destroy a SalObject
42 SalObject
* X11SalInstance::CreateObject( SalFrame
* pParent
, SystemWindowData
* pWindowData
, bool bShow
)
44 return X11SalObject::CreateObject( pParent
, pWindowData
, bShow
);
47 X11SalObject
* X11SalObject::CreateObject( SalFrame
* pParent
, SystemWindowData
* pWindowData
, bool bShow
)
49 int error_base
, event_base
;
50 X11SalObject
* pObject
= new X11SalObject();
51 SystemEnvData
* pObjData
= const_cast<SystemEnvData
*>(pObject
->GetSystemData());
53 if ( ! XShapeQueryExtension( (Display
*)pObjData
->pDisplay
,
54 &event_base
, &error_base
) )
60 pObject
->mpParent
= pParent
;
62 SalDisplay
* pSalDisp
= GetGenericData()->GetSalDisplay();
63 const SystemEnvData
* pEnv
= pParent
->GetSystemData();
64 Display
* pDisp
= pSalDisp
->GetDisplay();
65 XLIB_Window aObjectParent
= (XLIB_Window
)pEnv
->aWindow
;
67 // find out on which screen that window is
68 XWindowAttributes aParentAttr
;
69 XGetWindowAttributes( pDisp
, aObjectParent
, &aParentAttr
);
70 SalX11Screen
nXScreen( XScreenNumberOfScreen( aParentAttr
.screen
) );
71 Visual
* pVisual
= (pWindowData
&& pWindowData
->pVisual
) ?
72 (Visual
*)pWindowData
->pVisual
:
73 pSalDisp
->GetVisual( nXScreen
).GetVisual();
75 VisualID aVisID
= XVisualIDFromVisual( pVisual
);
76 XVisualInfo aTemplate
;
77 aTemplate
.visualid
= aVisID
;
79 XVisualInfo
* pInfos
= XGetVisualInfo( pDisp
, VisualIDMask
, &aTemplate
, &nVisuals
);
80 // only one VisualInfo structure can match the visual id
81 DBG_ASSERT( nVisuals
== 1, "match count for visual id is not 1" );
82 unsigned int nDepth
= pInfos
->depth
;
84 XSetWindowAttributes aAttribs
;
85 aAttribs
.event_mask
= StructureNotifyMask
96 XCreateSimpleWindow( pDisp
,
100 pSalDisp
->GetColormap( nXScreen
).GetBlackPixel(),
101 pSalDisp
->GetColormap( nXScreen
).GetWhitePixel()
103 if( aVisID
== pSalDisp
->GetVisual( nXScreen
).GetVisualId() )
105 pObject
->maSecondary
=
106 XCreateSimpleWindow( pDisp
,
110 pSalDisp
->GetColormap( nXScreen
).GetBlackPixel(),
111 pSalDisp
->GetColormap( nXScreen
).GetWhitePixel()
116 #if OSL_DEBUG_LEVEL > 1
117 fprintf( stderr
, "visual id of vcl %x, of visual %x\n",
118 static_cast<unsigned int> (pSalDisp
->GetVisual( nXScreen
).GetVisualId()),
119 static_cast<unsigned int> (aVisID
) );
121 GetGenericData()->ErrorTrapPush();
123 // create colormap for visual - there might not be one
124 pObject
->maColormap
= aAttribs
.colormap
= XCreateColormap(
126 pSalDisp
->GetRootWindow( nXScreen
),
130 pObject
->maSecondary
=
131 XCreateWindow( pDisp
,
132 pSalDisp
->GetRootWindow( nXScreen
),
137 CWEventMask
|CWColormap
, &aAttribs
);
138 XSync( pDisp
, False
);
139 if( GetGenericData()->ErrorTrapPop( false ) )
141 pObject
->maSecondary
= None
;
145 XReparentWindow( pDisp
, pObject
->maSecondary
, pObject
->maPrimary
, 0, 0 );
148 GetGenericData()->ErrorTrapPush();
150 XMapWindow( pDisp
, pObject
->maSecondary
);
151 XMapWindow( pDisp
, pObject
->maPrimary
);
154 pObjData
->pDisplay
= pDisp
;
155 pObjData
->aWindow
= pObject
->maSecondary
;
156 pObjData
->pWidget
= NULL
;
157 pObjData
->pVisual
= pVisual
;
158 pObjData
->nDepth
= nDepth
;
159 pObjData
->aColormap
= aVisID
== pSalDisp
->GetVisual( nXScreen
).GetVisualId() ?
160 pSalDisp
->GetColormap( nXScreen
).GetXColormap() : None
;
161 pObjData
->pAppContext
= NULL
;
164 if( GetGenericData()->ErrorTrapPop( false ) )
173 void X11SalInstance::DestroyObject( SalObject
* pObject
)
178 // SalClipRegion is a member of SalObject
179 // definition of SalClipRegion my be found in unx/inc/salobj.h
181 SalClipRegion::SalClipRegion()
183 ClipRectangleList
= NULL
;
184 numClipRectangles
= 0;
185 maxClipRectangles
= 0;
186 nClipRegionType
= SAL_OBJECT_CLIP_INCLUDERECTS
;
189 SalClipRegion::~SalClipRegion()
191 if ( ClipRectangleList
)
192 delete [] ClipRectangleList
;
196 SalClipRegion::BeginSetClipRegion( sal_uLong nRects
)
198 if (ClipRectangleList
)
199 delete [] ClipRectangleList
;
201 ClipRectangleList
= new XRectangle
[nRects
];
202 numClipRectangles
= 0;
203 maxClipRectangles
= nRects
;
207 SalClipRegion::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
209 if ( nWidth
&& nHeight
&& (numClipRectangles
< maxClipRectangles
) )
211 XRectangle
*aRect
= ClipRectangleList
+ numClipRectangles
;
213 aRect
->x
= (short) nX
;
214 aRect
->y
= (short) nY
;
215 aRect
->width
= (unsigned short) nWidth
;
216 aRect
->height
= (unsigned short) nHeight
;
222 // SalObject Implementation
223 X11SalObject::X11SalObject()
230 maSystemChildData
.nSize
= sizeof( SystemEnvData
);
231 maSystemChildData
.pDisplay
= GetGenericData()->GetSalDisplay()->GetDisplay();
232 maSystemChildData
.aWindow
= None
;
233 maSystemChildData
.pSalFrame
= 0;
234 maSystemChildData
.pWidget
= 0;
235 maSystemChildData
.pVisual
= 0;
236 maSystemChildData
.nDepth
= 0;
237 maSystemChildData
.aColormap
= 0;
238 maSystemChildData
.pAppContext
= NULL
;
239 maSystemChildData
.aShellWindow
= 0;
240 maSystemChildData
.pShellWidget
= NULL
;
242 std::list
< SalObject
* >& rObjects
= GetGenericData()->GetSalDisplay()->getSalObjects();
243 rObjects
.push_back( this );
246 X11SalObject::~X11SalObject()
248 std::list
< SalObject
* >& rObjects
= GetGenericData()->GetSalDisplay()->getSalObjects();
249 rObjects
.remove( this );
251 GetGenericData()->ErrorTrapPush();
253 XDestroyWindow( (Display
*)maSystemChildData
.pDisplay
, maSecondary
);
255 XDestroyWindow( (Display
*)maSystemChildData
.pDisplay
, maPrimary
);
257 XFreeColormap((Display
*)maSystemChildData
.pDisplay
, maColormap
);
258 XSync( (Display
*)maSystemChildData
.pDisplay
, False
);
259 GetGenericData()->ErrorTrapPop();
263 X11SalObject::ResetClipRegion()
265 maClipRegion
.ResetClipRegion();
267 const int dest_kind
= ShapeBounding
;
268 const int op
= ShapeSet
;
269 const int ordering
= YSorted
;
271 XWindowAttributes win_attrib
;
274 XLIB_Window aShapeWindow
= maPrimary
;
276 XGetWindowAttributes ( (Display
*)maSystemChildData
.pDisplay
,
282 win_size
.width
= win_attrib
.width
;
283 win_size
.height
= win_attrib
.height
;
285 XShapeCombineRectangles ( (Display
*)maSystemChildData
.pDisplay
,
288 0, 0, // x_off, y_off
289 &win_size
, // list of rectangles
290 1, // number of rectangles
295 X11SalObject::BeginSetClipRegion( sal_uLong nRectCount
)
297 maClipRegion
.BeginSetClipRegion ( nRectCount
);
301 X11SalObject::UnionClipRegion( long nX
, long nY
, long nWidth
, long nHeight
)
303 maClipRegion
.UnionClipRegion ( nX
, nY
, nWidth
, nHeight
);
307 X11SalObject::EndSetClipRegion()
309 XRectangle
*pRectangles
= maClipRegion
.EndSetClipRegion ();
310 const int nType
= maClipRegion
.GetClipRegionType();
311 const int nRectangles
= maClipRegion
.GetRectangleCount();
313 const int dest_kind
= ShapeBounding
;
314 const int ordering
= YSorted
;
319 case SAL_OBJECT_CLIP_INCLUDERECTS
:
322 case SAL_OBJECT_CLIP_EXCLUDERECTS
:
325 case SAL_OBJECT_CLIP_ABSOLUTE
:
332 XLIB_Window aShapeWindow
= maPrimary
;
334 XShapeCombineRectangles ( (Display
*)maSystemChildData
.pDisplay
,
337 0, 0, // x_off, y_off
344 X11SalObject::GetClipRegionType()
346 return maClipRegion
.GetClipRegionType();
350 X11SalObject::SetPosSize( long nX
, long nY
, long nWidth
, long nHeight
)
352 if ( maPrimary
&& maSecondary
&& nWidth
&& nHeight
)
354 XMoveResizeWindow( (Display
*)maSystemChildData
.pDisplay
,
356 nX
, nY
, nWidth
, nHeight
);
357 XMoveResizeWindow( (Display
*)maSystemChildData
.pDisplay
,
359 0, 0, nWidth
, nHeight
);
364 X11SalObject::Show( bool bVisible
)
366 if ( ! maSystemChildData
.aWindow
)
370 XMapWindow( (Display
*)maSystemChildData
.pDisplay
,
372 XMapWindow( (Display
*)maSystemChildData
.pDisplay
,
375 XUnmapWindow( (Display
*)maSystemChildData
.pDisplay
,
377 XUnmapWindow( (Display
*)maSystemChildData
.pDisplay
,
380 mbVisible
= bVisible
;
383 void X11SalObject::GrabFocus()
386 XSetInputFocus( (Display
*)maSystemChildData
.pDisplay
,
387 maSystemChildData
.aWindow
,
392 const SystemEnvData
* X11SalObject::GetSystemData() const
394 return &maSystemChildData
;
397 static sal_uInt16
sal_GetCode( int state
)
399 sal_uInt16 nCode
= 0;
401 if( state
& Button1Mask
)
403 if( state
& Button2Mask
)
404 nCode
|= MOUSE_MIDDLE
;
405 if( state
& Button3Mask
)
406 nCode
|= MOUSE_RIGHT
;
408 if( state
& ShiftMask
)
410 if( state
& ControlMask
)
412 if( state
& Mod1Mask
)
414 if( state
& Mod3Mask
)
420 bool X11SalObject::Dispatch( XEvent
* pEvent
)
422 std::list
< SalObject
* >& rObjects
= GetGenericData()->GetSalDisplay()->getSalObjects();
424 for( std::list
< SalObject
* >::iterator it
= rObjects
.begin(); it
!= rObjects
.end(); ++it
)
426 X11SalObject
* pObject
= static_cast<X11SalObject
*>(*it
);
427 if( pEvent
->xany
.window
== pObject
->maPrimary
||
428 pEvent
->xany
.window
== pObject
->maSecondary
)
430 if( pObject
->IsMouseTransparent() && (
431 pEvent
->type
== ButtonPress
||
432 pEvent
->type
== ButtonRelease
||
433 pEvent
->type
== EnterNotify
||
434 pEvent
->type
== LeaveNotify
||
435 pEvent
->type
== MotionNotify
440 const SystemEnvData
* pParentData
= pObject
->mpParent
->GetSystemData();
442 XLIB_Window aChild
= None
;
443 XTranslateCoordinates( pEvent
->xbutton
.display
,
444 pEvent
->xbutton
.root
,
445 pParentData
->aWindow
,
446 pEvent
->xbutton
.x_root
,
447 pEvent
->xbutton
.y_root
,
452 aEvt
.mnTime
= pEvent
->xbutton
.time
;
453 aEvt
.mnCode
= sal_GetCode( pEvent
->xbutton
.state
);
455 sal_uInt16 nEvent
= 0;
456 if( pEvent
->type
== ButtonPress
||
457 pEvent
->type
== ButtonRelease
)
459 switch( pEvent
->xbutton
.button
)
461 case Button1
: aEvt
.mnButton
= MOUSE_LEFT
;break;
462 case Button2
: aEvt
.mnButton
= MOUSE_MIDDLE
;break;
463 case Button3
: aEvt
.mnButton
= MOUSE_RIGHT
;break;
465 nEvent
= (pEvent
->type
== ButtonPress
) ?
466 SALEVENT_MOUSEBUTTONDOWN
:
467 SALEVENT_MOUSEBUTTONUP
;
469 else if( pEvent
->type
== EnterNotify
)
470 nEvent
= SALEVENT_MOUSELEAVE
;
472 nEvent
= SALEVENT_MOUSEMOVE
;
473 pObject
->mpParent
->CallCallback( nEvent
, &aEvt
);
477 switch( pEvent
->type
)
480 pObject
->mbVisible
= false;
483 pObject
->mbVisible
= true;
486 pObject
->CallCallback( SALOBJ_EVENT_TOTOP
, NULL
);
489 pObject
->CallCallback( SALOBJ_EVENT_GETFOCUS
, NULL
);
492 pObject
->CallCallback( SALOBJ_EVENT_LOSEFOCUS
, NULL
);
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */