Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / vcl / unx / generic / window / salobj.cxx
blob7a61bd1c92bdd73fe0ec677f4fb6969c77ed3c0c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
21 #include <stdio.h>
22 #endif
24 #include <prex.h>
25 #include <X11/extensions/shape.h>
26 #include <postx.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 ) )
56 delete pObject;
57 return NULL;
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();
74 // get visual info
75 VisualID aVisID = XVisualIDFromVisual( pVisual );
76 XVisualInfo aTemplate;
77 aTemplate.visualid = aVisID;
78 int nVisuals = 0;
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;
83 XFree( pInfos );
84 XSetWindowAttributes aAttribs;
85 aAttribs.event_mask = StructureNotifyMask
86 | ButtonPressMask
87 | ButtonReleaseMask
88 | PointerMotionMask
89 | EnterWindowMask
90 | LeaveWindowMask
91 | FocusChangeMask
92 | ExposureMask
95 pObject->maPrimary =
96 XCreateSimpleWindow( pDisp,
97 aObjectParent,
98 0, 0,
99 1, 1, 0,
100 pSalDisp->GetColormap( nXScreen ).GetBlackPixel(),
101 pSalDisp->GetColormap( nXScreen ).GetWhitePixel()
103 if( aVisID == pSalDisp->GetVisual( nXScreen ).GetVisualId() )
105 pObject->maSecondary =
106 XCreateSimpleWindow( pDisp,
107 pObject->maPrimary,
108 0, 0,
109 1, 1, 0,
110 pSalDisp->GetColormap( nXScreen ).GetBlackPixel(),
111 pSalDisp->GetColormap( nXScreen ).GetWhitePixel()
114 else
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) );
120 #endif
121 GetGenericData()->ErrorTrapPush();
123 // create colormap for visual - there might not be one
124 pObject->maColormap = aAttribs.colormap = XCreateColormap(
125 pDisp,
126 pSalDisp->GetRootWindow( nXScreen ),
127 pVisual,
128 AllocNone );
130 pObject->maSecondary =
131 XCreateWindow( pDisp,
132 pSalDisp->GetRootWindow( nXScreen ),
133 0, 0,
134 1, 1, 0,
135 nDepth, InputOutput,
136 pVisual,
137 CWEventMask|CWColormap, &aAttribs );
138 XSync( pDisp, False );
139 if( GetGenericData()->ErrorTrapPop( false ) )
141 pObject->maSecondary = None;
142 delete pObject;
143 return NULL;
145 XReparentWindow( pDisp, pObject->maSecondary, pObject->maPrimary, 0, 0 );
148 GetGenericData()->ErrorTrapPush();
149 if( bShow ) {
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;
163 XSync(pDisp, False);
164 if( GetGenericData()->ErrorTrapPop( false ) )
166 delete pObject;
167 return NULL;
170 return pObject;
173 void X11SalInstance::DestroyObject( SalObject* pObject )
175 delete 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;
195 void
196 SalClipRegion::BeginSetClipRegion( sal_uLong nRects )
198 if (ClipRectangleList)
199 delete [] ClipRectangleList;
201 ClipRectangleList = new XRectangle[nRects];
202 numClipRectangles = 0;
203 maxClipRectangles = nRects;
206 void
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;
218 numClipRectangles++;
222 // SalObject Implementation
223 X11SalObject::X11SalObject()
224 : mpParent(NULL)
225 , maPrimary(0)
226 , maSecondary(0)
227 , maColormap(0)
228 , mbVisible(false)
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();
252 if ( maSecondary )
253 XDestroyWindow( (Display*)maSystemChildData.pDisplay, maSecondary );
254 if ( maPrimary )
255 XDestroyWindow( (Display*)maSystemChildData.pDisplay, maPrimary );
256 if ( maColormap )
257 XFreeColormap((Display*)maSystemChildData.pDisplay, maColormap);
258 XSync( (Display*)maSystemChildData.pDisplay, False );
259 GetGenericData()->ErrorTrapPop();
262 void
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;
272 XRectangle win_size;
274 XLIB_Window aShapeWindow = maPrimary;
276 XGetWindowAttributes ( (Display*)maSystemChildData.pDisplay,
277 aShapeWindow,
278 &win_attrib );
280 win_size.x = 0;
281 win_size.y = 0;
282 win_size.width = win_attrib.width;
283 win_size.height = win_attrib.height;
285 XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
286 aShapeWindow,
287 dest_kind,
288 0, 0, // x_off, y_off
289 &win_size, // list of rectangles
290 1, // number of rectangles
291 op, ordering );
294 void
295 X11SalObject::BeginSetClipRegion( sal_uLong nRectCount )
297 maClipRegion.BeginSetClipRegion ( nRectCount );
300 void
301 X11SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
303 maClipRegion.UnionClipRegion ( nX, nY, nWidth, nHeight );
306 void
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;
315 int op;
317 switch ( nType )
319 case SAL_OBJECT_CLIP_INCLUDERECTS :
320 op = ShapeSet;
321 break;
322 case SAL_OBJECT_CLIP_EXCLUDERECTS :
323 op = ShapeSubtract;
324 break;
325 case SAL_OBJECT_CLIP_ABSOLUTE :
326 op = ShapeSet;
327 break;
328 default :
329 op = ShapeUnion;
332 XLIB_Window aShapeWindow = maPrimary;
334 XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
335 aShapeWindow,
336 dest_kind,
337 0, 0, // x_off, y_off
338 pRectangles,
339 nRectangles,
340 op, ordering );
343 sal_uInt16
344 X11SalObject::GetClipRegionType()
346 return maClipRegion.GetClipRegionType();
349 void
350 X11SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
352 if ( maPrimary && maSecondary && nWidth && nHeight )
354 XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
355 maPrimary,
356 nX, nY, nWidth, nHeight );
357 XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
358 maSecondary,
359 0, 0, nWidth, nHeight );
363 void
364 X11SalObject::Show( bool bVisible )
366 if ( ! maSystemChildData.aWindow )
367 return;
369 if ( bVisible ) {
370 XMapWindow( (Display*)maSystemChildData.pDisplay,
371 maSecondary );
372 XMapWindow( (Display*)maSystemChildData.pDisplay,
373 maPrimary );
374 } else {
375 XUnmapWindow( (Display*)maSystemChildData.pDisplay,
376 maPrimary );
377 XUnmapWindow( (Display*)maSystemChildData.pDisplay,
378 maSecondary );
380 mbVisible = bVisible;
383 void X11SalObject::GrabFocus()
385 if( mbVisible )
386 XSetInputFocus( (Display*)maSystemChildData.pDisplay,
387 maSystemChildData.aWindow,
388 RevertToNone,
389 CurrentTime );
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 )
402 nCode |= MOUSE_LEFT;
403 if( state & Button2Mask )
404 nCode |= MOUSE_MIDDLE;
405 if( state & Button3Mask )
406 nCode |= MOUSE_RIGHT;
408 if( state & ShiftMask )
409 nCode |= KEY_SHIFT;
410 if( state & ControlMask )
411 nCode |= KEY_MOD1;
412 if( state & Mod1Mask )
413 nCode |= KEY_MOD2;
414 if( state & Mod3Mask )
415 nCode |= KEY_MOD3;
417 return nCode;
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
439 SalMouseEvent aEvt;
440 const SystemEnvData* pParentData = pObject->mpParent->GetSystemData();
441 int dest_x, dest_y;
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,
448 &dest_x, &dest_y,
449 &aChild );
450 aEvt.mnX = dest_x;
451 aEvt.mnY = dest_y;
452 aEvt.mnTime = pEvent->xbutton.time;
453 aEvt.mnCode = sal_GetCode( pEvent->xbutton.state );
454 aEvt.mnButton = 0;
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;
471 else
472 nEvent = SALEVENT_MOUSEMOVE;
473 pObject->mpParent->CallCallback( nEvent, &aEvt );
475 else
477 switch( pEvent->type )
479 case UnmapNotify:
480 pObject->mbVisible = false;
481 return true;
482 case MapNotify:
483 pObject->mbVisible = true;
484 return true;
485 case ButtonPress:
486 pObject->CallCallback( SALOBJ_EVENT_TOTOP, NULL );
487 return true;
488 case FocusIn:
489 pObject->CallCallback( SALOBJ_EVENT_GETFOCUS, NULL );
490 return true;
491 case FocusOut:
492 pObject->CallCallback( SALOBJ_EVENT_LOSEFOCUS, NULL );
493 return true;
494 default: break;
497 return false;
500 return false;
503 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */