Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #if OSL_DEBUG_LEVEL > 1
31 : : #include <stdio.h>
32 : : #endif
33 : : #include <tools/debug.hxx>
34 : :
35 : : #include <vcl/keycodes.hxx>
36 : :
37 : : #include <tools/prex.h>
38 : : #include <X11/Xlib.h>
39 : : #include <X11/extensions/shape.h>
40 : : #include <tools/postx.h>
41 : :
42 : : #include <unx/salunx.h>
43 : : #include <unx/salstd.hxx>
44 : : #include <unx/saldata.hxx>
45 : : #include <unx/salinst.h>
46 : : #include <unx/saldisp.hxx>
47 : : #include <unx/salframe.h>
48 : : #include <unx/salobj.h>
49 : :
50 : : #include <salwtype.hxx>
51 : :
52 : :
53 : : // =======================================================================
54 : : // SalInstance member to create and destroy a SalObject
55 : :
56 : 0 : SalObject* X11SalInstance::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow )
57 : : {
58 : 0 : return X11SalObject::CreateObject( pParent, pWindowData, bShow );
59 : : }
60 : :
61 : 0 : X11SalObject* X11SalObject::CreateObject( SalFrame* pParent, SystemWindowData* pWindowData, sal_Bool bShow )
62 : : {
63 : : int error_base, event_base;
64 : 0 : X11SalObject* pObject = new X11SalObject();
65 : 0 : SystemChildData* pObjData = const_cast<SystemChildData*>(pObject->GetSystemData());
66 : :
67 : 0 : if ( ! XShapeQueryExtension( (Display*)pObjData->pDisplay,
68 : 0 : &event_base, &error_base ) )
69 : : {
70 : 0 : delete pObject;
71 : 0 : return NULL;
72 : : }
73 : :
74 : 0 : pObject->mpParent = pParent;
75 : :
76 : 0 : SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay();
77 : 0 : const SystemEnvData* pEnv = pParent->GetSystemData();
78 : 0 : Display* pDisp = pSalDisp->GetDisplay();
79 : 0 : XLIB_Window aObjectParent = (XLIB_Window)pEnv->aWindow;
80 : :
81 : : // find out on which screen that window is
82 : : XWindowAttributes aParentAttr;
83 : 0 : XGetWindowAttributes( pDisp, aObjectParent, &aParentAttr );
84 : 0 : SalX11Screen nXScreen( XScreenNumberOfScreen( aParentAttr.screen ) );
85 : : Visual* pVisual = (pWindowData && pWindowData->pVisual) ?
86 : : (Visual*)pWindowData->pVisual :
87 : 0 : pSalDisp->GetVisual( nXScreen ).GetVisual();
88 : : // get visual info
89 : 0 : VisualID aVisID = XVisualIDFromVisual( pVisual );
90 : : XVisualInfo aTemplate;
91 : 0 : aTemplate.visualid = aVisID;
92 : 0 : int nVisuals = 0;
93 : 0 : XVisualInfo* pInfos = XGetVisualInfo( pDisp, VisualIDMask, &aTemplate, &nVisuals );
94 : : // only one VisualInfo structure can match the visual id
95 : : DBG_ASSERT( nVisuals == 1, "match count for visual id is not 1" );
96 : 0 : unsigned int nDepth = pInfos->depth;
97 : 0 : XFree( pInfos );
98 : : XSetWindowAttributes aAttribs;
99 : : aAttribs.event_mask = StructureNotifyMask
100 : : | ButtonPressMask
101 : : | ButtonReleaseMask
102 : : | PointerMotionMask
103 : : | EnterWindowMask
104 : : | LeaveWindowMask
105 : : | FocusChangeMask
106 : : | ExposureMask
107 : 0 : ;
108 : :
109 : : pObject->maPrimary =
110 : : XCreateSimpleWindow( pDisp,
111 : : aObjectParent,
112 : : 0, 0,
113 : : 1, 1, 0,
114 : 0 : pSalDisp->GetColormap( nXScreen ).GetBlackPixel(),
115 : 0 : pSalDisp->GetColormap( nXScreen ).GetWhitePixel()
116 : 0 : );
117 : 0 : if( aVisID == pSalDisp->GetVisual( nXScreen ).GetVisualId() )
118 : : {
119 : : pObject->maSecondary =
120 : : XCreateSimpleWindow( pDisp,
121 : : pObject->maPrimary,
122 : : 0, 0,
123 : : 1, 1, 0,
124 : 0 : pSalDisp->GetColormap( nXScreen ).GetBlackPixel(),
125 : 0 : pSalDisp->GetColormap( nXScreen ).GetWhitePixel()
126 : 0 : );
127 : : }
128 : : else
129 : : {
130 : : #if OSL_DEBUG_LEVEL > 1
131 : : fprintf( stderr, "visual id of vcl %x, of visual %x\n",
132 : : static_cast<unsigned int> (pSalDisp->GetVisual( nXScreen ).GetVisualId()),
133 : : static_cast<unsigned int> (aVisID) );
134 : : #endif
135 : 0 : GetGenericData()->ErrorTrapPush();
136 : :
137 : : // create colormap for visual - there might not be one
138 : : pObject->maColormap = aAttribs.colormap = XCreateColormap(
139 : : pDisp,
140 : : pSalDisp->GetRootWindow( nXScreen ),
141 : : pVisual,
142 : 0 : AllocNone );
143 : :
144 : : pObject->maSecondary =
145 : : XCreateWindow( pDisp,
146 : : pSalDisp->GetRootWindow( nXScreen ),
147 : : 0, 0,
148 : : 1, 1, 0,
149 : : nDepth, InputOutput,
150 : : pVisual,
151 : 0 : CWEventMask|CWColormap, &aAttribs );
152 : 0 : XSync( pDisp, False );
153 : 0 : if( GetGenericData()->ErrorTrapPop( false ) )
154 : : {
155 : 0 : pObject->maSecondary = None;
156 : 0 : delete pObject;
157 : 0 : return NULL;
158 : : }
159 : 0 : XReparentWindow( pDisp, pObject->maSecondary, pObject->maPrimary, 0, 0 );
160 : : }
161 : :
162 : 0 : GetGenericData()->ErrorTrapPush();
163 : 0 : if( bShow ) {
164 : 0 : XMapWindow( pDisp, pObject->maSecondary );
165 : 0 : XMapWindow( pDisp, pObject->maPrimary );
166 : : }
167 : :
168 : 0 : pObjData->pDisplay = pDisp;
169 : 0 : pObjData->aWindow = pObject->maSecondary;
170 : 0 : pObjData->pWidget = NULL;
171 : 0 : pObjData->pVisual = pVisual;
172 : 0 : pObjData->nDepth = nDepth;
173 : 0 : pObjData->aColormap = aVisID == pSalDisp->GetVisual( nXScreen ).GetVisualId() ?
174 : 0 : pSalDisp->GetColormap( nXScreen ).GetXColormap() : None;
175 : 0 : pObjData->pAppContext = NULL;
176 : :
177 : 0 : XSync(pDisp, False);
178 : 0 : if( GetGenericData()->ErrorTrapPop( false ) )
179 : : {
180 : 0 : delete pObject;
181 : 0 : return NULL;
182 : : }
183 : :
184 : 0 : return pObject;
185 : : }
186 : :
187 : :
188 : 0 : void X11SalInstance::DestroyObject( SalObject* pObject )
189 : : {
190 : 0 : delete pObject;
191 : 0 : }
192 : :
193 : :
194 : : // ======================================================================
195 : : // SalClipRegion is a member of SalObject
196 : : // definition of SalClipRegion my be found in unx/inc/salobj.h
197 : :
198 : :
199 : 0 : SalClipRegion::SalClipRegion()
200 : : {
201 : 0 : ClipRectangleList = NULL;
202 : 0 : numClipRectangles = 0;
203 : 0 : maxClipRectangles = 0;
204 : 0 : nClipRegionType = SAL_OBJECT_CLIP_INCLUDERECTS;
205 : 0 : }
206 : :
207 : :
208 : 0 : SalClipRegion::~SalClipRegion()
209 : : {
210 : 0 : if ( ClipRectangleList )
211 : 0 : delete [] ClipRectangleList;
212 : 0 : }
213 : :
214 : :
215 : : void
216 : 0 : SalClipRegion::BeginSetClipRegion( sal_uLong nRects )
217 : : {
218 : 0 : if (ClipRectangleList)
219 : 0 : delete [] ClipRectangleList;
220 : :
221 : 0 : ClipRectangleList = new XRectangle[nRects];
222 : 0 : numClipRectangles = 0;
223 : 0 : maxClipRectangles = nRects;
224 : 0 : }
225 : :
226 : :
227 : : void
228 : 0 : SalClipRegion::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
229 : : {
230 : 0 : if ( nWidth && nHeight && (numClipRectangles < maxClipRectangles) )
231 : : {
232 : 0 : XRectangle *aRect = ClipRectangleList + numClipRectangles;
233 : :
234 : 0 : aRect->x = (short) nX;
235 : 0 : aRect->y = (short) nY;
236 : 0 : aRect->width = (unsigned short) nWidth;
237 : 0 : aRect->height= (unsigned short) nHeight;
238 : :
239 : 0 : numClipRectangles++;
240 : : }
241 : 0 : }
242 : :
243 : :
244 : : // =======================================================================
245 : : // SalObject Implementation
246 : :
247 : :
248 : 0 : X11SalObject::X11SalObject()
249 : : {
250 : 0 : maSystemChildData.nSize = sizeof( SystemChildData );
251 : 0 : maSystemChildData.pDisplay = GetGenericData()->GetSalDisplay()->GetDisplay();
252 : 0 : maSystemChildData.aWindow = None;
253 : 0 : maSystemChildData.pSalFrame = 0;
254 : 0 : maSystemChildData.pWidget = 0;
255 : 0 : maSystemChildData.pVisual = 0;
256 : 0 : maSystemChildData.nDepth = 0;
257 : 0 : maSystemChildData.aColormap = 0;
258 : 0 : maSystemChildData.pAppContext = NULL;
259 : 0 : maSystemChildData.aShellWindow = 0;
260 : 0 : maSystemChildData.pShellWidget = NULL;
261 : 0 : maPrimary = 0;
262 : 0 : maSecondary = 0;
263 : 0 : maColormap = 0;
264 : :
265 : 0 : std::list< SalObject* >& rObjects = GetGenericData()->GetSalDisplay()->getSalObjects();
266 : 0 : rObjects.push_back( this );
267 : 0 : }
268 : :
269 : :
270 : 0 : X11SalObject::~X11SalObject()
271 : : {
272 : 0 : std::list< SalObject* >& rObjects = GetGenericData()->GetSalDisplay()->getSalObjects();
273 : 0 : rObjects.remove( this );
274 : :
275 : 0 : GetGenericData()->ErrorTrapPush();
276 : 0 : if ( maSecondary )
277 : 0 : XDestroyWindow( (Display*)maSystemChildData.pDisplay, maSecondary );
278 : 0 : if ( maPrimary )
279 : 0 : XDestroyWindow( (Display*)maSystemChildData.pDisplay, maPrimary );
280 : 0 : if ( maColormap )
281 : 0 : XFreeColormap((Display*)maSystemChildData.pDisplay, maColormap);
282 : 0 : XSync( (Display*)maSystemChildData.pDisplay, False );
283 : 0 : GetGenericData()->ErrorTrapPop();
284 : 0 : }
285 : :
286 : :
287 : : void
288 : 0 : X11SalObject::ResetClipRegion()
289 : : {
290 : 0 : maClipRegion.ResetClipRegion();
291 : :
292 : 0 : const int dest_kind = ShapeBounding;
293 : 0 : const int op = ShapeSet;
294 : 0 : const int ordering = YSorted;
295 : :
296 : : XWindowAttributes win_attrib;
297 : : XRectangle win_size;
298 : :
299 : 0 : XLIB_Window aShapeWindow = maPrimary;
300 : :
301 : : XGetWindowAttributes ( (Display*)maSystemChildData.pDisplay,
302 : : aShapeWindow,
303 : 0 : &win_attrib );
304 : :
305 : 0 : win_size.x = 0;
306 : 0 : win_size.y = 0;
307 : 0 : win_size.width = win_attrib.width;
308 : 0 : win_size.height = win_attrib.height;
309 : :
310 : : XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
311 : : aShapeWindow,
312 : : dest_kind,
313 : : 0, 0, // x_off, y_off
314 : : &win_size, // list of rectangles
315 : : 1, // number of rectangles
316 : 0 : op, ordering );
317 : 0 : }
318 : :
319 : :
320 : : void
321 : 0 : X11SalObject::BeginSetClipRegion( sal_uLong nRectCount )
322 : : {
323 : 0 : maClipRegion.BeginSetClipRegion ( nRectCount );
324 : 0 : }
325 : :
326 : :
327 : : void
328 : 0 : X11SalObject::UnionClipRegion( long nX, long nY, long nWidth, long nHeight )
329 : : {
330 : 0 : maClipRegion.UnionClipRegion ( nX, nY, nWidth, nHeight );
331 : 0 : }
332 : :
333 : :
334 : : void
335 : 0 : X11SalObject::EndSetClipRegion()
336 : : {
337 : 0 : XRectangle *pRectangles = maClipRegion.EndSetClipRegion ();
338 : 0 : const int nType = maClipRegion.GetClipRegionType();
339 : 0 : const int nRectangles = maClipRegion.GetRectangleCount();
340 : :
341 : 0 : const int dest_kind = ShapeBounding;
342 : 0 : const int ordering = YSorted;
343 : : int op;
344 : :
345 : 0 : switch ( nType )
346 : : {
347 : : case SAL_OBJECT_CLIP_INCLUDERECTS :
348 : 0 : op = ShapeSet;
349 : 0 : break;
350 : : case SAL_OBJECT_CLIP_EXCLUDERECTS :
351 : 0 : op = ShapeSubtract;
352 : 0 : break;
353 : : case SAL_OBJECT_CLIP_ABSOLUTE :
354 : 0 : op = ShapeSet;
355 : 0 : break;
356 : : default :
357 : 0 : op = ShapeUnion;
358 : : }
359 : :
360 : 0 : XLIB_Window aShapeWindow = maPrimary;
361 : :
362 : : XShapeCombineRectangles ( (Display*)maSystemChildData.pDisplay,
363 : : aShapeWindow,
364 : : dest_kind,
365 : : 0, 0, // x_off, y_off
366 : : pRectangles,
367 : : nRectangles,
368 : 0 : op, ordering );
369 : 0 : }
370 : :
371 : :
372 : : sal_uInt16
373 : 0 : X11SalObject::GetClipRegionType()
374 : : {
375 : 0 : return maClipRegion.GetClipRegionType();
376 : : }
377 : :
378 : : // -----------------------------------------------------------------------
379 : :
380 : : void
381 : 0 : X11SalObject::SetPosSize( long nX, long nY, long nWidth, long nHeight )
382 : : {
383 : 0 : if ( maPrimary && maSecondary && nWidth && nHeight )
384 : : {
385 : : XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
386 : : maPrimary,
387 : 0 : nX, nY, nWidth, nHeight );
388 : : XMoveResizeWindow( (Display*)maSystemChildData.pDisplay,
389 : : maSecondary,
390 : 0 : 0, 0, nWidth, nHeight );
391 : : }
392 : 0 : }
393 : :
394 : :
395 : : void
396 : 0 : X11SalObject::Show( sal_Bool bVisible )
397 : : {
398 : 0 : if ( ! maSystemChildData.aWindow )
399 : 0 : return;
400 : :
401 : 0 : if ( bVisible ) {
402 : : XMapWindow( (Display*)maSystemChildData.pDisplay,
403 : 0 : maSecondary );
404 : : XMapWindow( (Display*)maSystemChildData.pDisplay,
405 : 0 : maPrimary );
406 : : } else {
407 : : XUnmapWindow( (Display*)maSystemChildData.pDisplay,
408 : 0 : maPrimary );
409 : : XUnmapWindow( (Display*)maSystemChildData.pDisplay,
410 : 0 : maSecondary );
411 : : }
412 : 0 : mbVisible = bVisible;
413 : : }
414 : :
415 : 0 : void X11SalObject::GrabFocus()
416 : : {
417 : 0 : if( mbVisible )
418 : : XSetInputFocus( (Display*)maSystemChildData.pDisplay,
419 : : maSystemChildData.aWindow,
420 : : RevertToNone,
421 : 0 : CurrentTime );
422 : 0 : }
423 : :
424 : : // -----------------------------------------------------------------------
425 : :
426 : 0 : const SystemChildData* X11SalObject::GetSystemData() const
427 : : {
428 : 0 : return &maSystemChildData;
429 : : }
430 : :
431 : 0 : static sal_uInt16 sal_GetCode( int state )
432 : : {
433 : 0 : sal_uInt16 nCode = 0;
434 : :
435 : 0 : if( state & Button1Mask )
436 : 0 : nCode |= MOUSE_LEFT;
437 : 0 : if( state & Button2Mask )
438 : 0 : nCode |= MOUSE_MIDDLE;
439 : 0 : if( state & Button3Mask )
440 : 0 : nCode |= MOUSE_RIGHT;
441 : :
442 : 0 : if( state & ShiftMask )
443 : 0 : nCode |= KEY_SHIFT;
444 : 0 : if( state & ControlMask )
445 : 0 : nCode |= KEY_MOD1;
446 : 0 : if( state & Mod1Mask )
447 : 0 : nCode |= KEY_MOD2;
448 : 0 : if( state & Mod3Mask )
449 : 0 : nCode |= KEY_MOD3;
450 : :
451 : 0 : return nCode;
452 : : }
453 : :
454 : 0 : long X11SalObject::Dispatch( XEvent* pEvent )
455 : : {
456 : 0 : std::list< SalObject* >& rObjects = GetGenericData()->GetSalDisplay()->getSalObjects();
457 : :
458 : 0 : for( std::list< SalObject* >::iterator it = rObjects.begin(); it != rObjects.end(); ++it )
459 : : {
460 : 0 : X11SalObject* pObject = static_cast<X11SalObject*>(*it);
461 : 0 : if( pEvent->xany.window == pObject->maPrimary ||
462 : : pEvent->xany.window == pObject->maSecondary )
463 : : {
464 : 0 : if( pObject->IsMouseTransparent() && (
465 : : pEvent->type == ButtonPress ||
466 : : pEvent->type == ButtonRelease ||
467 : : pEvent->type == EnterNotify ||
468 : : pEvent->type == LeaveNotify ||
469 : : pEvent->type == MotionNotify
470 : : )
471 : : )
472 : : {
473 : : SalMouseEvent aEvt;
474 : 0 : const SystemEnvData* pParentData = pObject->mpParent->GetSystemData();
475 : : int dest_x, dest_y;
476 : 0 : XLIB_Window aChild = None;
477 : : XTranslateCoordinates( pEvent->xbutton.display,
478 : : pEvent->xbutton.root,
479 : : pParentData->aWindow,
480 : : pEvent->xbutton.x_root,
481 : : pEvent->xbutton.y_root,
482 : : &dest_x, &dest_y,
483 : 0 : &aChild );
484 : 0 : aEvt.mnX = dest_x;
485 : 0 : aEvt.mnY = dest_y;
486 : 0 : aEvt.mnTime = pEvent->xbutton.time;
487 : 0 : aEvt.mnCode = sal_GetCode( pEvent->xbutton.state );
488 : 0 : aEvt.mnButton = 0;
489 : 0 : sal_uInt16 nEvent = 0;
490 : 0 : if( pEvent->type == ButtonPress ||
491 : : pEvent->type == ButtonRelease )
492 : : {
493 : 0 : switch( pEvent->xbutton.button )
494 : : {
495 : 0 : case Button1: aEvt.mnButton = MOUSE_LEFT;break;
496 : 0 : case Button2: aEvt.mnButton = MOUSE_MIDDLE;break;
497 : 0 : case Button3: aEvt.mnButton = MOUSE_RIGHT;break;
498 : : }
499 : : nEvent = (pEvent->type == ButtonPress) ?
500 : : SALEVENT_MOUSEBUTTONDOWN :
501 : 0 : SALEVENT_MOUSEBUTTONUP;
502 : : }
503 : 0 : else if( pEvent->type == EnterNotify )
504 : 0 : nEvent = SALEVENT_MOUSELEAVE;
505 : : else
506 : 0 : nEvent = SALEVENT_MOUSEMOVE;
507 : 0 : pObject->mpParent->CallCallback( nEvent, &aEvt );
508 : : }
509 : : else
510 : : {
511 : 0 : switch( pEvent->type )
512 : : {
513 : : case UnmapNotify:
514 : 0 : pObject->mbVisible = sal_False;
515 : 0 : return 1;
516 : : case MapNotify:
517 : 0 : pObject->mbVisible = sal_True;
518 : 0 : return 1;
519 : : case ButtonPress:
520 : 0 : pObject->CallCallback( SALOBJ_EVENT_TOTOP, NULL );
521 : 0 : return 1;
522 : : case FocusIn:
523 : 0 : pObject->CallCallback( SALOBJ_EVENT_GETFOCUS, NULL );
524 : 0 : return 1;
525 : : case FocusOut:
526 : 0 : pObject->CallCallback( SALOBJ_EVENT_LOSEFOCUS, NULL );
527 : 0 : return 1;
528 : 0 : default: break;
529 : : }
530 : : }
531 : 0 : return 0;
532 : : }
533 : : }
534 : 0 : return 0;
535 : : }
536 : :
537 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|