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