Update ooo320-m1
[ooovba.git] / vcl / unx / source / window / salobj.cxx
blob6f7ce680813a10f6b68b12c974c294c65834ebed
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salobj.cxx,v $
10 * $Revision: 1.24 $
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>
35 #include <X11/Xlib.h>
36 #include <X11/extensions/shape.h>
37 #include <tools/postx.h>
39 #include <salunx.h>
40 #include <salstd.hxx>
41 #include <saldata.hxx>
42 #ifndef _SV_SALINST_HXX
43 #include <salinst.h>
44 #endif
45 #include <saldisp.hxx>
46 #ifndef _SV_SALFRAME_HXX
47 #include <salframe.h>
48 #endif
49 #include <salobj.h>
50 #include <vcl/salwtype.hxx>
51 #include <vcl/keycodes.hxx>
53 #include <tools/debug.hxx>
54 #if OSL_DEBUG_LEVEL > 1
55 #include <stdio.h>
56 #endif
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 ) )
75 delete pObject;
76 return NULL;
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();
93 // get visual info
94 VisualID aVisID = XVisualIDFromVisual( pVisual );
95 XVisualInfo aTemplate;
96 aTemplate.visualid = aVisID;
97 int nVisuals = 0;
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;
102 XFree( pInfos );
103 XSetWindowAttributes aAttribs;
104 aAttribs.event_mask = StructureNotifyMask
105 | ButtonPressMask
106 | ButtonReleaseMask
107 | PointerMotionMask
108 | EnterWindowMask
109 | LeaveWindowMask
110 | FocusChangeMask
111 | ExposureMask
114 pObject->maPrimary =
115 XCreateSimpleWindow( pDisp,
116 aObjectParent,
117 0, 0,
118 1, 1, 0,
119 pSalDisp->GetColormap( nScreen ).GetBlackPixel(),
120 pSalDisp->GetColormap( nScreen ).GetWhitePixel()
122 if( aVisID == pSalDisp->GetVisual( nScreen ).GetVisualId() )
124 pObject->maSecondary =
125 XCreateSimpleWindow( pDisp,
126 pObject->maPrimary,
127 0, 0,
128 1, 1, 0,
129 pSalDisp->GetColormap( nScreen ).GetBlackPixel(),
130 pSalDisp->GetColormap( nScreen ).GetWhitePixel()
133 else
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) );
139 #endif
140 pSalDisp->GetXLib()->PushXErrorLevel( true );
142 // create colormap for visual - there might not be one
143 pObject->maColormap = aAttribs.colormap = XCreateColormap(
144 pDisp,
145 pSalDisp->GetRootWindow( nScreen ),
146 pVisual,
147 AllocNone );
149 pObject->maSecondary =
150 XCreateWindow( pDisp,
151 pSalDisp->GetRootWindow( nScreen ),
152 0, 0,
153 1, 1, 0,
154 nDepth, InputOutput,
155 pVisual,
156 CWEventMask|CWColormap, &aAttribs );
157 XSync( pDisp, False );
158 BOOL bWasXError = pSalDisp->GetXLib()->HasXErrorOccured();
159 pSalDisp->GetXLib()->PopXErrorLevel();
160 if( bWasXError )
162 pObject->maSecondary = None;
163 delete pObject;
164 return NULL;
166 XReparentWindow( pDisp, pObject->maSecondary, pObject->maPrimary, 0, 0 );
169 pSalDisp->GetXLib()->PushXErrorLevel( true );
170 if( bShow ) {
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;
184 XSync(pDisp, False);
185 BOOL bWasXError = pSalDisp->GetXLib()->HasXErrorOccured();
186 pSalDisp->GetXLib()->PopXErrorLevel();
187 if( bWasXError )
189 delete pObject;
190 return NULL;
193 return pObject;
197 void X11SalInstance::DestroyObject( SalObject* pObject )
199 delete 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;
224 void
225 SalClipRegion::BeginSetClipRegion( ULONG nRects )
227 if (ClipRectangleList)
228 delete [] ClipRectangleList;
230 ClipRectangleList = new XRectangle[nRects];
231 numClipRectangles = 0;
232 maxClipRectangles = nRects;
236 void
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;
248 numClipRectangles++;
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;
270 maPrimary = 0;
271 maSecondary = 0;
272 maColormap = 0;
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 );
285 if ( maSecondary )
286 XDestroyWindow( (Display*)maSystemChildData.pDisplay, maSecondary );
287 if ( maPrimary )
288 XDestroyWindow( (Display*)maSystemChildData.pDisplay, maPrimary );
289 if ( maColormap )
290 XFreeColormap((Display*)maSystemChildData.pDisplay, maColormap);
291 XSync( (Display*)maSystemChildData.pDisplay, False );
292 pSalDisp->GetXLib()->PopXErrorLevel();
296 void
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;
306 XRectangle win_size;
308 XLIB_Window aShapeWindow = maPrimary;
310 XGetWindowAttributes ( (Display*)maSystemChildData.pDisplay,
311 aShapeWindow,
312 &win_attrib );
314 win_size.x = 0;
315 win_size.y = 0;
316 win_size.width = win_attrib.width;
317 win_size.height = win_attrib.height;
319 XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
320 aShapeWindow,
321 dest_kind,
322 0, 0, // x_off, y_off
323 &win_size, // list of rectangles
324 1, // number of rectangles
325 op, ordering );
329 void
330 X11SalObject::BeginSetClipRegion( ULONG nRectCount )
332 maClipRegion.BeginSetClipRegion ( nRectCount );
336 void
337 X11SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
339 maClipRegion.UnionClipRegion ( nX, nY, nWidth, nHeight );
343 void
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;
352 int op;
354 switch ( nType )
356 case SAL_OBJECT_CLIP_INCLUDERECTS :
357 op = ShapeSet;
358 break;
359 case SAL_OBJECT_CLIP_EXCLUDERECTS :
360 op = ShapeSubtract;
361 break;
362 case SAL_OBJECT_CLIP_ABSOLUTE :
363 op = ShapeSet;
364 break;
365 default :
366 op = ShapeUnion;
369 XLIB_Window aShapeWindow = maPrimary;
371 XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
372 aShapeWindow,
373 dest_kind,
374 0, 0, // x_off, y_off
375 pRectangles,
376 nRectangles,
377 op, ordering );
381 USHORT
382 X11SalObject::GetClipRegionType()
384 return maClipRegion.GetClipRegionType();
387 // -----------------------------------------------------------------------
389 void
390 X11SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
392 if ( maPrimary && maSecondary && nWidth && nHeight )
394 XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
395 maPrimary,
396 nX, nY, nWidth, nHeight );
397 XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
398 maSecondary,
399 0, 0, nWidth, nHeight );
404 void
405 X11SalObject::Show( BOOL bVisible )
407 if ( ! maSystemChildData.aWindow )
408 return;
410 if ( bVisible ) {
411 XMapWindow( (Display*)maSystemChildData.pDisplay,
412 maSecondary );
413 XMapWindow( (Display*)maSystemChildData.pDisplay,
414 maPrimary );
415 } else {
416 XUnmapWindow( (Display*)maSystemChildData.pDisplay,
417 maPrimary );
418 XUnmapWindow( (Display*)maSystemChildData.pDisplay,
419 maSecondary );
421 mbVisible = bVisible;
424 // -----------------------------------------------------------------------
426 void X11SalObject::Enable( BOOL )
430 // -----------------------------------------------------------------------
432 void X11SalObject::GrabFocus()
434 if( mbVisible )
435 XSetInputFocus( (Display*)maSystemChildData.pDisplay,
436 maSystemChildData.aWindow,
437 RevertToNone,
438 CurrentTime );
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 )
462 USHORT nCode = 0;
464 if( state & Button1Mask )
465 nCode |= MOUSE_LEFT;
466 if( state & Button2Mask )
467 nCode |= MOUSE_MIDDLE;
468 if( state & Button3Mask )
469 nCode |= MOUSE_RIGHT;
471 if( state & ShiftMask )
472 nCode |= KEY_SHIFT;
473 if( state & ControlMask )
474 nCode |= KEY_MOD1;
475 if( state & Mod1Mask )
476 nCode |= KEY_MOD2;
477 if( state & Mod3Mask )
478 nCode |= KEY_MOD3;
480 return nCode;
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
502 SalMouseEvent aEvt;
503 const SystemEnvData* pParentData = pObject->mpParent->GetSystemData();
504 int dest_x, dest_y;
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,
511 &dest_x, &dest_y,
512 &aChild );
513 aEvt.mnX = dest_x;
514 aEvt.mnY = dest_y;
515 aEvt.mnTime = pEvent->xbutton.time;
516 aEvt.mnCode = sal_GetCode( pEvent->xbutton.state );
517 aEvt.mnButton = 0;
518 USHORT nEvent = 0;
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;
534 else
535 nEvent = SALEVENT_MOUSEMOVE;
536 pObject->mpParent->CallCallback( nEvent, &aEvt );
538 else
540 switch( pEvent->type )
542 case UnmapNotify:
543 pObject->mbVisible = FALSE;
544 return 1;
545 case MapNotify:
546 pObject->mbVisible = TRUE;
547 return 1;
548 case ButtonPress:
549 pObject->CallCallback( SALOBJ_EVENT_TOTOP, NULL );
550 return 1;
551 case FocusIn:
552 pObject->CallCallback( SALOBJ_EVENT_GETFOCUS, NULL );
553 return 1;
554 case FocusOut:
555 pObject->CallCallback( SALOBJ_EVENT_LOSEFOCUS, NULL );
556 return 1;
557 default: break;
560 return 0;
563 return 0;